欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【百度大脑新品体验】车牌识别

程序员文章站 2022-07-12 20:40:31
...

车牌识别现在已经有了许多应用,例如停车场闸机识别,高速公路收费站车牌识别等。在本文中,将介绍如何使用百度AI的接口来实现车牌识别。

车牌识别接口介绍

本段将简单介绍一下车牌识别接口,具体的内容可以参见 文档( https://ai.baidu.com/docs#/OCR-API/5116ac95 )。

接口描述

对机动车蓝牌、绿牌、单/双行黄牌的地域编号和车牌号进行识别,并能同时识别图像中的多张车牌。

请求说明

请求url:https://aip.baidubce.com/rest/2.0/ocr/v1/license_plate
请求参数:image, multi_detect
【百度大脑新品体验】车牌识别

返回说明

返回参数:log_id, Color,number,probability, vertexes_location
【百度大脑新品体验】车牌识别

返回实例
{‘log_id’: 6317054685683389581,
‘words_result’: [{‘color’: ‘blue’,
‘number’: ‘晋A2B222’,
‘probability’: [0.9048133492469788,
0.9014081954956055,
0.9013367891311646,
0.901279628276825,
0.9011501669883728,
0.9012312889099121,
0.9011697769165039],
‘vertexes_location’: [{‘x’: 69, ‘y’: 83},
{‘x’: 326, ‘y’: 83},
{‘x’: 326, ‘y’: 163},
{‘x’: 69, ‘y’: 163}]}]}
Python3 调用接口实现车牌识别

如果是初次使用接口可以查看 接入指南文档 ( https://ai.baidu.com/docs#/Begin/top )了解更多相关信息。

获取 API key 和 Secret Key

  1. 进入百度智能云控制台( https://console.bce.baidu.com/?fromai=1#/aip/overview ),在左侧找到“文字识别”并点击;

【百度大脑新品体验】车牌识别

  1. 点击“创建应用”,填写好相应的信息之后点击“立即创建”即可;
    【百度大脑新品体验】车牌识别
    【百度大脑新品体验】车牌识别
    【百度大脑新品体验】车牌识别

3.应用创建好之后就能看到对应的 API Key 和 Secret Key,这两个对应的内容需要在代码中使用。

获取 access token

Access token 获取以及Access token的相关文档可以查看 鉴权认证机制文档 ( http://ai.baidu.com/docs#/Auth/top )

下面是本文使用 python3 通过 request 库获取 access token 的代码

def get_token_key(client_id, client_secret):
“”"
get access token key.

Args:
    client_id: API Key of related application
    client_secret: Secret Key of related application

Returns:
    token_key: access token

"""
url = f'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials' \
    f'&client_id={client_id}&client_secret={client_secret}'
headers = {'Content-Type': 'application/json; charset=UTF-8'}
res = requests.post(url, headers=headers)
token_content = res.json()
assert "error" not in token_content, f"{token_content['error_description']}"
token_key = token_content['access_token']
return token_key

调用车牌识别接口

根据请求参数可以实现车牌识别接口的调用,本文中将接口调用写在了一个类中,详细代码如下:

-- encoding: utf-8 --

import requests
import cv2
import numpy as np
from utils import draw_zh, get_pixel, get_edge
requests.packages.urllib3.disable_warnings()

class Plate(object):

def __init__(self, client_id, client_secret):
    self.client_id = client_id
    self.client_secret = client_secret
    self.token_key = self.get_token_key()
    self.multi_detect = True
    self.COLOR = {'blue': "蓝色", 'green': "绿色", 'yellow': "黄色"}
    self.color = {'blue': (255, 0, 0), 'green': (0, 255, 0), 'yellow': (0, 255, 255)}

def get_token_key(self):
    url = f'https://aip.baidubce.com/oauth/2.0/token'
    res = requests.get(url, verify=False,params={
        'grant_type': 'client_credentials',
        'client_id': self.client_id,
        'client_secret': self.client_secret})
    token_content = res.json()
    assert "error" not in token_content, f"{token_content['error_description']}"
    token_key = token_content['access_token']
    return token_key

def get_result(self, data):
    """
    调用车牌识别接口,获取识别结果
    Args:
        data: 接口请求参数,类型为 dict

    Returns: 如果未识别到车牌,直接退出;如果识别到车牌,返回识别结果。

    """
    request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/license_plate"
    params = dict()
    params['access_token'] = self.token_key
    res = requests.post(url=request_url,
                        data=data,
                        params=params,
                        verify=False,
                        headers={'Content-Type': 'application/x-www-form-urlencoded'})
    result = res.json()
    self.multi_detect = data['multi_detect']
    if 'error_code' in result:
        print('未检测到车牌,请换图片进行检测!')
        exit()
    return result

def get_length(self, result):
    """

    Args:
        result: 调用接口获得的识别结果,类型为 dict

    Returns: 识别到的车牌的数量

    """
    return len(result['words_result']) if self.multi_detect else 1

def draw(self, img, result, color=(0, 255, 0), merge=False):
    """
    将识别结果绘制在原图像上,包括车牌边框、颜色及车牌号
    Args:
        img: 通过 opencv 读入的图像
        result: 调用车牌识别接口获取的识别结果
        color: 绘制所用的颜色
        merge: 是否将车牌提取出来放在原图像左上角

    Returns: 绘制好结果的图像

    """
    length = self.get_length(result)
    data = result['words_result']
    for i in range(length):
        plate_color = self.get_color(data[i])
        number = self.get_number(data[i])
        points = self.get_points(data[i])
        pts = np.array(points, np.int32).reshape((-1, 1, 2))
        cv2.polylines(img, [pts], True, self.color[plate_color], 3)
        (x, y, w, h) = cv2.boundingRect(pts)

        pixel = get_pixel(w)
        edge = get_edge(pixel)

        roi = np.zeros((edge+h, w, 3), np.uint8)
        roi.fill(255)
        clone = img.copy()
        roi[edge:, :] = clone[y:y + h, x:x + w]
        draw_zh(roi, f'{number}', 0, 0, self.color[plate_color], pixel)
        # cv2.imshow(f'roi{i}', roi)
        background = img[points[0][1] - edge:points[0][1], points[0][0]:points[0][0]+edge*8]
        background.fill(255)
        draw_zh(img, f'{number} - {self.COLOR[plate_color]}', points[0][0], points[0][1] - edge,
                self.color[plate_color], pixel)
        if merge:
            img[:edge+h, :w] = roi
    return img

@staticmethod
def get_log_id(result):
    return result['log_id']

@staticmethod
def get_color(data):
    return data['color']

@staticmethod
def get_number(data):
    return data['number']

@staticmethod
def get_points(data):
    points = data['vertexes_location']
    locations = list()
    for point in points:
        locations.append([point['x'], point['y']])
    return locations

调用类实现识别

通过调用上面介绍的车牌识别类可以方便的执行车牌识别

以下是 python3 执行的代码

import requests
from plate import Plate
from utils import pic_base64
from pprint import pprint
import cv2
import imutils
requests.packages.urllib3.disable_warnings()

client_id = “这里填写自己的 API Key”
client_secret = “这里填写自己的 Secret Key”

img_name = “images/004.jpg”
image_base64 = pic_base64(img_name)
multi_detect = True

data = dict()
data[‘image’] = str(image_base64, encoding=‘utf-8’)
data[‘multi_detect’] = multi_detect

plate_obj = Plate(client_id, client_secret)
result = plate_obj.get_result(data)

pprint(result)

img = cv2.imread(img_name)
img = plate_obj.draw(img, result, merge=False)
cv2.namedWindow(‘pic’, cv2.WINDOW_NORMAL)
cv2.imshow(‘pic’, img)
cv2.waitKey()
车牌识别结果展示
【百度大脑新品体验】车牌识别
【百度大脑新品体验】车牌识别
【百度大脑新品体验】车牌识别
【百度大脑新品体验】车牌识别

从结果中可以看到,对于单个车牌的检测还是非常准确的。多个车牌的检测还是有一些问题。但是在实际应用中,多车牌的识别暂时还比较少。

相关标签: ocr