使用 PP-ShiTu 全流程教你使用少量的图像分类数据集完成目标检测任务。

在这里插入图片描述

挑战内容

本赛题以智慧零售为真实应用开发场景,要求参赛选手基于计算机视觉技术完成该场景下智慧结算系统的开发设计,如视觉结算台、智能货架、智能购
物车等(如下图所示),考察参赛选手在产品设计、数据处理、模型设计、模型部署等方面的综合能力。
在这里插入图片描述

背景

智慧零售,也称“智慧新零售”,是我国零售业为改变传统零售业的困局,基于互联网、人工智能等技术,对“消费者、货品、场景”的重塑。通过大数据分析消费者消费习惯,满足消费者需求,提供个性化产品和服务。换言之,智慧零售的核心是围绕消费者而产生的购买行为、场景体验和生产设计中,融入数字智能化平台,优化企业资源分配和场景布局效益,模糊线上线下界线并实现线上营销精准化和线下门店高效化。

基于此,我们对于现存的零售商店进行分析思考,使用基于PP-ShiTu带来智能零售结算系统,可以将该技术部署至智能设备应用于线下门店,实现自主购物交易,为新的技术品牌商及商超零售企业开始引进人工智能技术,探索商品管理、成本控制、用户体验等多维度的数字化转型。

环境准备

注意这里下载的是2.3版本的PaddleClas,使用的是PP-ShiTu,官网最新推出了PP-ShiTuV2。

#paddleClas下载
!git clone https://gitee.com/paddlepaddle/PaddleClas.git -b release/2.3
#依赖安装
%cd /home/aistudio/PaddleClas/
!pip install --upgrade -r requirements.txt -i https://mirror.baidu.com/pypi/simple

一 数据集处理

根据我们采用的PP-ShiTu方案,所以需要对数据集进行特定的处理。

原本数据集是目标检测数据集,这里的数据集为对单个目标物体进行截取形成图像,以此构建出图像分类数据集。

#解压数据集
%cd /home/aistudio/data/
!unzip -oq /home/aistudio/data/data144965/goods10.zip
#修复文件名乱码
%cd /home/aistudio/data/goods10/
import os
#names = ['方形蛋糕', '红灯笼椒', '全开盖', '草莓', '易撕盖', '莲雾果', '苹果', '易拉盖', '圆形蛋糕']
#dicts = {'▓▌▌о':'草莓', '╖╜╨╬╡░╕т':'方形蛋糕', '╘▓╨╬╡░╕т':'圆形蛋糕', '╞╗╣√':'苹果', '╚л┐к╕╟':'全开盖', '╥╫└н╕╟':'易拉盖', '╥╫╦║╕╟':'易撕盖', '║ь╡╞┴¤╜╖':'红灯笼椒', '┴л╬э╣√':'莲雾果'}
dicts = {'▓▌▌о':1, '╖╜╨╬╡░╕т':2, '╘▓╨╬╡░╕т':3, '╞╗╣√':4, '╚л┐к╕╟':5, '╥╫└н╕╟':6, '╥╫╦║╕╟':7, '║ь╡╞┴¤╜╖':8, '┴л╬э╣√':9}
for dirs in os.listdir("./"):
    
    if (dirs == 'train'):
        for dir_train in os.listdir('./train'):
            old = 'train/{}'.format(dir_train)
            new = 'train/{}'.format(dicts[dir_train])
            os.renames(old, new)
    if (dirs == 'test'):
        for dir_train in os.listdir('./test'):
            old = 'test/{}'.format(dir_train)
            new = 'test/{}'.format(dicts[dir_train])
            os.renames(old, new)

图像数据制作

我们当前存在的数据情况如下,面对没有现成的图像分类数据集的情况,我们需要自己进行制作:

在这里插入图片描述

一个图像中存在多个物品,而我们如果需要使用ShiTu方案的话就需要把这些个体目标截取出来形成单独的数据集。

在这里插入图片描述

接下来我就简单的介绍一下该类数据集快捷的制作方法,下面这部分需要在本地实现。

labelimg

这是一款用于目标检测数据集制作的工具,我们可以通过python下载这个工具,只需要在终端输入:

pip install labelimg -i https://pypi.tuna.tsinghua.edu.cn/simple

即可完成下载,然后再终端输入:labelimg 即可打开该工具。

在这里插入图片描述

用法读者自行百度,通过该软件标注,我们可以获取图像的相关信息,以xml文件的形式进行存储。

