PPVehicle车辆属性的识别服务

PPVehicle车辆属性的识别服务

一.功能说明

  • 实现web服务,在页面上导入图片,输出车位置、颜色和车型
  • 绘制在图片上,并显示
  • 支持API接口
  • 当前提供的预训练模型支持识别10种车辆颜色及9种车型,同VeRi数据集,具体如下:
# 车辆颜色
- "yellow"
- "orange"
- "green"
- "gray"
- "red"
- "blue"
- "white"
- "golden"
- "brown"
- "black"

# 车型
- "sedan"
- "suv"
- "van"
- "hatchback"
- "mpv"
- "pickup"
- "bus"
- "truck"
- "estate"

二.开发环境搭建

1.搭建conda环境

1.1.下载conda安装包

  wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-2021.11-Linux-x86_64.sh

1.2.执行安装

  bash Anaconda3-2021.11-Linux-x86_64.sh

期间Enter直接回车,yes|no选择yes

1.3.安装后添加环境变量

  vim ~/.bashrc

文件最后追加下面内容

  export  PATH="/home/test/anaconda3/bin:$PATH"

加载环境变量

  source ~/.bashrc

1.4.查看安装结果

  conda --version

如果有版本输出则安装成功

2.搭建项目运行环境

2.1.创建虚拟运行环境

  conda create -n pp python=3.7

这里选择工程的python运行版本为3.7

2.2.切换到虚拟运行环境

  conda activate pp

2.3.安装python依赖module

依赖module列表
cat >> requestsments.txt << EOF

numpy==1.21.6

tqdm
typeguard
visualdl>=2.2.0
opencv-python <= 4.6.0
PyYAML
shapely
scipy
terminaltables
Cython
pycocotools
setuptools

# for vehicleplate
pyclipper

# for mot
lap
motmetrics
sklearn==0.0
filterpy

# flask
Flask>=2.1.0

paddlepaddle==2.4.1

EOF

2.4.执行安装命令

conda install lap
pip install -r requirements.txt  -i https://pypi.douban.com/simple

在安装requirements.txt是会有异常产生,需要依赖lap

三.运行测试code

1.下载工程

git clone https://github.com/PaddlePaddle/PaddleDetection.git

2.测试demo

cd PaddleDetection
# 预测单张图片文件
python deploy/pipeline/pipeline.py --config deploy/pipeline/config/infer_cfg_ppvehicle.yml \
--image_file=test_image.jpg \
--device=gpu

image_file:指定测试文件

四.配置项说明

1.配置文件

配置文件路径
deploy/pipeline/config/infer_cfg_ppvehicle.yml

配置文件中与属性相关的参数如下:

VEHICLE_ATTR:
  model_dir: output_inference/vehicle_attribute_infer/ # 车辆属性模型调用路径
  batch_size: 8     # 模型预测时的batch_size大小
  color_threshold: 0.5  # 颜色属性阈值,需要置信度达到此阈值才会确定具体颜色,否则为'Unknown‘
  type_threshold: 0.5   # 车型属性阈值,需要置信度达到此阈值才会确定具体属性,否则为'Unknown‘
  enable: False         # 是否开启该功能

2.修改模型路径,有以下两种方式:

  • 方法一:./deploy/pipeline/config/infer_cfg_ppvehicle.yml下可以配置不同模型路径,属性识别模型修改VEHICLE_ATTR字段下配置
  • 方法二:直接在命令行中增加-o,以覆盖配置文件中的默认模型路径:
python deploy/pipeline/pipeline.py --config deploy/pipeline/config/infer_cfg_ppvehicle.yml \
                                                   --video_file=test_video.mp4 \
                                                   --device=gpu \
                                                   -o VEHICLE_ATTR.model_dir=output_inference/vehicle_attribute_infer

五.封装接口

1.调用工程模块,切换运行环境

import os
import sys
#运行环境切换到调用工程目录
PRO_PATH = os.path.join(os.path.abspath(os.path.dirname(__file__)),"PaddleDetection")
ENV_PATH = os.path.join(PRO_PATH,"deploy/pipeline")
sys.path.append(ENV_PATH)
from PaddleDetection.deploy.pipeline.pipeline import argsparser,merge_cfg,print_arguments,Pipeline

2.初始化模型

def init_ppvehicle():
    """初始化车辆属性识别

    Returns:
        _type_: 车辆属性识别对象
    """
    paddle.enable_static()

    # parse params from command
    parser = argsparser()
    # python deploy/pipeline/pipeline.py --config deploy/pipeline/config/infer_cfg_ppvehicle.yml --image_file=./deploy/pipeline/docs/images/ppvehicleplate.jpg --device=gpu
    # 输入初始化参数
    FLAGS = parser.parse_args([
                            #测试结果输出到指定目录
                            '--output_dir','./out',
                            #配置文件路径
                            '--config',os.path.join(PRO_PATH,'deploy/pipeline/config/infer_cfg_ppvehicle.yml'),  
                            # 测试图片路径
                            '--image_file',os.path.join(PRO_PATH,'deploy/pipeline/docs/images/ppvehicleplate.jpg'),  
                            #设置运行gpu:0
                            '--device','0' 
                            ])
    FLAGS.device = FLAGS.device.upper()
    cfg = merge_cfg(FLAGS)  # use command params to update config
    print_arguments(cfg)
    pipeline = Pipeline(FLAGS, cfg)
    return pipeline

