基于Tensorflow和Opencv的行人检测

    技术2022-07-12  61

    本文主要记录在Tensorflow和Opencv环境下实现行人检测的主要步骤,特别是一些常用命令和需要用到的脚本文件,生成的模型文件等。文章主要分为以下几个部分:环境搭建、数据集生成制作、Tensoflow训练、导出模型在Opencv中实现行人检测。

     

    目录

    一、环境搭建... 2

    1.1 tensorflow.. 2

    1.2 opencv. 2

    1.3下载opencv4.1.1源码... 3

    1.4下载安装protoc. 3

    1.5安装Tensorflow object_detection API及下载models文件... 3

    1.6 下载视频数据集... 4

    二、数据集生成制作... 4

    2.1获取每一帧图像... 4

    2.2获取标注信息... 5

    2.3生成Pascal VOC2012数据集... 6

    2.4生成tf record. 8

    三、Tensorflow训练... 9

    3.1迁移学习... 9

    3.2运行训练... 10

    四、导出模型在Opencv中实现行人检测... 11

    4.1模型导出生成pb文件... 11

    4.2 Opencv中使用tensorflow.. 11

    4.3运行结果... 12

     

     

    一、环境搭建

    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进行迁移学习。

    下载模型:

    https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md

    下载其中的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运行结果

     

     

    Processed: 0.012, SQL: 9