安裝Anacond:https://blog.csdn.net/ITLearnHall/article/details/81708148
安裝Pycharm:https://blog.csdn.net/qq_15698613/article/details/86502371
一:MyQR 生成動態二維碼100個
import random
from MyQR import myqr
import os
for i in range(1,101):
z=''.join(str(random.choice(range(10))) for _ in range(10))#生成長度爲10的隨機數
name=z+".png"#設置圖片名字
myqr.run(
version=1, # 設置容錯率
level='L',
brightness=1.0,
words=z,
save_name=name
)
二:下載圖片,將圖片和二維碼大小進行修改
需要安裝opencv參考
https://blog.csdn.net/iracer/article/details/80498732
import os
import cv2
#讀取文件夾下文件
def read_directory(directory_name,save_img):
i=0
for fileName in os.listdir(directory_name):
#print(fileName)
obsPath=directory_name+"/"+fileName
obsSave_path=save_img+"/"+fileName
resize_img(obsPath,obsSave_path)
i+=1
if(i==100):
break
def resize_img(path_img,save_img):
im1 = cv2.imread(path_img)
im2 = cv2.resize(im1,(716,1000),) # 爲圖片重新指定尺寸
cv2.imwrite(save_img,im2)
read_directory("D:/pythonLearnDemo/AnacondaJqueryDemo/neg/neg","D:/pythonLearnDemo/AnacondaJqueryDemo/neg/resize_neg")
三:將照片和二維碼進行隨機合併
import cv2
import numpy as np
import matplotlib.pyplot as plt
import random
#讀取照片
directory_name="D:/pythonLearnDemo/AnacondaJqueryDemo/neg/resize_neg"
myqrPaths=os.listdir("D:/pythonLearnDemo/AnacondaJqueryDemo/neg/myqrCode")
lens=len(os.listdir(directory_name))
for fileName in os.listdir(directory_name):
obsPathName=directory_name+"/"+fileName
yNum=0
xNum=0
for i in range(1,3):
dst = cv2.imread(obsPathName)#背景圖
ranNum=random.randint(0,lens)
print("ranNum:",ranNum,"NAME:",myqrPaths[ranNum])
srcPath="D:/pythonLearnDemo/AnacondaJqueryDemo/neg/myqrCode"+"/"+myqrPaths[ranNum]
x_loc=0
y_loc=0
if(i==1):
y_loc=random.randint(141,350)
yNum=y_loc
x_loc=random.randint(141,260)
xNum=x_loc
else:
y_loc=random.randint(yNum+170,641)
x_loc=random.randint(xNum+141,500)
center = (x_loc,y_loc)
#dst = cv2.imread("D:/pythonLearnDemo/AnacondaJqueryDemo/neg/opencv-seamless-cloning-example.jpg.jpg")
print(srcPath)
src = cv2.imread(srcPath)
src_mask = np.zeros(src.shape, src.dtype)
poly = np.array([[0, 2], [258, 2], [258, 260], [0, 260]], np.int32)
cv2.fillPoly(src_mask, [poly], (255, 255, 255))
output = cv2.seamlessClone(src, dst, src_mask, center, cv2.NORMAL_CLONE)
mrgPath="D:/pythonLearnDemo/AnacondaJqueryDemo/neg/images"+"/"+fileName
obsPathName=mrgPath
cv2.imwrite(mrgPath, output);
下載安裝Tensorflow object detection API :https://github.com/tensorflow/models下載到本地,解壓放到需要使用的路徑下
四:Protobuf 安裝與配置
Protobuf(Google Protocol Buffers)是GG開發的的一套用於數據存儲,網絡通信時用於協議編解碼的工具庫。和XML,Json數據差不多,把數據按某種形式保存起來。相對與XML和Json的不同之處,它是一種二進制的數據格式,具有更高的傳輸,打包和解包效率。
在https://github.com/google/protobuf/releases 網站中選擇windows 版本,解壓後將bin文件夾中的【protoc.exe】放到models中的research目錄下,執行下面的代碼,將
object_detection/protos下的.proto文件轉換成.py文件
'''
需要到protoc所在的目錄下執行protoc
'''
import
os
os.chdir(
'models-master/research'
)#可以寫
for
each
in
os.listdir(
'object_detection/protos'
):#可以寫models-master(
Tensorflow object detection API 解壓後文件)可對路徑
if
each.endswith(
'proto'
):
os.system(
'protoc object_detection/protos/%s --python_out=.'
%
each)
運行jupyter notebook,找到../models-master/research/object_detection下的
object_detection_tutorial.ipynb進行運行
demo結果
如果代碼成功運行的話,運行結果如下圖所示:
給圖片打標籤
使用打標籤工具LabelImg,下載頁面鏈接:https://tzutalin.github.io/labelImg/
下載後解壓,打開:
在輸入法爲英文輸入的情況下,按鍵盤上的w鍵則可以開始繪製方框,方框會框住圖片中的物體。完成繪製方框後,還需要爲方框標上類別,如下圖所示。
注意:每完成一張圖的打標籤,一定要記得保存!!!,初次使用可以在edit選項中設置正方形和矩形框:
每次打完標籤,會生成對應的xml數據,感興趣的可以查看一下某個xml文件,其中記錄了標籤及bounding box座標:
<annotation>
<folder>images</folder>
<filename>1.jpg</filename>
<path>D:\pythonLearnDemo\AnacondaJqueryDemo\neg\images\1.jpg</path>
<source>
<database>Unknown</database>
</source>
<size>
<width>716</width>
<height>1000</height>
<depth>3</depth>
</size>
<segmented>0</segmented>
<object>
<name>qrCode</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>141</xmin>
<ymin>222</ymin>
<xmax>355</xmax>
<ymax>436</ymax>
</bndbox>
</object>
<object>
<name>qrCode</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>369</xmin>
<ymin>422</ymin>
<xmax>561</xmax>
<ymax>605</ymax>
</bndbox>
</object>
</annotation>
xml轉csv
xml轉csv的意思是,將xml文件中的信息整合到csv文件中,其中利用的是xml模塊
# -*- coding: utf-8 -*-
"""
@author: Zbb
將文件夾內所有XML文件的信息記錄到CSV文件中
"""
import os
import pandas as pd
import xml.etree.ElementTree as ET
from sklearn.model_selection import train_test_split
path = 'D:/pythonLearnDemo/saveLabels'
def xml_to_csv(path):
xml_list = []
for xml_file in glob.glob(path + '/*.xml'):
tree = ET.parse(xml_file)
root = tree.getroot()
for member in root.findall('object'):
value = (root.find('filename').text,
int(root.find('size')[0].text),
int(root.find('size')[1].text),
member[0].text,
int(member[4][0].text),
int(member[4][1].text),
int(member[4][2].text),
int(member[4][3].text)
)
xml_list.append(value)
column_name = ['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax']
xml_df = pd.DataFrame(xml_list, columns=column_name)
return xml_df
def xmlPath_list_to_df(xmlPath_list):
xmlContent_list = []
for xmlPath in xmlPath_list:
print(xmlPath)
tree = ET.parse(xmlPath)
root = tree.getroot()
for member in root.findall('object'):
value = (root.find('filename').text, # 文件名
int(root.find('size')[0].text), # width
int(root.find('size')[1].text), # height
member[0].text, # 標籤
int(member[4][0].text), # xmin
int(member[4][1].text), # ymin
int(member[4][2].text), # xmax
int(member[4][3].text) # ymax
)
xmlContent_list.append(value)
column_name = ['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax']
xmlContent_df = pd.DataFrame(xmlContent_list, columns=column_name)
return xmlContent_df
def main():
image_path = path
xml_df = xml_to_csv(image_path)
xml_df.to_csv('tv_vehicle_labels.csv', index=None)
print('Successfully converted xml to csv.')
def dirPath_to_csv(dirPath):
fileName_list = os.listdir(dirPath)
all_xmlPath_list = [os.path.join(dirPath, fileName) for fileName in fileName_list if '.xml' in fileName]
train_xmlPath_list, test_xmlPath_list = train_test_split(all_xmlPath_list, test_size=0.1, random_state=1)
train_df = xmlPath_list_to_df(train_xmlPath_list)
train_df.to_csv('train.csv')
print('成功產生文件train.csv,訓練集共有%d張圖片' % len(train_xmlPath_list))
test_df = xmlPath_list_to_df(test_xmlPath_list)
test_df.to_csv('test.csv')
print('成功產生文件test.csv,測試集共有%d張圖片' % len(test_xmlPath_list))
#main()
dirPath_to_csv(path)
csv轉tfrecord
由於下面的代碼我們需要模塊
1 |
|
該模塊是我們在Tensorflow object detection API中下載的,要想使用該模塊,我們需要添加環境變量PATHPATH。方法如下:右鍵計算機->屬性
其中變量值包含下載的objec_detection路徑及slim路徑,如E:\ML\models-master\research;E:\ML\models-master\research\slim
# -*- coding: utf-8 -*-
"""
@author: Zbb
將文件夾內所有XML文件的信息記錄到CSV文件中
"""
import os
import io
import pandas as pd
import tensorflow as tf
from PIL import Image
from object_detection.utils import dataset_util
from collections import namedtuple, OrderedDict
import os
import pandas as pd
import tensorflow as tf
from object_detection.utils import dataset_util
import shutil
def csv2tfrecord(csv_path, imageDir_path, tfrecord_path):
objectInfo_df = pd.read_csv(csv_path)
tfrecord_writer = tf.python_io.TFRecordWriter(tfrecord_path)
for filename, group in objectInfo_df.groupby('filename'):
height = group.iloc[0]['height']
width = group.iloc[0]['width']
filename_bytes = filename.encode('utf-8')
image_path = os.path.join(imageDir_path, filename)
with open(image_path, 'rb') as file:
encoded_jpg = file.read()
image_format = b'jpg'
xmin_list = list(group['xmin'] / width)
xmax_list = list(group['xmax'] / width)
ymin_list = list(group['ymin'] / height)
ymax_list = list(group['ymax'] / height)
classText_list = [classText.encode('utf-8') for classText in group['class']]
classLabel_list = [classText_to_classLabel(classText) for classText in group['class']]
tf_example = tf.train.Example(features=tf.train.Features(
feature={
'image/height': dataset_util.int64_feature(height),
'image/width': dataset_util.int64_feature(width),
'image/filename': dataset_util.bytes_feature(filename_bytes),
'image/source_id': dataset_util.bytes_feature(filename_bytes),
'image/encoded': dataset_util.bytes_feature(encoded_jpg),
'image/format': dataset_util.bytes_feature(image_format),
'image/object/bbox/xmin': dataset_util.float_list_feature(xmin_list),
'image/object/bbox/xmax': dataset_util.float_list_feature(xmax_list),
'image/object/bbox/ymin': dataset_util.float_list_feature(ymin_list),
'image/object/bbox/ymax': dataset_util.float_list_feature(ymax_list),
'image/object/class/text': dataset_util.bytes_list_feature(classText_list),
'image/object/class/label': dataset_util.int64_list_feature(classLabel_list),
}))
tfrecord_writer.write(tf_example.SerializeToString())
tfrecord_writer.close()
print('成功產生tfrecord文件,保存在路徑:%s' % tfrecord_path)
# 如果訓練自己的模型,目標檢測類別不同,需要修改此處
def classText_to_classLabel(row_label):
if row_label == 'fish':
return 1
elif row_label == 'human_face':
return 2
else:
return None
dir_name = 'training'
if not os.path.isdir(dir_name):
os.mkdir(dir_name)
csv2tfrecord('D:/pythonLearnDemo/train.csv', 'D:/pythonLearnDemo/AnacondaJqueryDemo/neg/images', 'D:/pythonLearnDemo/training/train.tfrecord')
csv2tfrecord('D:/pythonLearnDemo/test.csv', 'D:/pythonLearnDemo/AnacondaJqueryDemo/neg/images', 'D:/pythonLearnDemo/training/test.tfrecord')
運行上面的代碼,目標檢測文件夾中會產生一個文件夾training,如下圖所示:
編寫pbtxt文件
在目標檢測的文件夾training中,創建文本文件my_label_map.pbtxt。複製下面一段內容到文本文件my_label_map.pbtxt中:
item {
name : "qrCode"
id : 1
}
8)編寫配置文件
可以在object_detection文件夾中的samples/config路徑下,找到原生配置文件ssdlite_mobilenet_v2_coco.config,先複製1份到桌面文件目標檢測的文件夾training中,並做如下修改:
- 第9行的num_classes,對於本文來說,此數設置爲1
- 第141行的batch_size,對於本文來說,此數設置爲
3
,讀者根據自己的電腦配置,可以調高或者調低 - 第177行input_path設置成
"D:/pythonLearnDemo/training/train.tfrecord"(我設置的爲絕對路徑)
- 第179行label_map_path設置成
"D:/pythonLearnDemo/training/my_label_map.pbtxt"
- 第191行input_path設置成
"D:/pythonLearnDemo/training/test.tfrecord"
- 第193行label_map_path設置成
"
D:/pythonLearnDemo/training
/my_label_map.pbtxt"
- 第158、159這2行需要刪除
- 第二處爲eval_config中的num_examples,它表示在驗證階段需要執行的圖片數量,本次驗證數量爲10(可以在create_pascal_tf_record.py中,輸出對應的examples_list長度,就可以知道這個大小)。
修改配置文件ssdlite_mobilenet_v2_coco.config並保存後,此時文件夾training中有4個文件,如下圖所示:
# SSD with Mobilenet v1 configuration for MSCOCO Dataset.
# Users should configure the fine_tune_checkpoint field in the train config as
# well as the label_map_path and input_path fields in the train_input_reader and
# eval_input_reader. Search for "PATH_TO_BE_CONFIGURED" to find the fields that
# should be configured.
model {
ssd {
num_classes: 1
box_coder {
faster_rcnn_box_coder {
y_scale: 10.0
x_scale: 10.0
height_scale: 5.0
width_scale: 5.0
}
}
matcher {
argmax_matcher {
matched_threshold: 0.5
unmatched_threshold: 0.5
ignore_thresholds: false
negatives_lower_than_unmatched: true
force_match_for_each_row: true
}
}
similarity_calculator {
iou_similarity {
}
}
anchor_generator {
ssd_anchor_generator {
num_layers: 6
min_scale: 0.2
max_scale: 0.95
aspect_ratios: 1.0
aspect_ratios: 2.0
aspect_ratios: 0.5
aspect_ratios: 3.0
aspect_ratios: 0.3333
}
}
image_resizer {
fixed_shape_resizer {
height: 300
width: 300
}
}
box_predictor {
convolutional_box_predictor {
min_depth: 0
max_depth: 0
num_layers_before_predictor: 0
use_dropout: false
dropout_keep_probability: 0.8
kernel_size: 1
box_code_size: 4
apply_sigmoid_to_scores: false
conv_hyperparams {
activation: RELU_6,
regularizer {
l2_regularizer {
weight: 0.00004
}
}
initializer {
truncated_normal_initializer {
stddev: 0.03
mean: 0.0
}
}
batch_norm {
train: true,
scale: true,
center: true,
decay: 0.9997,
epsilon: 0.001,
}
}
}
}
feature_extractor {
type: 'ssd_mobilenet_v1'
min_depth: 16
depth_multiplier: 1.0
conv_hyperparams {
activation: RELU_6,
regularizer {
l2_regularizer {
weight: 0.00004
}
}
initializer {
truncated_normal_initializer {
stddev: 0.03
mean: 0.0
}
}
batch_norm {
train: true,
scale: true,
center: true,
decay: 0.9997,
epsilon: 0.001,
}
}
}
loss {
classification_loss {
weighted_sigmoid {
}
}
localization_loss {
weighted_smooth_l1 {
}
}
hard_example_miner {
num_hard_examples: 3000
iou_threshold: 0.99
loss_type: CLASSIFICATION
max_negatives_per_positive: 3
min_negatives_per_image: 0
}
classification_weight: 1.0
localization_weight: 1.0
}
normalize_loss_by_num_matches: true
post_processing {
batch_non_max_suppression {
score_threshold: 1e-8
iou_threshold: 0.6
max_detections_per_class: 100
max_total_detections: 100
}
score_converter: SIGMOID
}
}
}
train_config: {
batch_size: 3
optimizer {
rms_prop_optimizer: {
learning_rate: {
exponential_decay_learning_rate {
initial_learning_rate: 0.004
decay_steps: 800720
decay_factor: 0.95
}
}
momentum_optimizer_value: 0.9
decay: 0.9
epsilon: 1.0
}
}
#fine_tune_checkpoint: "PATH_TO_BE_CONFIGURED/model.ckpt"
#from_detection_checkpoint: true
# Note: The below line limits the training process to 200K steps, which we
# empirically found to be sufficient enough to train the pets dataset. This
# effectively bypasses the learning rate schedule (the learning rate will
# never decay). Remove the below line to train indefinitely.
num_steps: 200000
data_augmentation_options {
random_horizontal_flip {
}
}
data_augmentation_options {
ssd_random_crop {
}
}
}
train_input_reader: {
tf_record_input_reader {
input_path: "D:/pythonLearnDemo/training/train.tfrecord"
}
label_map_path: "D:/pythonLearnDemo/training/my_label_map.pbtxt"
}
eval_config: {
num_examples: 10
# Note: The below line limits the evaluation process to 10 evaluations.
# Remove the below line to evaluate indefinitely.
max_evals: 10
}
eval_input_reader: {
tf_record_input_reader {
input_path: "D:/pythonLearnDemo/training/test.tfrecord"
}
label_map_path: "D:/pythonLearnDemo/training/my_label_map.pbtxt"
shuffle: false
num_readers: 1
}
三、模型訓練
1)錯誤一:
在桌面的目標檢測文件夾中打開cmd,即在路徑中輸入cmd後按Enter鍵運行。在cmd中運行命令:
1 |
1. python D:/tensorflowObject/models-master/research/object_detection/model_main.py
2. python3 object_detection/model_main.py |
運行結果如下圖所示:
可以看出缺少pycocotools庫,在linux系統中安裝pycocotools庫只需要運行命令:pip install pycocotools,
但是在Windows上安裝則複雜得多:
首先下載Microsoft C++ build 14.0,鏈接:https://go.microsoft.com/fwlink/?LinkId=691126,初始化安裝程序->自定義->選擇功能只勾選Windows 10 SDK 10.0.10240->安裝,過程比較漫長,一般安裝有VS完整版的,不會缺失
然後下載安裝pycocotools,鏈接:https://github.com/philferriere/cocoapi,解壓到當前文件夾,進入文件夾cocoapi-master中的文件夾PythonAPI,在此文件夾下打開cmd,輸入:python setup.py build_ext install
然後重新訓練,模型訓練穩定地進行一段時間後,會做一次模型評估,如下圖所示。所以如果讀者看到下圖中的情況,則說明模型訓練很順利:
將訓練模型導出
python D:/tensorflowObject/models-master/research/object_detection/export_inference_graph.py
--input_type=image_tensor
--pipeline_config_path=D:/pythonLearnDemo/training/ssd_mobilenet_v1_coco.config
--trained_checkpoint_prefix=D:/pythonLearnDemo/training/model_training/model.ckpt-20000 #之前默認設置20000次
--output_directory=fish_inference_graph
3)查看模型訓練狀況
模型訓練穩定地進行後,在桌面的目標檢測文件夾中重新打開cmd。在cmd中運行命令:
D:/pythonLearnDemo/training/model_training(路徑爲之前保存訓練模型的地方)
--trained_checkpoint_prefix=D:/pythonLearnDemo/training/model_training/
tensorboard --logdir=D:/pythonLearnDemo/training/model_training --host=127.0.0.1
可查看數據
測試:
測試代碼下載地址
鏈接:https://pan.baidu.com/s/1kqFlP6vdsMgwyYRPFPmxnA
提取碼:68rc
在測試過程中,出現不了展示圖片大的效果,然後修改成了保存
訓練結果: