如何用PaddleDetection做一个完整的目标检测项目
PaddleDetection 是百度飞桨推出的物体检测统一框架。支持现有的RCNN、SSD、YOLO等系列模型、支持 ResNet、ResNet-VD、ResNeXt、ResNeXt-VD、SENet、MobileNet、DarkNet等主干网络。针对不同的业务场景(性能、目标大小、准确率等)可以选择框架中的不同模块组合得到最适合的模型,实现任务。相比于tensorflow的Object_Detection,优势之一就是将YOLOv3这一目标检测的快速算法融合到了框架下。
文章将以一个Yolov3识别水果的例子为说明,详解如何利用PaddleDetection完成一个项目。
项目用到的工具 硬件:Win10(RTX2060)笔记本、某品牌服务器(4*T4)工业相机(Hikvision)软件:pycharm、VS2019。
目录:
- 环境部署
- 数据集准备
- 训练
- 训练过程可视化
- 模型导出
- python进行单张/多张图片的预测
- python+qt(给客户的演示demo)
- C++进行单张预测(含编译简介)
- C++预测代码封装成DLL、配合C#完成一个整体项目
- 扩展:关于PaddlePaddle代码数据读取的方式。
01.环境部署
1.1 安装PaddlePaddle
利用anaconda创建一个名字叫做paddle-detection的Paddle环境(备注:下文中命令提示窗口出现的(paddle)是指该项目环境的名称叫做paddle)。安装链接如下: https://www. paddlepaddle.org.cn/ins tall/quick
1.2 安装COCO-API
1 pip install Cython
2 pip install git+https://github.com/philferriere/cocoapi.git#subdirectory=PythonAPI
1.3 选择一个文件夹,下载PaddleDetection
第一种方式:直接从github官网上进行下载:
https:// github.com/PaddlePaddle /PaddleDetection
第二种方式:使用git进行下载:
1 git clone https://github.com/PaddlePaddle/PaddleDetection.git
1.4 安装所需的Python其他依赖库
依赖库文档在requirements.txt中给出,可使用
1 pip install -r requirements.txt
如下图所示是requirements.txt文档中的内容。
如图为requirements文件中的内容,图中所示的均为PaddleDetection的依赖库。
在下图所示内容中打“cmd”,然后出现在该路径的命令提示符。
激活环境,并且 pip install -r requirements.txt
然后运行
当显示Successfully…… ,基本上表示安装完成了,具体是否成功,下一步的测试验证。
1.5 确认测试通过
1 set PYTHONPATH=`pwd`:$PYTHONPATH
2 python ppdet/modeling/tests/test_architectures.py
但是发现运行报错,报错内容如下:
错误提示发现缺少“ppdet”这个模块,ppdet(其实就是paddle detection的一个缩写),但是我找到 ppdet/modeling/tests/test_architectures.py这个文件,然后添加红框所示的代码
出现如图所示的代码,表示运行成功。
至此,所有的运行环境已经配置成功。
02.数据集的准备
2.1 数据标注:
目前项目使用的数据集格式是VOC数据格式,使用labelimg作为标注工具,标注工具的下载安装见链接: https:// zhuanlan.zhihu.com/p/97 807042
特别说明:项目中使用的数据集是PaddleDetection提供的演示示例数据集,下文将通过使用该数据首先,下载该数据集,
下载地址: https:// pan.baidu.com/wap/init? surl=ZO8OlqvWuMk_sqOwlo56rg
提取码:vw3b
下载后如下图所示:
标注方式如下:
打开软件,并导入图片:
选取标注文件的保存路径:
点击Change Save Dir ,然后将标注文件保存在某一个路径下。
开始标注:点击Create\nRectBo---框选目标--命名(下图中命名为apple)--点击OK---点击Save(完成)
所有标注完成以后会生成很多的xml文件。
打开一个xml文件:
具体信息如下:
2.2 创建VOC数据集格式
其中Annotations存放标注生成的xml文件,JPEGImage存放图片,ImageSets存放对训练集和
备注:train.txt、val.txt是根据下文中代码(该代码会命名为:get_list.py,放置在了数据集链接的文字
接上文所述,是生成生成train.txt、val.txt的代码,该代码会将300张水果图片分成240张训练
1 import os
2 import random
4 train_precent=0.7
5 xml="C:/Users/zhili/Desktop/fruit-detection/Annotations"
6 save="C:/Users/zhili/Desktop/fruit-detection/ImageSets/Main"
7 total_xml=os.listdir(xml)
9 num=len(total_xml)
10 tr=int(num*train_precent)
11 train=range(0,tr)
13 ftrain=open("C:/Users/zhili/Desktop/fruit-detection/ImageSets/Main/train.txt","w")
14 ftest=open("C:/Users/zhili/Desktop/fruit-detection/ImageSets/Main/test.txt","w")
16 for i in range(num):
17 name=total_xml[i][:-4]+"\n"
18 if i in train:
19 ftrain.write(name)
20 else:
21 ftest.write(name)
22 ftrain.close()
23 ftest.close()
如下图是生成的train文件。
备注:在Main文件夹中生成的train.txt文件和val.txt文件仅仅是对数据集的划分,还需要进一步的利用
1 import os
2 import os.path as osp
3 import re
4 import random
6 devkit_dir = './'
7 years = ['2007', '2012']
10 def get_dir(devkit_dir, type):
11 return osp.join(devkit_dir, type)
14 def walk_dir(devkit_dir):
15 filelist_dir = get_dir(devkit_dir, 'ImageSets/Main')
16 annotation_dir = get_dir(devkit_dir, 'Annotations')
17 img_dir = get_dir(devkit_dir, 'JPEGImages')
18 trainval_list = []
19 test_list = []
20 added = set()
22 for _, _, files in os.walk(filelist_dir):
23 for fname in files:
24 img_ann_list = []
25 if re.match('train\.txt', fname):
26 img_ann_list = trainval_list
27 elif re.match('val\.txt', fname):
28 img_ann_list = test_list
29 else:
30 continue
31 fpath = osp.join(filelist_dir, fname)
32 for line in open(fpath):
33 name_prefix = line.strip().split()[0]
34 if name_prefix in added:
35 continue
36 added.add(name_prefix)
37 ann_path = osp.join(annotation_dir, name_prefix + '.xml')
38 img_path = osp.join(img_dir, name_prefix + '.jpg')
39 assert os.path.isfile(ann_path), 'file %s not found.' % ann_path
40 assert os.path.isfile(img_path), 'file %s not found.' % img_path
41 img_ann_list.append((img_path, ann_path))
43 return trainval_list, test_list
46 def prepare_filelist(devkit_dir, output_dir):
47 trainval_list = []
48 test_list = []
49 trainval, test = walk_dir(devkit_dir)
50 trainval_list.extend(trainval)
51 test_list.extend(test)
52 random.shuffle(trainval_list)
53 with open(osp.join(output_dir, 'train.txt'), 'w') as ftrainval:
54 for item in trainval_list:
55 ftrainval.write(item[0] + ' ' + item[1] + '\n')
57 with open(osp.join(output_dir, 'val.txt'), 'w') as ftest:
58 for item in test_list:
59 ftest.write(item[0] + ' ' + item[1] + '\n')