YOLOv3+ResNet车辆逆行违章检测
Sharpiless 发布于2020-05-06 17:50 浏览:526 回复:1
0
收藏

基于Paddle的车辆逆行违章检测
作者:梁瑛平

QQ:1691608003

博客地址:https://blog.csdn.net/weixin_44936889

项目地址:https://aistudio.baidu.com/aistudio/projectdetail/453620

(有问题欢迎讨论~)

简介:
该项目使用Paddle框架开发,在 AI Studio 平台运行,

属于整体项目的一个功能模块(逆行违章检测模块)。

该模型使用YOLOv3算法进行车辆的检测;

使用ResNet18进行车辆状态识别(包括朝向,颜色和类型);

该项目使用了PaddleDetection工具和X2Paddle工具进行开发。

其中:

1. PaddleDetection 提供了很好的应用接口和预训练模型,实现了快速的车辆检测;

2. X2Paddle 则解决了不同深度学习框架的模型权重文件转换的问题;

3. AI Studio提供了模型训练和测试的平台,并无需我们自己配置环境,提高了开发效率;

最终效果如图:

绪论:
对于目前绝大多数的交通监控而言,依旧是沿用传统的管理模式。

对着国民经济的日益发展和交通产业的需求日益增长,智能交通视觉系统的发展将趋向用机器视觉下的图像处理技术进行实时监测。

基于深度学习的计算机视觉技术的发展,使得智能监控的精度不断提升。

一些模型的性能已经能够达到应用水平。

并且近年来提出的许多压缩模型和优化模型的方法,使得模型参数和计算量进一步下降。

从而使得深度学习模型能够在智能监控、嵌入式设备等计算资源受限的平台使用。

PaddleDetection 简介:
源码地址:https://github.com/PaddlePaddle/PaddleDetection

官方文档:https://paddledetection.readthedocs.io/

PaddleDetection 创立的目的是为工业界和学术界提供丰富、易用的目标检测模型。不仅性能优越、易于部署,而且能够灵活的满足算法研究的需求。

简而言之就是,该工具使用百度开源的 Paddle 框架,集成了多种图像识别和目标检测框架,并且提供了相应的训练、推理和部署工具,使得用户可以自己 DIY 数据集和模型细节,实现深度学习落地应用的快速部署。 特点:

· 易部署:PaddleDetection的模型中使用的核心算子均通过C++或CUDA实现,同时基于PaddlePaddle的高性能推理引擎可以方便地部署在多种硬件平台上。

· 高灵活度:PaddleDetection通过模块化设计来解耦各个组件,基于配置文件可以轻松地搭建各种检测模型。

· 高性能:基于PaddlePaddle框架的高性能内核,在模型训练速度、显存占用上有一定的优势。例如,YOLOv3的训练速度快于其他框架,在Tesla V100 16GB环境下,Mask-RCNN(ResNet50)可以单卡Batch Size可以达到4 (甚至到5)。

支持的主流模型包括:

并且支持多种拓展特性:

使得开发者只需修改相应的 yml 格式参数文件,即可一键 DIY 并训练自己的模型:

ResNet简介:
2.1 论文地址:
《Deep Residual Learning for Image Recognition》

2.2 核心思想:
将本来回归的目标函数H(x)转化为F(x)+x,即F(x) = H(x) - x,称之为残差。

2.3 网络结构:
2.3.1 残差单元:
ResNet的基本的残差单元如图所示:

基本结构如图,假设每个单元输入的特征层为x,经过两个卷积层获得输出y,将x与y求和即得到了这个单元的输出;

在训练时,我们将该单元目标映射(即要趋近的最优解)假设为F(x) + x,而输出为y+x,那么训练的目标就变成了使y趋近于F(x)。即去掉映射前后相同的主体部分x,从而突出微小的变化(残差)。

用数学表达式表示为:

其中:

1. x是残差单元的输入;

2. y是残差单元的输出;

3. F(x)是目标映射;

4. {Wi}是残差单元中的卷积层;

5. Ws是一个1x1卷积核大小的卷积,作用是给x降维或升维,从而与输出y大小一致(因为需要求和);

 

YOLOv3简介:
(一)论文地址:
https://arxiv.org/abs/1804.02767

(二)核心思想:
‘Sometimes you just kinda phone it in for a year, you know?’

作者说他一年大部分时间去刷 Twitter 了,然后玩了(play around)一阵子 GAN,正好剩下一点时间,就改进了一下 YOLO 算法,提出了 YOLO v3;

(作者有点皮呀)

 

(三)DarkNet-53:
作者在 DarkNet-19 的基础上加入了残差结构,使得它在 ImageNet 上的表现跟 ResNet-101 相差无几,但是处理速度却快得多;

 

(四)Class Prediction:
这里由于 YOLO 使用了多层 label,因此使用了 Logistic 回归和 binary cross-entropy 损失函数;

(五)Predictions Across Scales:
这里每个区域使用了 3 个不同大小的 Anchor,其余设置跟 YOLO v2 相同;

并且作者使用了跟 FPN 相似的特征金字塔进行预测,共选出了 3 个特征层去针对不同大小的物体,这三个特征层大小分别为:13,26,52;

(六)实验结果:
(非常快)

 

添加工作环境路径
这一步导入os、sys库

设置工作环境为:'/home/aistudio/work'

并添加扫描路径:'/home/aistudio/external-libraries'

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可:# Also add the following code, so that every time the environment (kernel) starts, just run the following code:import osimport sys

 

os.chdir('/home/aistudio/work')

sys.path.append('/home/aistudio/external-libraries')

解压权重文件:
这一步使用命令行命令解压权重文件:

# !unzip /home/aistudio/data/data33477/clsmodel.zip -d /home/aistudio/work# !unzip /home/aistudio/data/data33477/darknet.zip -d /home/aistudio/work

导入需要的包
import cv2from paddle_model_cls.model_with_code.model import x2paddle_net

import argparseimport functoolsimport numpy as npimport paddle.fluid as fluidimport matplotlib.pyplot as plt

定义图像预处理函数:
这里主要是将图像进行标准化

然后将图像放缩到224×224大小

def process_img(img, image_shape=[3, 224, 224]):

 

    mean = [0.485, 0.456, 0.406]

    std = [0.229, 0.224, 0.225]

 

    img = cv2.resize(img, (image_shape[1], image_shape[2]))

    #img = cv2.resize(img,(256,256))

    #img = crop_image(img, image_shape[1], True)

 

    # RBG img [224,224,3]->[3,224,224]

    img = img[:, :, ::-1].astype('float32').transpose((2, 0, 1)) / 255

    #img = img.astype('float32').transpose((2, 0, 1)) / 255

    img_mean = np.array(mean).reshape((3, 1, 1))

    img_std = np.array(std).reshape((3, 1, 1))

    img -= img_mean

    img /= img_std

 

    img = img.astype('float32')

    img = np.expand_dims(img, axis=0)

 

    return img

定义预测函数:
功能是将one hot表示的标签转换为颜色、朝向、类别的索引

def get_predict(output):

    output = np.squeeze(output)

    pred_color = output[:9]

    pred_direction = output[9:11]

    pred_type = output[11:]

 

    color_idx = np.argmax(pred_color)

    direction_idx = np.argmax(pred_direction)

    type_idx = np.argmax(pred_type)

 

    return color_idx, direction_idx, type_idx

定义分类器:
这里定义了分类器的一个类,用于获取图像输入,并输出预测;

注意CPU环境中use_gpu需要改成False

use_gpu = Falseclass CarClassifier(object):

 

    def __init__(self):

 

        self.color_attrs = ['Black', 'Blue', 'Brown',

                            'Gray', 'Green', 'Pink',

                            'Red', 'White', 'Yellow']  # 车体颜色

 

        self.direction_attrs = ['Front', 'Rear']  # 拍摄位置

 

        self.type_attrs = ['passengerCar', 'saloonCar',

                           'shopTruck', 'suv', 'trailer', 'truck', 'van', 'waggon']  # 车辆类型

 

        self.init_params()

 

    def inference(self, img):

        fetch_list = [self.out.name]

 

        output = self.exe.run(self.eval_program,

                              fetch_list=fetch_list,

                              feed={'image': img})

        color_idx, direction_idx, type_idx = get_predict(np.array(output))

 

        color_name = self.color_attrs[color_idx]

        direction_name = self.direction_attrs[direction_idx]

        type_name = self.type_attrs[type_idx]

 

        return color_name, direction_name, type_name

 

    def init_params(self):

 

        # Attack graph

        adv_program = fluid.Program()

 

        # 完成初始化

        with fluid.program_guard(adv_program):

            input_layer = fluid.layers.data(

                name='image', shape=[3, 224, 224], dtype='float32')

            # 设置为可以计算梯度

            input_layer.stop_gradient = False

 

            # model definition

            _, out_logits = x2paddle_net(inputs=input_layer)

            self.out = fluid.layers.softmax(out_logits[0])

 

            place = fluid.CUDAPlace(0) if use_gpu else fluid.CPUPlace()

            self.exe = fluid.Executor(place)

            self.exe.run(fluid.default_startup_program())

 

            # 记载模型参数

            fluid.io.load_persistables(

                self.exe, './paddle_model_cls/model_with_code/')

 

        # 创建测试用评估模式

        self.eval_program = adv_program.clone(for_test=True)

 

    def predict(self, im):

 

        im_input = process_img(im)

 

        color_name, direction_name, type_name = self.inference(im_input)

 

        label = '颜色:{}\n朝向:{}\n类型:{}'.format(

            color_name, direction_name, type_name)

 

        return label

定义并测试分类器
结果如图:

%matplotlib inline

classifier = CarClassifier()im = cv2.imread('a.png')result = classifier.predict(im)

 

print(result)

plt.imshow(im[:, :, [2, 1, 0]])

plt.show()

颜色:Yellow

朝向:Front

类型:suv

导入其他包
主要是一些绘图工具(PIL)和PaddleDetection工具(ppdet)

import ppdet.utils.checkpoint as checkpointfrom ppdet.utils.cli import ArgsParserfrom ppdet.utils.eval_utils import parse_fetchesfrom ppdet.core.workspace import load_config, createfrom paddle import fluidimport osimport cv2import glob

from ppdet.utils.coco_eval import bbox2out, mask2out, get_category_info

import numpy as npfrom PIL import Imagefrom PIL import ImageFont, ImageDraw

定义绘图函数
使用PIL库解决opencv不支持中文的问题

 

font_path = r'./simsun.ttc' # 新宋体

font = ImageFont.truetype(font_path, 16)

 

def putText(img, text, x, y, color=(0, 0, 255)):

 

    img_pil = Image.fromarray(img)

    draw = ImageDraw.Draw(img_pil)

    b, g, r = color

    a = 0

    draw.text((x, y), text, font=font, fill=(b, g, r, a))

    img = np.array(img_pil)

    return img

定义目标检测类
class VehicleDetector(object):

 

    def __init__(self):

 

        self.size = 608

 

        self.draw_threshold = 0.1

 

        self.cfg = load_config('./configs/vehicle_yolov3_darknet.yml')

 

        self.place = fluid.CUDAPlace(

            0) if use_gpu else fluid.CPUPlace()

        # self.place = fluid.CPUPlace()

        self.exe = fluid.Executor(self.place)

 

        self.model = create(self.cfg.architecture)

 

        self.classifier = classifier

 

        self.init_params()

 

    def draw_bbox(self, image, catid2name, bboxes, threshold):

 

        raw = image.copy()

 

        for dt in np.array(bboxes):

 

            catid, bbox, score = dt['category_id'], dt['bbox'], dt['score']

            if score < threshold or catid == 6:

            # if score < threshold:

                continue

 

            xmin, ymin, w, h = bbox

            xmin = int(xmin)

            ymin = int(ymin)

            xmax = int(xmin + w)

            ymax = int(ymin + h)

            roi = raw[ymin:ymax, xmin:xmax].copy()

            label = self.classifier.predict(roi)

 

            cv2.rectangle(image, (xmin, ymin), (xmax, ymax), (255, 0, 0), 4)

            image = putText(image, label, 0, 10, color=(255, 0, 0))

            print(label)

            print()

 

        return image

 

    def init_params(self):

 

        startup_prog = fluid.Program()

        infer_prog = fluid.Program()

        with fluid.program_guard(infer_prog, startup_prog):

            with fluid.unique_name.guard():

                inputs_def = self.cfg['TestReader']['inputs_def']

                inputs_def['iterable'] = True

                feed_vars, loader = self.model.build_inputs(**inputs_def)

                test_fetches = self.model.test(feed_vars)

        infer_prog = infer_prog.clone(True)

 

        self.exe.run(startup_prog)

        if self.cfg.weights:

            checkpoint.load_params(self.exe, infer_prog, self.cfg.weights)

 

        extra_keys = ['im_info', 'im_id', 'im_shape']

        self.keys, self.values, _ = parse_fetches(

            test_fetches, infer_prog, extra_keys)

        dataset = self.cfg.TestReader['dataset']

        anno_file = dataset.get_anno()

        with_background = dataset.with_background

        use_default_label = dataset.use_default_label

 

        self.clsid2catid, self.catid2name = get_category_info(anno_file, with_background,

                                                              use_default_label)

 

        is_bbox_normalized = False

        if hasattr(self.model, 'is_bbox_normalized') and \

                callable(self.model.is_bbox_normalized):

            is_bbox_normalized = self.model.is_bbox_normalized()

 

        self.is_bbox_normalized = is_bbox_normalized

 

        self.infer_prog = infer_prog

 

    def process_img(self, img):

 

        mean = [0.485, 0.456, 0.406]

        std = [0.229, 0.224, 0.225]

        shape = img.shape[:2]

 

        img = cv2.resize(img, (self.size, self.size))

 

        # RBG img [224,224,3]->[3,224,224]

        img = img[:, :, ::-1].astype('float32').transpose((2, 0, 1)) / 255

        img_mean = np.array(mean).reshape((3, 1, 1))

        img_std = np.array(std).reshape((3, 1, 1))

        img -= img_mean

        img /= img_std

 

        img = img.astype('float32')

        img = np.expand_dims(img, axis=0)

 

        shape = np.expand_dims(np.array(shape), axis=0)

        im_id = np.zeros((1, 1), dtype=np.int64)

 

        return img, im_id, shape

 

    def detect(self, img):

 

        # img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

        raw = img.copy()

        img, im_id, shape = self.process_img(img=img)

        outs = self.exe.run(self.infer_prog,

                            feed={'image': img, 'im_size': shape.astype(np.int32), 'im_id': im_id},

                            fetch_list=self.values,

                            return_numpy=False)

        res = {

            k: (np.array(v), v.recursive_sequence_lengths())

            for k, v in zip(self.keys, outs)

        }

 

        bbox_results = bbox2out(

            [res], self.clsid2catid, self.is_bbox_normalized)

 

        result = self.draw_bbox(raw, self.catid2name,

                                bbox_results, self.draw_threshold)

 

        return result

测试检测+识别
效果如图:

det = VehicleDetector()

 

im = cv2.imread('./car.jpg')

result = det.detect(im)

 

plt.imshow(result[:, :, [2,1,0]])

plt.show()

 

cv2.imwrite('./result.png', result)

2020-05-06 16:41:19,803-INFO: Loading parameters from ./vehicle_yolov3_darknet...

2020-05-06 16:41:19,804-WARNING: ./vehicle_yolov3_darknet.pdparams not found, try to load model file saved with [ save_params, save_persistables, save_vars ]2020-05-06 16:41:19,804-WARNING: ./vehicle_yolov3_darknet.pdparams not found, try to load model file saved with [ save_params, save_persistables, save_vars ]2020-05-06 16:41:20,397-INFO: Not found annotation file contrib/VehicleDetection/vehicle.json, load coco17 categories.

 

 

颜色:Yellow

朝向:Front

类型:passengerCar

 

 

 

 

 

 

 

True

进行车辆逆行检测:
进行逆行检测只需要规定好正确朝向

对于非正确朝向的车辆,我们标注为违规。

正常车辆为绿色,违规车辆标注为红色

right_direct = 'Rear'

class new_Det(VehicleDetector):

 

    def __init__(self):

 

        self.size = 608

 

        self.draw_threshold = 0.1

 

        self.cfg = load_config('./configs/vehicle_yolov3_darknet.yml')

 

        self.place = fluid.CUDAPlace(

            0) if use_gpu else fluid.CPUPlace()

        # self.place = fluid.CPUPlace()

        self.exe = fluid.Executor(self.place)

 

        self.model = create(self.cfg.architecture)

 

        self.classifier = classifier

 

        self.init_params()

 

 

    def init_params(self):

 

        startup_prog = fluid.Program()

        infer_prog = fluid.Program()

        with fluid.program_guard(infer_prog, startup_prog):

            with fluid.unique_name.guard():

                inputs_def = self.cfg['TestReader']['inputs_def']

                inputs_def['iterable'] = True

                feed_vars, loader = self.model.build_inputs(**inputs_def)

                test_fetches = self.model.test(feed_vars)

        infer_prog = infer_prog.clone(True)

 

        self.exe.run(startup_prog)

        if self.cfg.weights:

            checkpoint.load_params(self.exe, infer_prog, self.cfg.weights)

 

        extra_keys = ['im_info', 'im_id', 'im_shape']

        self.keys, self.values, _ = parse_fetches(

            test_fetches, infer_prog, extra_keys)

        dataset = self.cfg.TestReader['dataset']

        anno_file = dataset.get_anno()

        with_background = dataset.with_background

        use_default_label = dataset.use_default_label

 

        self.clsid2catid, self.catid2name = get_category_info(anno_file, with_background,

                                                              use_default_label)

 

        is_bbox_normalized = False

        if hasattr(self.model, 'is_bbox_normalized') and \

                callable(self.model.is_bbox_normalized):

            is_bbox_normalized = self.model.is_bbox_normalized()

 

        self.is_bbox_normalized = is_bbox_normalized

 

        self.infer_prog = infer_prog

 

    def process_img(self, img):

 

        mean = [0.485, 0.456, 0.406]

        std = [0.229, 0.224, 0.225]

        shape = img.shape[:2]

 

        img = cv2.resize(img, (self.size, self.size))

 

        # RBG img [224,224,3]->[3,224,224]

        img = img[:, :, ::-1].astype('float32').transpose((2, 0, 1)) / 255

        img_mean = np.array(mean).reshape((3, 1, 1))

        img_std = np.array(std).reshape((3, 1, 1))

        img -= img_mean

        img /= img_std

 

        img = img.astype('float32')

        img = np.expand_dims(img, axis=0)

 

        shape = np.expand_dims(np.array(shape), axis=0)

        im_id = np.zeros((1, 1), dtype=np.int64)

 

        return img, im_id, shape

 

    def detect(self, img):

 

        # img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

        raw = img.copy()

        img, im_id, shape = self.process_img(img=img)

        outs = self.exe.run(self.infer_prog,

                            feed={'image': img, 'im_size': shape.astype(np.int32), 'im_id': im_id},

                            fetch_list=self.values,

                            return_numpy=False)

        res = {

            k: (np.array(v), v.recursive_sequence_lengths())

            for k, v in zip(self.keys, outs)

        }

 

        bbox_results = bbox2out(

            [res], self.clsid2catid, self.is_bbox_normalized)

 

        result = self.draw_bbox(raw, self.catid2name,

                                bbox_results, self.draw_threshold)

 

        return result

    def draw_bbox(self, image, catid2name, bboxes, threshold):

 

        raw = image.copy()

 

        for dt in np.array(bboxes):

 

            catid, bbox, score = dt['category_id'], dt['bbox'], dt['score']

            if score < threshold or catid == 6:

                # if score < threshold:

                continue

 

            xmin, ymin, w, h = bbox

            xmin = int(xmin)

            ymin = int(ymin)

            xmax = int(xmin + w)

            ymax = int(ymin + h)

            roi = raw[ymin:ymax, xmin:xmax].copy()

            label = self.classifier.predict(roi)

            if right_direct in label:

                color = (0, 255, 0)

            else:

                color = (0, 0, 255)

                print('检测到违章逆行!')

 

            cv2.rectangle(image, (xmin, ymin), (xmax, ymax), color, 4)

            print(label)

            print()

 

        return image

det = new_Det()

2020-05-06 16:42:29,823-INFO: Loading parameters from ./vehicle_yolov3_darknet...

2020-05-06 16:42:29,825-WARNING: ./vehicle_yolov3_darknet.pdparams not found, try to load model file saved with [ save_params, save_persistables, save_vars ]2020-05-06 16:42:29,825-WARNING: ./vehicle_yolov3_darknet.pdparams not found, try to load model file saved with [ save_params, save_persistables, save_vars ]2020-05-06 16:42:30,284-INFO: Not found annotation file contrib/VehicleDetection/vehicle.json, load coco17 categories.

最终效果:

 

im = cv2.imread('./demo.png')

result = det.detect(im)

 

plt.imshow(result[:, :, [2, 1, 0]])

 

plt.show()

检测到违章逆行!

颜色:Black

朝向:Front

类型:saloonCar

 

使用 X2Paddle 进行模型转换:
(下面只是演示一下如何使用X2Paddle进行模型转换,感兴趣的同学可以试一下)

看到这里有同学要问了,这个类型识别是如何实现的?

这里我们使用的是 torch 的开源车辆类型识别模型,并使用 X2Paddle 工具将其转换为 Paddle 模型;

X2Paddle 源码地址:https://github.com/PaddlePaddle/X2Paddle

深度学习的应用主要包括两个部分,一是通过深度学习框架训练出模型,二是利用训练出来的模型进行预测。

开发者基于不同的深度学习框架能够得到不同的训练模型,如果想要基于一种框架进行预测,就必须要解决不同框架的模型之间的匹配问题。基于这种考虑,也为了帮助用户快速从其他框架迁移,PaddlePaddle开源了模型转换工具X2Paddle。

它可以将TensorFlow、Caffe 的模型转换为PaddlePaddle的核心框架Paddle Fluid可加载的格式。同时X2Paddle还支持ONNX格式的模型转换,这样也相当于支持了众多可以转换为ONNX格式的框架,比如PyTorch、MXNet、CNTK等。

下载 torch 源码:

源码地址:https://github.com/Sharpiless/Paddle-Car-type-recognition

 

点⭐然后下载解压:

 

下载权重文件,放到 src 文件夹下面:

链接:https://pan.baidu.com/s/1fBwOr9PM9S7LmCgRddX0Gg

提取码:pv6e

 

首先运行 torch2onnx.py,将 pth 模型转换为 onnx 中间模型: 然后运行:

x2paddle --framework=onnx --model=classifier.onnx --save_dir=pd_model

 

可以看到生成了相应的 Paddle 模型;

此时将 model.py 中的:

def x2paddle_net():

替换为:

def x2paddle_net(inputs):

将:

x2paddle_input_1 = fluid.layers.data(dtype='float32', shape=[1, 3, 224, 224], name='x2paddle_input_1', append_batch_size=False)

替换为:

x2paddle_input_1 = inputs

然后创建调用 Paddle 模型的 test_img.py:

import cv2from pd_model.model_with_code.model import x2paddle_net

import argparseimport functoolsimport numpy as npimport paddle.fluid as fluidfrom PIL import ImageFont, ImageDraw, Image

 

font_path = r'./simsun.ttc'

font = ImageFont.truetype(font_path, 32)

 

def putText(img, text, x, y, color=(0, 0, 255)):

 

    img_pil = Image.fromarray(img)

    draw = ImageDraw.Draw(img_pil)

    b, g, r = color

    a = 0

    draw.text((x, y), text, font=font, fill=(b, g, r, a))

    img = np.array(img_pil)

    return img

 

# 定义一个预处理图像的函数def process_img(img_path='', image_shape=[3, 224, 224]):

 

    mean = [0.485, 0.456, 0.406]

    std = [0.229, 0.224, 0.225]

 

    img = cv2.imread(img_path)

    img = cv2.resize(img, (image_shape[1], image_shape[2]))

    #img = cv2.resize(img,(256,256))

    #img = crop_image(img, image_shape[1], True)

 

    # RBG img [224,224,3]->[3,224,224]

    img = img[:, :, ::-1].astype('float32').transpose((2, 0, 1)) / 255

    #img = img.astype('float32').transpose((2, 0, 1)) / 255

    img_mean = np.array(mean).reshape((3, 1, 1))

    img_std = np.array(std).reshape((3, 1, 1))

    img -= img_mean

    img /= img_std

 

    img = img.astype('float32')

    img = np.expand_dims(img, axis=0)

 

    return img

# 模型推理函数

 

 

color_attrs = ['Black', 'Blue', 'Brown',

               'Gray', 'Green', 'Pink',

               'Red', 'White', 'Yellow']  # 车体颜色

 

direction_attrs = ['Front', 'Rear']  # 拍摄位置

 

type_attrs = ['passengerCar', 'saloonCar',

              'shopTruck', 'suv', 'trailer', 'truck', 'van', 'waggon']  # 车辆类型

 

def inference(img):

    fetch_list = [out.name]

 

    output = exe.run(eval_program,

                     fetch_list=fetch_list,

                     feed={'image': img})

    color_idx, direction_idx, type_idx = get_predict(np.array(output))

 

    color_name = color_attrs[color_idx]

    direction_name = direction_attrs[direction_idx]

    type_name = type_attrs[type_idx]

 

    return color_name, direction_name, type_name

 

def get_predict(output):

    output = np.squeeze(output)

    pred_color = output[:9]

    pred_direction = output[9:11]

    pred_type = output[11:]

 

    color_idx = np.argmax(pred_color)

    direction_idx = np.argmax(pred_direction)

    type_idx = np.argmax(pred_type)

 

    return color_idx, direction_idx, type_idx

 

 

use_gpu = True# Attack graph

adv_program = fluid.Program()

# 完成初始化with fluid.program_guard(adv_program):

    input_layer = fluid.layers.data(

        name='image', shape=[3, 224, 224], dtype='float32')

    # 设置为可以计算梯度

    input_layer.stop_gradient = False

 

    # model definition

    _, out_logits = x2paddle_net(inputs=input_layer)

    out = fluid.layers.softmax(out_logits[0])

 

    place = fluid.CUDAPlace(0) if use_gpu else fluid.CPUPlace()

    exe = fluid.Executor(place)

    exe.run(fluid.default_startup_program())

 

    # 记载模型参数

    fluid.io.load_persistables(exe, './pd_model/model_with_code/')

# 创建测试用评估模式

eval_program = adv_program.clone(for_test=True)

# im_pt = './a.jpg'

im_pt = './a.png'

img = process_img(im_pt)

 

color_name, direction_name, type_name = inference(img)

 

label = '颜色:{}\n朝向:{}\n类型:{}'.format(color_name, direction_name, type_name)

 

img = cv2.imread(im_pt)

img = putText(img, label, x=1, y=10, color=(0, 215, 255))

 

cv2.imshow('a', img)

cv2.waitKey(0)

 

cv2.destroyAllWindows()

运行测试:

成功~

总结:
在本篇文章中,我们使用了 PaddleDetection 和 X2Paddle 两个工具,在AI Studio平台上实现了一个图片、视频中车辆检测和类型识别的小项目。

其中:

1. PaddleDetection 提供了很好的应用接口和预训练模型,实现了快速的车辆检测;

2. X2Paddle 则解决了不同深度学习框架的模型权重文件转换的问题;

3. AI Studio提供了模型训练和测试的平台,并无需我们自己配置环境,提高了开发效率;

 

收藏
点赞
0
个赞
共1条回复 最后由鹿鼎记肯定回复于2020-05-06 18:19
#2鹿鼎记肯定回复于2020-05-06 18:19:44

酷~

1
TOP
切换版块