这个章节打算介绍如何利用py-qt编一个显示界面,并结合工业相机实时采集并进行目标检测。
文章用到的软件有pyqt5、pycharm、Hikvision工业相机。
文章内容如下:
1、在pycharm下搭建pyqt的环境;
2、介绍paddle保存模型、加载模型的形式以及模型的说明;
3、如何利用paddle检测单帧图像
4、pyqt5效果展示

1在pycharm下搭建pyqt5的环境

该过程见链接,作者将paddle和pyqt5安装在了同一个虚拟环境下面。
https://editor.csdn.net/md/?articleId=104687950

2介绍paddle模型保存、模型加载的形式以及模型的说明

介绍模型的保存和加载目的是更好的了解paddle更好的理解预测过程。本文中主要来说明模型保存的函数 fluid.io.save_params、fluid.io.save_inference_model和模型加载的函数 fluid.io.save_params 、fluid.io.load_inference_model
2-1模型的保存
2-1-1 fluid.io.save_params
fluid.io.save_params:从字面上意思来理解,表示保存参数。而该函数的主要目的也确实是保存训练过程中生成的各个节点之间的参数(权重、偏置等),使用fluid.io.save_params进行模型的保存,其保存的内容如下图所示:
在这里插入图片描述
2-1-2 fluid.io.save_inference_model
fluid.io.save_inference_model:从字面上意思来理解,表示保存可进行后续预测的模型。而该函数的主要目的也确实是保存可进行预测的模型。即调用save_inference_model函数,可将save_params所保存的参数基础上融合网络结构生成的一个可进行预测的模型。这一点类似于tensorflow将训练出来的ckpt文件固化成pb文件。从我们git中下载的PaddleDetection代码中,在PaddleDetection-relaase/tools/export_model中就是利用save_inference_model导出结合后的模型。
利用export_model.py保存下来的文件如下所示:生成了两个文件,__model__和__params__文件,其中__model__表示网络结构,__params__表示训过程产生的参数。

2-2模型的加载
fluid.io.load_params:根据上文得知,该函数表示加载训练过程中的参数进行预测,如果要加载参数进行预测,则需要将网络结构也加载进来,PaddleDetection给出的官方预测的示例就是利用该方式进行预测。
2-2-2 fluid.io.load_inference_model
fluid.io.load_inference_model:根据上文得知,该函数表述加载了参数和网络结构的融合体进行预测。作者在如下的内容中就是使用该方式进行预测。

2-3备注
2-3-1 备注一
在paddle生成的__model__文件里面是包含了NMS部分(这一点和tensorflow的pb文件不同,pb文件是没有NMS节点的)关于__model__文件,我们可以使用Netron进行展开。Netron使用地址https://lutzroeder.github.io/netron/ 打开以后可看到网络结构,在最下端发现有NMS节点。
在这里插入图片描述
2-3-2 备注二
出了上述谈到的模型加载和保存的方式,还有另外一组即fluid.io.save_inference_model和fluid.io.load_persistables。

3如何利用paddle进行预测

在PaddleDetection里面已经有了相应的预测代码infer.py,在该代码中是利用paddle的reader机制进行图像的预测,同时该代码使用的加载模型的方式是fluid.io.load_params。作者个人为了能配合后续在qt下运行检测,使用fluid.io.load_inference_model作为模型的加载方式,从paddle的AI Studio上截取了一部分代码重新构造了预测代码。

作者构造自身的预测代码思路如下图所示:

代码如下:
说明:
1、 该代码由于使用参数和网络结构融合的模型,因此对于其他库的依赖比较少,只需要将paddle导入即可,
2、 该代码由于使用的模型文件是《 model__和__params 》,因此在使用load_inference__model时候,必须在该函数的参数中指明这两个名字。
在这里插入图片描述
3、 该代码中需要着重注意一下一点:图像在度如时候需要进行归一化,归一化的数据来源训练该模型的config文件
在这里插入图片描述
在这里插入图片描述

import numpy as np
import time
import paddle.fluid as fluid
from PIL import Image
from PIL import ImageDraw
train_parameters = {
    "label_dict": {0:"apple",1:"banana",2:"orange"},
    "use_gpu": True,
    "input_size": [3, 608, 608],    # 原版的边长大小为608,为了提高训练速度和预测速度,此处压缩为448
target_size = train_parameters['input_size']
anchors = train_parameters['anchors']
anchor_mask = train_parameters['anchor_mask']
label_dict = train_parameters['label_dict']
print(label_dict[1])
# class_dim = train_parameters['class_dim']
# print("label_dict:{} class dim:{}".format(label_dict, class_dim))
place = fluid.CUDAPlace(0) if train_parameters['use_gpu'] else fluid.CPUPlace()
exe = fluid.Executor(place)
path="C:\\Users\\zhili\\Desktop\\2"#_mobilenet_v1
[inference_program, feed_target_names, fetch_targets] = fluid.io.load_inference_model(dirname=path, executor=exe,model_filename='__model__', params_filename='__params__')
class inference():
    def __init__(self):
        print("8888888888")
    def draw_bbox_image(self,img, boxes, labels,scores, save_name):
        给图片画上外接矩形框
        :param img:
        :param boxes:
        :param save_name:
        :param labels
        :return:
        draw = ImageDraw.Draw(img)
        for box, label,score in zip(boxes, labels,scores):
            print(box, label, score)
            if(score >0.9):
                xmin, ymin, xmax, ymax = box[0], box[1], box[2], box[3]
                draw.rectangle((xmin, ymin, xmax, ymax), 3, 'red')
                draw.text((xmin, ymin), label_dict[label], (255, 255, 0))
        img.save(save_name)
    def resize_img(self,img, target_size):#将图片resize到target_size
        保持比例的缩放图片
        :param img:
        :param target_size:
        :return:
        img = img.resize(target_size[1:], Image.BILINEAR)
        return img
    def read_image(self,img_path):
        origin = Image.open(img_path)
        img = self.resize_img(origin, target_size)
        resized_img = img.copy()
        if img.mode != 'RGB':
            img = img.convert('RGB')
        img = np.array(img).astype('float32').transpose((2, 0, 1))  # HWC to CHW 让矩阵进行方向的转置
        img = img / 255.0
        img[0, :, :] -= 0.485
        img[1, :, :] -= 0.456
        img[2, :, :] -= 0.406
        img[0, :, :] /=0.229
        img[1, :, :] /=0.224
        img[2, :, :] /=0.225
        img = img[np.newaxis, :]
        return origin, img, resized_img
    def infer(self,image_path):
        预测,将结果保存到一副新的图片中
        :param image_path:
        :return:
        origin, tensor_img, resized_img = self.read_image(image_path)
        input_w, input_h = origin.size[0], origin.size[1]
        image_shape = np.array([input_h, input_w], dtype='int32')
        t1 = time.time()
        batch_outputs = exe.run(inference_program,
                                feed={feed_target_names[0]: tensor_img,
                                      feed_target_names[1]: image_shape[np.newaxis, :]},
                                fetch_list=fetch_targets,
                                return_numpy=False)
        period = time.time() - t1
        print("predict cost time:{0}".format("%2.2f sec" % period))
        bboxes = np.array(batch_outputs[0])
        if bboxes.shape[1] != 6:
            print("No object found in {}".format(image_path))
            return
        labels = bboxes[:, 0].astype('int32')
        scores = bboxes[:, 1].astype('float32')
        boxes = bboxes[:, 2:].astype('float32')
        last_dot_index = image_path.rfind('.')
        out_path = image_path[:last_dot_index]
        out_path += '-result.jpg'
        self.draw_bbox_image(origin, boxes, labels,scores, out_path)
if __name__ == '__main__':
    image_path= "C:\\Users\\zhili\\Desktop\\123\\2.jpg"
    a=inference()
    a.infer(image_path)

4 pyqt5检测效果

1、首先通过步骤1配置好的pyqt中QT Designer,创建两个Button对象,分别为“打开相机”、“开始检测”,然后创建两个Label对象,分别用于显示相机原图和显示检测后图像。
在这里插入图片描述
2、创建多线程检测机制,分别给两个Button设置不同的槽函数,分别用于触发相机拍照和调用检测函数。运行程序可得到如下结构。由于作者使用的是黑白相机,检测效果不是很好,同时由于是初学qt,对其中的显示不是很了解,但是基本上可以看出框选到了目标。
在这里插入图片描述
特别说明:该文章受到了高松鹤同学和百度paddle团队的大力支持,表示感谢
相关代码放置在github上,项目地址:
https://github.com/yzl19940819/Paddle_infer_python

有问题欢迎沟通 作者微信 yzl819819

PaddleDetection源码,PaddleDetection-master PaddleDetection源码,PaddleDetection-master PaddleDetection源码,PaddleDetection-master 2.输入python tools/infer.py -c configs/yolov3/yolov3_mobilenet_v1_270e_voc.yml -o weights=output/yolov3_mobilenet_v1_270e_voc/model_final.pdparams --infer_dir=demo。位置在PaddleDetection/configs/yolov3/yolov3_mobilenet_v1_270e_voc.yml。4、label_list.txt照片分类的种类。 PaddleDetectionPaddleDetection 源码 PaddleDetectionPaddleDetection 源码 PaddleDetectionPaddleDetection 源码 如何利用PaddleDetection一个完整项目(一) 0PaddleDetection简介 PaddleDetectionPaddlePaddle推出的物体检测统一框架。支持现有的RCNN、SSD、YOLO等系列模型、支持 ResNet、ResNet-VD、ResNeXt、ResNeXt-VD、SENet、MobileNet、DarkNet等主干网络。针对不同的业务场景(性能、目标大小... 一、PaddleDetection的安装 前言:PaddleDetection依赖paddlepaddle,需要先安装paddlepaddle 1.从github/gitee获取PaddleDetection完整资源 github git clone https://github.com/PaddlePaddle/PaddleDetection.git gitee git clone https://gitee.com/paddlepaddle/PaddleDetection 2.安装相关依赖 infer.py —— 模型预测 python tools/infer.py -c configs/faster_rcnn_r50_1x.yml --infer_img=demo/000000570688.jpg 2 运行分析 2.1 图像预测 我们可以使用如下的命令来预测图像中的物体目标 # 用PP-YOLO算法在COCO数据集上预训练模型预测一张图片 pytho 对于训练调优场景,使用paddle.save/load保存和载入模型。 对于推理部署场景,使用paddle.jit.save/load(动态图)和paddle.static.save/load_inference_model(静态图)保存载入模型。 1.2高级API paddle.Model.fit (训练接口,同时带有参数保存的功能) paddle.Model.save paddle.Model.load 2.训练调优场景的模型&a paddleDetection预训练模型导出,并且给paddex使用序言下载paddleDetection权重文件导出模型修改model.yml 最近准备用paddlex部署项目,但是踩了几天的坑发现paddleDetection中的模型并不能直接导出给paddlex使用,关键是paddleDetection使用python tools/export_model.py导出的配置文件是infer_cfg.yml,里面的内容与paddlex可以使用的model.yml有些区别,一种方法是找合适一个数据集,