系列文章:如何利用PaddleDetection做一个完整的项目(一)

系列文章:如何利用PaddleDetection做一个完整的项目(一)


0PaddleDetection简介

PaddleDetection 是PaddlePaddle推出的物体检测统一框架。支持现有的RCNN、SSD、YOLO等系列模型、支持 ResNet、ResNet-VD、ResNeXt、ResNeXt-VD、SENet、MobileNet、DarkNet等主干网络。针对不同的业务场景(性能、目标大小、准确率等)可以调用框架下的不同参数(或者是参数文件),实现任务。相比于tensorflow的Object_Detection,优势之一就是将YOLO这一目标检测的快速算法融合到了框架下。

文章将以一个例子为说明,来谈如何利用paddleDetection完成一个项目

项目用到的工具 硬件:Win10(RTX2060)笔记本、某品牌服务器(4*T4)工业相机(Hikvision)软件:pycharm、VS2019

文章结构如下,本文章将介绍1-6

1、环境部署

2、数据集准备

3、训练

4、训练过程可视化

5、模型导出

6、python进行单张/多张图片的预测

7、python+qt(给客户的演示demo)

8、C++进行单张预测(含编译简介)

9、C++预测代码封装成DLL、配合C#完成一个整体项目

10、扩展:关于PaddlePaddle代码数据读取的方式。

1环境部署

1.1安装paddle

利用anaconda创建一个名字叫做anaconda的paddle环境(备注:下文中命令提示窗口出现的(paddle)是指该项目环境的名称叫做paddle)具体安装方式见如下链接

1.2安装COCO-API

pip install Cython
pip install git+https://github.com/philferriere/cocoapi.git#subdirectory=PythonAPI

1.3选择一个文件夹,下载PaddleDetection

第一种方式:直接从github官网上进行下载 github.com/PaddlePaddle

第二种方式:使用git进行下载:git clone

1.4安装所需的Python其他依赖库

依赖库文档在requirements.txt中给出,可使用pip install -r requirements.txt,如下图所示是requirements.txt文档中的内容。

如图为requirements文件中的内容,图中所示的均为Paddle Detection的依赖库。

在下图所示内容中打“cmd”,然后出现在该路径的命令提示符。

激活环境,并且 pip install -r requirements.txt

然后运行

当显示Successfully…… ,基本上表示安装完成了,具体是否成功,下一步的测试验证

1.5确认测试通过

set PYTHONPATH=`pwd`:$PYTHONPATH
python ppdet/modeling/tests/test_architectures.py  ###备注:在paddle自带的文档中为export PYTHONPATH=`pwd`:$PYTHONPATH
export是linux下的用法,在windows下将exoprt改成set

但是发现运行报错,报错内容如下:

错误提示发现缺少“ppdet”这个模块,ppdet(其实就是paddle detection的一个缩写),但是我们在项目的路径里面可以发现有这个模块,原因就是,我们的代码所在的路径无法读取到该文件下的代码,因此,我们需要在代码中进行改进一下。

找到 ppdet/modeling/tests/test_architectures.py这个文件,然后添加红框所示的代码。备注,第二个红框里面的路径是我的项目路径

出现如图所示的代码,表示运行成功

至此,所有的运行环境已经配置成功。

2数据集的准备

2.1数据标注:

目前项目使用的数据集格式是VOC数据格式,使用labelimg作为标注工具,标注工具的下载安装见如下链接


特别说明:项目中使用的数据集是PaddleDetection提供的演示示例数据集,下文将通过使用该数据集来说明。

首先,下载该数据集,下载后如下图所示:下载链接,提取码:vw3b 。


标注方式如下:

  • 打开软件,并导入图片:
  • 选取标注文件的保存路径
  • 点击Change Save Dir ,然后将标注文件保存在某一个路径下。
  • 开始标注:点击Create\nRectBo---框选目标--命名(下图中命名为apple)--点击OK---点击Save(完成一张)--点击Next Image 标注下一张。

所有标注完成以后会生成很多的xml文件。

标注后的xml文件列表

打开一个xml文件

具体信息如下:

2.2创建VOC数据集格式

其中Annotations存放标注生成的xml文件,JPEGImage存放图片,ImageSets存放对训练集和数据集的划分。ImageSet下有Main文件,Mian下需要建立一个label_list.txt。label_list.txt是指标注的目标的名称。其内容如下:

备注:train.txt、val.txt是根据下文中代码(该代码会命名为:get_list.py,放置在了数据集链接的文件里面)生成,分别是对训练集和验证集的划分接上文所述,是生成生成train.txt、val.txt的代码,该代码会将300张水果图片分成240张训练集和60张验证集。

import os
import random
train_precent=0.8
xml="C:/Users/zhili/Desktop/fruit-detection/Annotations"
save="C:/Users/zhili/Desktop/fruit-detection/ImageSets/Main"
total_xml=os.listdir(xml)
num=len(total_xml)
tr=int(num*train_precent)
train=range(0,tr)
ftrain=open("C:/Users/zhili/Desktop/fruit-detection/ImageSets/Main/train.txt","w")
ftest=open("C:/Users/zhili/Desktop/fruit-detection/ImageSets/Main/test.txt","w")
for i in range(num):
    name=total_xml[i][:-4]+"\n"
    if i in train:
        ftrain.write(name)
 else:
        ftest.write(name)
ftrain.close()
ftest.close()

如下图是生成的train文件

备注:在Main文件夹中生成的train.txt文件和val.txt文件仅仅是对数据集的划分,还需要进一步的利用如下代码(create_list.py,该代码是paddle提供的)生成含有路径信息以及图像和xml文件一一对应的文件。

import os
import os.path as osp
import re
import random
devkit_dir = './'
years = ['2007', '2012']
def get_dir(devkit_dir,  type):
 return osp.join(devkit_dir, type)
def walk_dir(devkit_dir):
    filelist_dir = get_dir(devkit_dir, 'ImageSets/Main')
    annotation_dir = get_dir(devkit_dir, 'Annotations')
    img_dir = get_dir(devkit_dir, 'JPEGImages')
    trainval_list = []
    test_list = []
    added = set()
 for _, _, files in os.walk(filelist_dir):
 for fname in files:
            img_ann_list = []
 if re.match('train\.txt', fname):
                img_ann_list = trainval_list
 elif re.match('val\.txt', fname):
                img_ann_list = test_list
 else:
 continue
 fpath = osp.join(filelist_dir, fname)
 for line in open(fpath):
                name_prefix = line.strip().split()[0]
 if name_prefix in added:
 continue
 added.add(name_prefix)
                ann_path = osp.join(annotation_dir, name_prefix + '.xml')
                img_path = osp.join(img_dir, name_prefix + '.jpg')
 assert os.path.isfile(ann_path), 'file %s not found.' % ann_path
 assert os.path.isfile(img_path), 'file %s not found.' % img_path
                img_ann_list.append((img_path, ann_path))
 return trainval_list, test_list
def prepare_filelist(devkit_dir, output_dir):
    trainval_list = []
    test_list = []
    trainval, test = walk_dir(devkit_dir)
    trainval_list.extend(trainval)
    test_list.extend(test)
    random.shuffle(trainval_list)
 with open(osp.join(output_dir, 'train.txt'), 'w') as ftrainval:
 for item in trainval_list:
            ftrainval.write(item[0] + ' ' + item[1] + '\n')
 with open(osp.join(output_dir, 'val.txt'), 'w') as ftest:
 for item in test_list: