本文主要記錄在Tensorflow和Opencv環境下實現行人檢測的主要步驟,特別是一些常用命令和需要用到的腳本文件,生成的模型文件等。文章主要分爲以下幾個部分:環境搭建、數據集生成製作、Tensoflow訓練、導出模型在Opencv中實現行人檢測。
目錄
1.5安裝Tensorflow object_detection API及下載models文件... 3
一、環境搭建
1.1 tensorflow
首先是最重要的tensorflow和opencv環境安裝。已經安裝好了,這裏檢查一下版本信息。
打開cmd,輸入命令:da info –envs
可見tensorflow環境已經安裝好了,再輸入命令:activate tensorflow_gpu_1.12_py37
此時已進入tensorflow,我的tensorflow版本是1.12.0的GPU版本的
具體查看tensorflow版本也可用以下命令實現:
python
import tensorflow as tf
tf.__version__
1.2 opencv
同樣查看opencv可用以下命令
python
import cv2 as cv
cv.__version__
可見我的opencv是4.1.1版本的。
1.3下載opencv4.1.1源碼
需要注意的是,需要下載opencv4.1.1源碼,在後續會用到其中的腳本文件D:\packages\opencv-4.1.1\sources\samples\dnn\tf_text_graph_ssd.py
1.4下載安裝protoc
安裝protoc是爲了編譯下面的Object Dection對象檢測API
Windows 10下可以直接下載已經編譯好的protoc可執行文件,一定要安裝3.4.0版本的protoc纔不會報錯。
https://github.com/protocolbuffers/protobuf/releases/download/v3.4.0/protoc-3.4.0-win32.zip
1.5安裝Tensorflow object_detection API及下載models文件
Github官網上有安裝教程,但只有Ubuntu系統的教程:
https://github.com/tensorflow/models/tree/master/research/object_detection
想在win10下安裝,可以參考下面的博客:
https://blog.csdn.net/qq_28019591/article/details/82023949
1.6 下載視頻數據集
視頻數據:
http://www.robots.ox.ac.uk/ActiveVision/Research/Projects/2009bbenfold_headpose/Datasets/TownCentreXVID.avi
標註信息
http://www.robots.ox.ac.uk/ActiveVision/Research/Projects/2009bbenfold_headpose/Datasets/TownCentre-groundtruth.top
二、數據集生成製作
2.1獲取每一幀圖像
執行extract_towncentre.py腳本,代碼如下:
import cv2 as cv
import os
def video2ims(src, train_path="images", test_path="test_images", factor=2):
os.mkdir(train_path)
os.mkdir(test_path)
frame = 0
cap = cv.VideoCapture(src)
counts = int(cap.get(cv.CAP_PROP_FRAME_COUNT))
w = int(cap.get(cv.CAP_PROP_FRAME_WIDTH))
h = int(cap.get(cv.CAP_PROP_FRAME_HEIGHT))
print("number of frames : %d"%counts)
while True:
ret, im = cap.read()
if ret is True:
if frame < 3600:
path = train_path
else:
path = test_path
im = cv.resize(im, (w//factor, h//factor))
cv.imwrite(os.path.join(path, str(frame)+".jpg"), im)
frame += 1
else:
break
cap.release()
if __name__== "__main__":
video2ims("D:/images/video/TownCentreXVID.avi")
功能:將視頻一分爲二,前3600幀作爲訓練集,後3600幀作爲測試集。並把每一幀圖像保存爲jpg文件,分別存貯在images目錄下和test_images目錄下。
2.2獲取標註信息
執行extract_GT.py腳本,代碼如下:
import os
import pandas as pd
if __name__ == '__main__':
GT = pd.read_csv('D:/images/video/TownCentre-groundtruth.top', header=None)
indent = lambda x, y: ''.join([' ' for _ in range(y)]) + x
factor = 2
train_size = 3600
os.mkdir('xmls')
name = 'pedestrian'
width, height = 1920 // factor, 1080 // factor
for frame_number in range(train_size):
Frame = GT.loc[GT[1] == frame_number]
x1 = list(Frame[8])
y1 = list(Frame[11])
x2 = list(Frame[10])
y2 = list(Frame[9])
points = [[(round(x1_), round(y1_)), (round(x2_), round(y2_))] for x1_, y1_, x2_, y2_ in zip(x1, y1, x2, y2)]
#其中VOC2012/JPEGImages/不能改
with open(os.path.join('xmls', str(frame_number) + '.xml'), 'w') as file:
file.write('<annotation>\n')
file.write(indent('<folder>voc2012</folder>\n', 1))
file.write(indent('<filename>' + str(frame_number) + '.jpg' + '</filename>\n', 1))
file.write(indent('<path>D:/pedestrian_data/VOC2012/JPEGImages/' + str(frame_number) + '.jpg' + '</path>\n', 1))
file.write(indent('<size>\n', 1))
file.write(indent('<width>' + str(width) + '</width>\n', 2))
file.write(indent('<height>' + str(height) + '</height>\n', 2))
file.write(indent('<depth>3</depth>\n', 2))
file.write(indent('</size>\n', 1))
for point in points:
top_left = point[0]
bottom_right = point[1]
if top_left[0] > bottom_right[0]:
xmax, xmin = top_left[0] // factor, bottom_right[0] // factor
else:
xmin, xmax = top_left[0] // factor, bottom_right[0] // factor
if top_left[1] > bottom_right[1]:
ymax, ymin = top_left[1] // factor, bottom_right[1] // factor
else:
ymin, ymax = top_left[1] // factor, bottom_right[1] // factor
file.write(indent('<object>\n', 1))
file.write(indent('<name>' + name + '</name>\n', 2))
file.write(indent('<pose>Unspecified</pose>\n', 2))
file.write(indent('<truncated>' + str(0) + '</truncated>\n', 2))
file.write(indent('<difficult>' + str(0) + '</difficult>\n', 2))
file.write(indent('<bndbox>\n', 2))
file.write(indent('<xmin>' + str(xmin) + '</xmin>\n', 3))
file.write(indent('<ymin>' + str(ymin) + '</ymin>\n', 3))
file.write(indent('<xmax>' + str(xmax) + '</xmax>\n', 3))
file.write(indent('<ymax>' + str(ymax) + '</ymax>\n', 3))
file.write(indent('</bndbox>\n', 2))
file.write(indent('</object>\n', 1))
file.write('</annotation>\n')
print('File:', frame_number, end='\r')
功能:提取TownCentre-groundtruth.top中的標註信息,存放到xmls目錄下。
注意:程序中關於VOC2012的目錄路徑必須與數據集的要求保持一致。
可以從xmls文件查看到標註信息。
2.3生成Pascal VOC2012數據集
Pascal VOC2012官網:http://host.robots.ox.ac.uk/pascal/VOC/voc2012/index.html
將上面生成的訓練集圖片,images目錄下的圖片複製到:
D:\pedestrian_data\VOC2012\JPEGImages
將xmls文件複製到:
D:\pedestrian_data\VOC2012\Annotation
在D:\pedestrian_data\VOC2012\ImageSets\Main目錄下生成pedestrin_train.py和pedestrin_val.py(可以用腳本creat_trainval.py來生成)
注意pedestrin_train.py和aeroplane_train.py文件名,如果不修改C:\Users\P7XXTM1-G\AppData\Local\conda\conda\envs\tensorflow_gpu_1.12_py37\models\research\object_detection\dataset_tools\create_pascal_tf_record.py文件的話,則必須要用aeroplane_train.py和aeroplane_val.py來命名。
2.4生成tf record
其中,label_map文件用來描述數據有多少個類別,每個類別的id和name是什麼。製作label_map.pbtxt文件可以參考下面的文件:
C:\Users\P7XXTM1G\AppData\Local\conda\conda\envs\tensorflow_gpu_1.12_py37\models\research\object_detection\data\pet_label_map.pbtxt
也可以用
C:\Users\P7XXTM1-G\AppData\Local\conda\conda\envs\tensorflow_gpu_1.12_py37\models\research\object_detection\legacy\train.py
三、Tensorflow訓練
3.1遷移學習
選好預訓練模型,通過tensorflow object detection API進行遷移學習。
下載模型:
下載其中的ssd_mobilenet_v2_coco
我下載好的目錄
F:\development\Pedestrian-Detection-master\ssd_mobilenet_v2_coco_2018_03_29\ssd_mobilenet_v2_coco_2018_03_29
修改config文件:config文件在
C:\Users\P7XXTM1-G\AppData\Local\conda\conda\envs\tensorflow_gpu_1.12_py37\models\research\object_detection\samples\configs\ssdlite_mobilenet_v2_coco.config
修改PATH_TO_BE_CONFIG,修改好後,將ssdlite_mobilenet_v2_coco.config文件拷貝到下面的目錄:
D:\pedestrian_train\models
3.2運行訓練
python object_detection/model_main.py --pipeline_config_path=D:/pedestrian_train/models/ssd_mobilenet_v2_coco.config --model_dir=D:/pedestrian_train/models/train --num_train_steps=1500 --sample_1_of_n_eval_examples=1 --alsologstderr
其中,num_train_step用於設置訓練步數。這一步也可以一同object_detection/legacy/train.py來實現如下。
python object_detection/legacy/train.py --train_dir=D:/pedestrian_train/models/train --pipeline_config_path=D:/pedestrian_train/models/ssd_mobilenet_v2_coco.config logtostderr
可視化命令tensorboard --logdir=D:/pedestrian_train/models/train
其中, D:/pedestrian_train/models/train這個路徑是ckpt路徑。
訓練生成的ckpt文件
可視化結果如下
四、導出模型在Opencv中實現行人檢測
4.1模型導出生成pb文件
python object_detection\export_inference_graph.py --input_type=image_tensor --pipeline_config_path=D:/pedestrian_train/models/ssd_mobilenet_v2_coco.config --trained_checkpoint_prefix=D:\pedestrian_data\model\model.ckpt-1000 --output_directory=D:/pedestrian_data/test
pb文件可以在tensorflow中使用,來檢測出行人。
4.2 Opencv中使用tensorflow
要先用opencv源代碼中的一個腳本:
D:\packages\opencv-4.1.1\sources\samples\dnn\tf_text_graph_ssd.py來生產pbtxt文件。
輸入命令:python tf_text_graph_ssd.py
上圖顯示了需要輸入的參數。
(tensorflow_gpu_1.12_py37) D:\packages\opencv-4.1.1\sources\samples\dnn>python tf_text_graph_ssd.py --input=D:\pedestrian_data\test\frozen_inference_graph.pb --output=D:\pedestrian_data\test\graph.pbtxt --config=D:\pedestrian_data\test\pipeline.config
此命令可生成pbtxt文件。
4.3運行結果