因为PP-ShiTu方案的优越性,我们并不需要标很多数据集,标注的数量远远小于完成目标检测的数据标注量。

切分图像

根据生成的xml文件,我们可以利用编程对图像进行截取后分类存储,这样就完成了我们需要的数据集,代码如下。

#该代码的作用就是,通过读取XML配置文件来截取图像中的目标物品然后单独生成图像进行存储。
import xml.etree.ElementTree as ET
import sys
import os
import cv2
import datetime as dt

class splitImg():
    def __init__(self, savePath, xmlsPath):
        self.xmin = []
        self.ymax = []
        self.ymin = []
        self.xmax = []

        self.imgPath = ""
        self.name = []

        self.savePath = savePath
        self.xmlsPath = xmlsPath

    def read_xml(self, filename):
    #读取xml文件获取信息
        self.name = []

        self.xmin = []
        self.ymax = []
        self.ymin = []
        self.xmax = []
        tree = ET.parse(filename)
        self.imgPath = tree.findall("path")[0].text
        for i in range(len(tree.findall("object"))):
            self.xmin.append(tree.findall("object")[i].find("bndbox")[0].text)
            self.ymin.append(tree.findall("object")[i].find("bndbox")[1].text)
            self.xmax.append(tree.findall("object")[i].find("bndbox")[2].text)
            self.ymax.append(tree.findall("object")[i].find("bndbox")[3].text)
            self.name.append(tree.findall("object")[i].find("name").text)
        # print(len(tree.findall("object")))
        # print(self.imgPath, "\n", self.box, "\n", self.name, "\n")
    def selectROI(self):
    #截取roi区域
        img = cv2.imread(self.imgPath)
        # print(self.imgPath)
        # print(self.ymin, "\n", self.ymax, "\n", self.xmin, self.xmax, "\n")
        for i in range(len(self.name)):
            roiImg = img[int(self.ymin[i]):int(self.ymax[i]), int(self.xmin[i]):int(self.xmax[i])]
            #根据系统时间命名图像
            now_time = dt.datetime.now().strftime("%Y%m%d%H%M%S%f")
            saveName = os.path.join(self.savePath+"/"+self.name[i]+"/", str(now_time)[:]+".jpg")
            if not os.path.exists(self.savePath+"/"+self.name[i]+"/"):
                os.mkdir(self.savePath+"/"+self.name[i]+"/")
            cv2.imwrite(saveName, roiImg)
            cv2.waitKey(1)
    def run(self):
    #运行函数
        for file in os.listdir(self.xmlsPath):
            if file.split(".")[1] == "xml":
                path = os.path.join(self.xmlsPath, file)
                self.read_xml(path)
                self.selectROI()
if __name__ == '__main__':
    #只需要改下面的这两个路径即可
    xmlPath = "E:/xmlFiles/" #存储xml的根目录路径
    savePath = "E:/images/" #需要保存截取图像的位置
    aa = splitImg(savePath, xmlPath)
    aa.run()
#需要保存截取图像的位置
    aa = splitImg(savePath, xmlPath)
    aa.run()

生成数据集路径、分类内容文件(TXT)

我们这里准备好了图像分类的数据集,所以每个图像中放的是单个物品。

在这里插入图片描述

我们需要生成一个txt文件,包含图像路径和其中物品的类别信息,便于后续的分类模型训练、向量检索的特征提取。

格式如下:

在这里插入图片描述

每一行的内容为:图片地址 图像中物品的类别(类别采用LabelEncoder进行编码为数字)图像id 。三个类。

#生成txt配置文件
%cd /home/aistudio/data/goods10
!mv /home/aistudio/process_format_train.py /home/aistudio/data/goods10/process_format_train.py
!python process_format_train.py

总共有9各类别:易撕盖
莲雾果
易拉盖
苹果
圆形蛋糕
红灯笼椒
全开盖
方形蛋糕
草莓

训练集:1006张图像

测试集:176张图像

二 PP-ShiTu方案实现目标检测

对于PP-ShiTu官网有详细的介绍:https://gitee.com/paddlepaddle/PaddleClas/tree/release%2F2.3/

该方案主要有三个部分:主体检测、图像分类、向量检索,接下来将从这三个方面进行解析。

在这里插入图片描述

2.1 主体检测

该部分需要实现的效果是:在图像中找到可能是需要的主体的集合,也就是目标检测,不过是不需要分类的检测(其实是将所有主体标签都视为同一类),需要从图像中提取到所有主体的roi图像,以便后续的分类识别,通过识别来获取到我们需要的目标。
在这里插入图片描述

这个部分,我们可以直接使用PaddleDetection 自研的轻量级模型 PicoDet-LCNet_x2_5 作为 PP-ShiTu 的主体检测模型。也可以自己自定义数据集选取其他的模型进行训练获取模型。使用PaddleDetection方法参考:https://gitee.com/paddlepaddle/PaddleDetection?_from=gitee_search

#建立models文件夹,存放官方的主体检测模型
%cd /home/aistudio/
!mkdir models
%cd models
# 下载通用检测 inference 模型并解压,主体检测模型
!wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/picodet_PPLCNet_x2_5_mainbody_lite_v1.0_infer.tar && tar -xf picodet_PPLCNet_x2_5_mainbody_lite_v1.0_infer.tar

2.2 特征提取

特征提取是图像识别中的关键一环,它的作用是将输入的图片转化为固定维度的特征向量,用于后续的 向量检索 。考虑到特征提取模型的速度、模型大小、特征提取性能等因素,最终选择 PaddleClas 自研的 PPLCNet_x2_5 作为特征提取网络。

该部分需要完成 2.1 主体检测 传来的主体图像进行特征提取,将图像转换成固定维度的特征向量,使得能够进行后续的向量检索,该部分需要获取一个特征提取能力很好的模型。

#不训练可直接下载以下任意一个模型即可
#下载官方使用的推理模型
!mkdir /home/aistudio/models
%cd /home/aistudio/models
!wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/general_PPLCNet_x2_5_lite_v1.0_infer.tar && tar -xf general_PPLCNet_x2_5_lite_v1.0_infer.tar
#模型2
%cd /home/aistudio/models
!wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/vehicle_cls_ResNet50_CompCars_v1.0_infer.tar
!tar -xf vehicle_cls_ResNet50_CompCars_v1.0_infer.tar

2.2.1 分类模型训练

这里作者使用自定义的数据集训练一个图像分类模型来用于特征的提取。数据集已经通过 一 数据处理 中准备完毕,这里我们就可以使用PaddleClas中的方法训练模型。

根据配置文件:/home/aistudio/PaddleClas/ppcls/configs/GeneralRecognition/GeneralRecognition_PPLCNet_x2_5.yaml

使用默认的参数,只需要修改DataLoader下的相关路径位置即可:

在这里插入图片描述

这里需要修改为自定义的数据集的路径

在这里插入图片描述

#一键训练
%cd /home/aistudio/PaddleClas
#替换已经改好的配置文件
!mv /home/aistudio/GeneralRecognition_PPLCNet_x2_5.yaml /home/aistudio/PaddleClas/ppcls/configs/GeneralRecognition/GeneralRecognition_PPLCNet_x2_5.yaml
!python tools/train.py \
    -c ppcls/configs/GeneralRecognition/GeneralRecognition_PPLCNet_x2_5.yaml -o Arch.pretrained=True
    
#导出模型
%cd /home/aistudio/PaddleClas
!python tools/export_model.py \
    -c ppcls/configs/GeneralRecognition/GeneralRecognition_PPLCNet_x2_5.yaml \
    -o Global.pretrained_model=output/RecModel/best_model
#导出模型位置:/home/aistudio/models/infer/

2.3 向量检索

(一) 向量检索技术在图像识别、图像检索中应用比较广泛。该部分需要实现的功能是:对于给定的查询向量,在上部分已经建立好的向量库中,与库中所有的待查询向量,进行特征向量的相似度或距离计算,得到相似度排序。

在这里插入图片描述

(二) 我们使用Faiss来实现该部分的功能,对于Faiss,是由FaceBook的AI团队针对大规模相似度检索问题开发的一个工具,使用C++编写,有python接口,对10亿量级的索引可以做到毫秒级检索的性能。其具有以下特点:

适配性好:支持 Windos、Linux、MacOS 系统

安装方便: 支持 python 接口,直接使用 pip 安装

算法丰富:支持多种检索算法,满足不同场景的需求

同时支持 CPU、GPU,能够加速检索过程

在这里插入图片描述

(三) 检索的大致流程

在这里插入图片描述

如上图中所示,向量检索部分,在整个 PP-ShiTu 系统中有两部分内容

图中绿色部分:建立检索库,供检索时查询使用,同时提供增、删等功能

图中蓝色部分:检索功能,即给定一张图的特征向量,返回库中相似图像的 label

#faiss模块下载
!pip install --upgrade pip
!pip install faiss-cpu==1.7.1post2

检索向量集配置文件(txt)

对于该部分,我们需要数据集用于向量集的提取,同样需要准备txt配置文件。

格式如下:

在这里插入图片描述

图像路径 图像类别 两类。

#生成向量提取txt文件
%cd /home/aistudio/data/goods10
!mv /home/aistudio/process_format.py /home/aistudio/data/goods10/process_format.py
!python process_format.py

修改配置文件

(一) 涉及检索模块配置文件位于:deploy/configs/ 下,其中 build_.yaml 是建立特征库的相关配置文件,inference_.yaml 是检索或者分类的推理配置文件。

其中 yaml 文件的建库的配置如下,在运行时,请根据实际情况进行修改。建库操作会将根据 data_file 的图像列表,将 image_root 下的图像进行特征提取,并在 index_dir 下进行存储,以待后续检索使用。

其中 data_file 文件存储的是图像文件的路径和标签,每一行的格式为:image_path label。中间间隔以 yaml 文件中 delimiter 参数作为间隔。

关于特征提取的具体模型参数,可查看 yaml 文件。
在这里插入图片描述

(二) 参数解释:

index_method:使用的检索算法。目前支持三种,HNSW32、IVF、Flat

index_dir:构建的特征库所存放的文件夹

image_root:构建特征库所需要的标注图像所存储的文件夹位置

data_file:构建特征库所需要的标注图像的数据列表,每一行的格式:relative_path label

index_operation: 此次运行建库的操作:new 新建,append 将 data_file 的图像特征添加到特征库中,remove 将 data_file 的图像从特征库中删除

delimiter:data_file 中每一行的间隔符

dist_type: 特征匹配过程中使用的相似度计算方式。例如 IP 内积相似度计算方式,L2 欧式距离计算方法

embedding_size:特征维度

#一键构建向量库
# 进入 deploy 目录
%cd /home/aistudio/PaddleClas/deploy
# yaml 文件根据需要改成自己所需的具体 yaml 文件
!mv /home/aistudio/build_general.yaml /home/aistudio/PaddleClas/deploy/configs/build_general.yaml #直接替换好配置好的文件
!python python/build_gallery.py -c configs/build_general.yaml

到这里,models文件夹下存在三个文件夹在这里插入图片描述

index 表示基于原始图像构建得到的索引库信息

infer 表示图像特征提取模型,即 步骤二 中获取到的模型

picodet_PPLCNet_x2_5_mainbody_lite_v1.0_infer 主体检测模型

models 文件夹下应有如下文件结构

在这里插入图片描述

三 效果展示

基于以上几步,我们就得到了三个主要的配置文件,两个模型,一个向量库。

当这三个元素都准备好后就可以进行预测展示了。

#预测
%cd /home/aistudio/PaddleClas/deploy/
#替换修改好的文件
!mv /home/aistudio/inference_general.yaml /home/aistudio/PaddleClas/deploy/configs/inference_general.yaml
!mv /home/aistudio/draw_bbox.py /home/aistudio/PaddleClas/deploy/utils/draw_bbox.py
#单图片预测
!python python/predict_system.py -c configs/inference_general.yaml -o Global.infer_imgs="/home/aistudio/10.png" -o IndexProcess.index_dir="/home/aistudio/models/index" -o Global.use_gpu=False 
#批量检测
!python3.7 python/predict_system.py -c configs/inference_general.yaml -o Global.infer_imgs="./drink_dataset_v1.0/test_images/"

检测结果图片在 文件路径/home/aistudio/output下查看

总结

本项目基于PP-ShiTu,采用官方的主体检测模型,使用自定义的数据集进行了图像分类模型的训练,以及基于该模型完成向量集的提取,完成了智慧零售场景中的物品的目标检测任务,最后效果也十分不错,希望改篇文章可以帮助大家更好的上手PP-ShiTu完成自己的目标检测任务。

(一) 使用 PP-ShiTu 可以不需要很多的数据集即可完成目标检测任务

(二) 该方案效率高,细粒度识别效果比较好。

感谢作者韩三岁:https://aistudio.baidu.com/aistudio/personalcenter/thirdview/381661 对本项目的指导。

数据及制作参考:https://blog.csdn.net/Yibaomeimei/article/details/127396013?spm=1001.2014.3001.5502

此文章为搬运
原项目链接

Logo

学大模型,用大模型上飞桨星河社区!每天8点V100G算力免费领!免费领取ERNIE 4.0 100w Token >>>

更多推荐