3.执行检测识别

def exec_ppvehicle(pipeline,input = None,output = None):
    """车辆属性识别

    Args:
        pipeline (_type_): 车辆属性识别对象
        input (_type_, optional): 输入路径. Defaults to None.
        output (_type_, optional): 输出目录. Defaults to None.

    Returns:
        _type_: _description_
    """
    if input:
        #输入路径['']
        pipeline.input = input
    if output:
        #修改测试结果输出目录
        pipeline.predictor.output_dir = output
    # 执行车辆检测识别
    pipeline.run()
    #返回结果
    return pipeline.predictor.pipeline_res.res_dict

4.检测结果解析

def result_ppvehicle(out_path,res_dict,isprit=False):
    """车辆属性识别返回结果解析

    Args:
        out_path (_type_): 输出图片路径
        res_dict (_type_): 识别结果,返回结构化结果
        isprit (bool, optional): 特殊格式. Defaults to False.

    Returns:
        _type_: _description_
    """
    out_dict = {}
    logging.warning(out_path)
    if os.path.exists(out_path):
        with open(out_path,"rb") as f:
            img = str(base64.b64encode(f.read()),'utf-8')
    boxes = res_dict["det"]["boxes"]
    vehicle_attrs = res_dict["vehicle_attr"]["output"]
    
    rec_res = []
    num = 0
    for box,attrs in zip(boxes,vehicle_attrs):
        score = box[1]
        x1,y1,x2,y2 = box[2:]
        if isprit:
            rec_res.append([num,",".join(attrs),float(f'{score:.3f}')])
        else:
            atrr_dict = dict(attr.split(":") for attr in attrs)
            atrr_dict["score"] = float(f'{score:.3f}')
            atrr_dict["box"]={
                "x1":float(f'{x1:.3f}'),
                "y1":float(f'{y1:.3f}'),
                "x2":float(f'{x2:.3f}'),
                "y2":float(f'{y2:.3f}'),
                }
            rec_res.append(atrr_dict)
        num = num + 1
    out_dict["dets"] = rec_res
    logging.warning(out_dict)
    out_dict["image"] = img
    return out_dict

六.开发Api,并Postman测试

1.Flask运行接口搭建

# -*- encoding: utf-8 -*-
# @Author: fy
# @Contact: [email protected]
import os
import base64
import json
import time
import logging
from wsgiref.simple_server import make_server

import cv2
import numpy as np
from flask import Flask, render_template, request


from tools import CfgUtil as cfg
from tools.Logger import Logger

from Vehicle import init_ppvehicle,exec_ppvehicle,result_ppvehicle


app = Flask(__name__)
# 调整接收文本大小
app.config['MAX_CONTENT_LENGTH'] = 30 * 1024 * 1024



@app.route('/')
def index():
    return render_template('index.html')

@app.route('/api/v1/vehicle/detect', methods=['POST'])
def ocr_idcard():
    if request.method == 'POST':
        try:
            #接收检测图片
            json_obj = request.get_json()
            logging.warning(json_obj)
            img_str = json_obj["image"]

            image = base64.b64decode(img_str + '=' * (-len(img_str) % 4))
            nparr = np.frombuffer(image, np.uint8)
        except Exception as e:
            logging.error(e)
            return json.dumps({"code": -1001,"msg": u"Incomplete parameters","data": {}})
        try:
            image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
            
            if image.ndim == 2:
                image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
            
            
        except Exception as e:
            logging.error(e)
            return json.dumps({"code": -1101,"msg": u"Detection failed","data": {}})
        image = None
        out_dict = {}
        try:
            t1 = time.time()
            # 3.执行检测识别
           
            
            # 4.检测结果解析,格式化输出结果
            
        except Exception as e:
            logging.error(e)
            return json.dumps({"code": -1102,"msg": u"Parsing failed","data": {}})
        logging.warning(f'out_dict:{out_dict}')
        return json.dumps({"code": 1000,"msg": "success","data": out_dict})
if __name__ == '__main__':
    # 1.初始化模型,创建车辆属性识别对象
    
    
    # 2.对象第一次执行,可能存在第一次耗时较长的问题
    
    ip = '0.0.0.0'
    ip_port = 9999
    logging.warning(f"http://{ip}:{ip_port}")
    server = make_server(ip, ip_port, app)
    server.serve_forever()

2.调用识别封装接口

  1. 初始化模型,创建车辆属性识别对象
  2. 对象第一次执行,可能存在第一次耗时较长的问题
  3. 执行检测识别
  4. 检测结果解析,格式化输出结果

七.web支持,前后端测试

八.测试结果

测试结果预览
PPVehicle车辆属性的识别服务_第1张图片

你可能感兴趣的:(人工智能,python,开发语言)