Realización del sistema de reconocimiento de matrículas de vehículos (2) -Ubicación de matrículas

Realización del sistema de reconocimiento de matrículas de vehículos (2) -Ubicación de matrículas

Prefacio

Soy un novato en procesamiento de visión por computadora en mi último año. Debido a mi interés personal y finalización, quiero aprender sobre la visión por computadora. Estoy esperando sus críticas y correcciones de errores.

Preprocesamiento de imágenes

Cuando la cámara adquiere una imagen de la matrícula de un automóvil, en la mayoría de los casos, no es realista que solo haya una matrícula en la imagen. Es normal que haya edificios, árboles, otros automóviles, etc. en una imagen; y es extremadamente grande. La mayoría de ellos tendrán puntos de ruido, en este caso causará una gran interferencia en el posicionamiento y reconocimiento de la matrícula.
Diagrama de flujo de preprocesamiento de imágenes
Los principios del filtrado de la mediana y el suavizado gaussiano se han introducido muy claramente en muchos blogs de Internet, por lo que no diré más aquí, ¡solo vaya al código!
** Nota: Aquí es solo un recordatorio, todos deben distinguir entre negro sobre fondo blanco o blanco sobre fondo negro. Sufrí mucho cuando estaba estudiando. ¡Esto es muy importante! **

#对图像进行缩放处理
if img_width > MAX_WIDTH:
    resize_rate = MAX_WIDTH / img_width
    img = cv2.resize(img,(MAX_WIDTH,int(img_hight * resize_rate)),interpolation=cv2.INTER_AREA)
# cv_show('img_resize',img)

# 高斯平滑
img_aussian = cv2.GaussianBlur(img,(5,5),1)
# cv_show('img_aussian',img_aussian)

#中值滤波
img_median = cv2.medianBlur(img_aussian,3)
# cv_show('img_median',img_median)

Características de la matrícula

El objeto de nuestra investigación son las placas de matrícula azul y blanca, otras placas no pueden reconocerse temporalmente. Dicho esto, por cierto, explique la información de color de la placa azul y la placa blanca. Para una imagen normalmente expuesta, los valores de tres canales de la placa azul son aproximadamente Azul = 138, Verde = 63, Rojo = 23. Además de la información de color, la placa de matrícula tiene una forma rectangular con una relación de aspecto fija de 3: 1. (Este párrafo está tomado de https://blog.csdn.net/qq_39960119/article/details/83930112)

Posicionamiento de matrículas

La ubicación de la placa de matrícula generalmente también se denomina extracción de matrículas y su propósito es encontrar el área de la matrícula a partir de la imagen que contiene la matrícula. La importancia de la ubicación de la placa de matrícula es evidente. Como primer paso del reconocimiento de matrículas, el éxito o el fracaso de la ubicación del área de matrículas es la base y el principal determinante de la finalización del sistema de reconocimiento de matrículas. Este sistema utiliza un método de posicionamiento basado en información de color. Este método tiene ventajas y desventajas. La ventaja es que puede localizar de forma rápida y precisa el área de la matrícula. La desventaja es que la intensidad de la luz y el clima tienen una gran influencia en el efecto de posicionamiento. Sin embargo, para los principiantes, este método Es más simple y fácil de usar.
Pasos para colocar la placa de matrícula
El código se acaba de completar, es complicado, se ordenará y funcionalizará más tarde. Intento comentar tanto como sea posible. Es conveniente que todos lean. Si no entiendes, puedes comentar y dejar un mensaje.

#分离通道
img_B = cv2.split(img_median)[0]
img_G = cv2.split(img_median)[1]
img_R = cv2.split(img_median)[2]
# print(img_B)
# print(img_G)
# print(img_R)
for i in range(img_median.shape[:2][0]):
    for j in range(img_median.shape[:2][1]):
        if abs(img_B[i,j] - Blue) < THRESHOLD and abs(img_G[i,j] - Green) <THRESHOLD and abs(img_R[i,j] - Red) < THRESHOLD:
            img_median[i][j][0] = 255
            img_median[i][j][1] = 255
            img_median[i][j][2] = 255
        else:
            img_median[i][j][0] = 0
            img_median[i][j][1] = 0
            img_median[i][j][2] = 0
cv_show('img_median',img_median)

kernel = np.ones((3,3),np.uint8)
img_dilate = cv2.dilate(img_median,kernel,iterations = 5) #膨胀操作
img_erosion = cv2.erode(img_dilate,kernel,iterations = 5) #腐蚀操作
cv_show('img_erosion',img_erosion)
img1 = cv2.cvtColor(img_erosion,cv2.COLOR_RGB2GRAY)
# cv_show('img1',img1)
image, contours, hierarchy = cv2.findContours(img1,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
# for i in range(len(contours)):
#     print(contours[i])

car_contours = []
for cnt in contours: #TODO:此处需要一个异常处理(因为有可能/0)
    # 框选 生成最小外接矩形 返回值(中心(x,y), (宽,高), 旋转角度)rect[0]:矩形中心点坐标;rect[1]:矩形的高和宽;rect[2]:矩形的旋转角度
    rect = cv2.minAreaRect(cnt)
    # print('宽高:',rect[1])
    area_width, area_height = rect[1]
    #计算最小矩形的面积,初步筛选
    area = rect[1][0] * rect[1][1] #最小矩形的面积
    if area > MIN_AREA:
        # 选择宽大于高的区域
        if area_width < area_height:
            area_width, area_height = area_height, area_width
        wh_ratio = area_width / area_height
        # print('宽高比:',wh_ratio)
        # 要求矩形区域长宽比在2到5.5之间,2到5.5是车牌的长宽比,其余的矩形排除
        if wh_ratio > 2 and wh_ratio < 5.5:
            car_contours.append(rect)  # rect是minAreaRect的返回值,根据minAreaRect的返回值计算矩形的四个点
            box = cv2.boxPoints(rect)  # box里面放的是最小矩形的四个顶点坐标
            box = np.int0(box)  # 取整
            # for i in range(len(box)):
            #     print('最小矩形的四个点坐标:', box[i])
            # 获取四个顶点坐标
            left_point_x = np.min(box[:, 0])
            right_point_x = np.max(box[:, 0])
            top_point_y = np.min(box[:, 1])
            bottom_point_y = np.max(box[:, 1])
            left_point_y = box[:, 1][np.where(box[:, 0] == left_point_x)][0]
            right_point_y = box[:, 1][np.where(box[:, 0] == right_point_x)][0]
            top_point_x = box[:, 0][np.where(box[:, 1] == top_point_y)][0]
            bottom_point_x = box[:, 0][np.where(box[:, 1] == bottom_point_y)][0]
            vertices = np.array([[top_point_x, top_point_y], [bottom_point_x, bottom_point_y], [left_point_x, left_point_y],[right_point_x, right_point_y]])
        oldimg = cv2.drawContours(img, [box], 0, (0, 0, 255), 2)
        # print(car_contours)
        cv_show('oldimg', oldimg)

Preprocesamiento y posicionamiento de matrículas de todo el código

** Si el entorno es correcto, ¡debería poder ejecutarse después de copiar! **

import numpy as np
import cv2
import argparse
from matplotlib import pyplot as plt
Blue = 138
Green = 63
Red = 23
THRESHOLD = 50
ANGLE = -45
MIN_AREA = 2000
LICENSE_WIDTH = 440
LICENSE_HIGH = 140

#绘图展示(后期放入工具类中)
def cv_show(name,img):
    cv2.namedWindow(name,0)
    print(img.shape)
    cv2.imshow(name,img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

MAX_WIDTH = 640
# 设置参数
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--image", required=True,help="path to input image") #image是变量名
args = vars(parser.parse_args())

#读取原图像
img = cv2.imread(args["image"])
cv_show('img',img)
img_hight, img_width = img.shape[:2]

#-------------------------------预处理--------------------------------------
#对图像进行缩放处理
if img_width > MAX_WIDTH:
    resize_rate = MAX_WIDTH / img_width
    img = cv2.resize(img,(MAX_WIDTH,int(img_hight * resize_rate)),interpolation=cv2.INTER_AREA)
# cv_show('img_resize',img)

# 高斯平滑
img_aussian = cv2.GaussianBlur(img,(5,5),1)
# cv_show('img_aussian',img_aussian)

#中值滤波
img_median = cv2.medianBlur(img_aussian,3)
# cv_show('img_median',img_median)
# print('width:',img_median.shape[:2][0])
# print('h',img_median.shape[:2][1])
#------------------------------车牌定位-------------------------------------
#分离通道
img_B = cv2.split(img_median)[0]
img_G = cv2.split(img_median)[1]
img_R = cv2.split(img_median)[2]
# print(img_B)
# print(img_G)
# print(img_R)
for i in range(img_median.shape[:2][0]):
    for j in range(img_median.shape[:2][1]):
        if abs(img_B[i,j] - Blue) < THRESHOLD and abs(img_G[i,j] - Green) <THRESHOLD and abs(img_R[i,j] - Red) < THRESHOLD:
            img_median[i][j][0] = 255
            img_median[i][j][1] = 255
            img_median[i][j][2] = 255
        else:
            img_median[i][j][0] = 0
            img_median[i][j][1] = 0
            img_median[i][j][2] = 0
cv_show('img_median',img_median)

kernel = np.ones((3,3),np.uint8)
img_dilate = cv2.dilate(img_median,kernel,iterations = 5) #膨胀操作
img_erosion = cv2.erode(img_dilate,kernel,iterations = 5) #腐蚀操作
cv_show('img_erosion',img_erosion)
img1 = cv2.cvtColor(img_erosion,cv2.COLOR_RGB2GRAY)
# cv_show('img1',img1)
image, contours, hierarchy = cv2.findContours(img1,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
# for i in range(len(contours)):
#     print(contours[i])

car_contours = []
for cnt in contours: #TODO:此处需要一个异常处理(因为有可能/0)
    # 框选 生成最小外接矩形 返回值(中心(x,y), (宽,高), 旋转角度)rect[0]:矩形中心点坐标;rect[1]:矩形的高和宽;rect[2]:矩形的旋转角度
    rect = cv2.minAreaRect(cnt)
    # print('宽高:',rect[1])
    area_width, area_height = rect[1]
    #计算最小矩形的面积,初步筛选
    area = rect[1][0] * rect[1][1] #最小矩形的面积
    if area > MIN_AREA:
        # 选择宽大于高的区域
        if area_width < area_height:
            area_width, area_height = area_height, area_width
        wh_ratio = area_width / area_height
        # print('宽高比:',wh_ratio)
        # 要求矩形区域长宽比在2到5.5之间,2到5.5是车牌的长宽比,其余的矩形排除
        if wh_ratio > 2 and wh_ratio < 5.5:
            car_contours.append(rect)  # rect是minAreaRect的返回值,根据minAreaRect的返回值计算矩形的四个点
            box = cv2.boxPoints(rect)  # box里面放的是最小矩形的四个顶点坐标
            box = np.int0(box)  # 取整
            # for i in range(len(box)):
            #     print('最小矩形的四个点坐标:', box[i])
            # 获取四个顶点坐标
            left_point_x = np.min(box[:, 0])
            right_point_x = np.max(box[:, 0])
            top_point_y = np.min(box[:, 1])
            bottom_point_y = np.max(box[:, 1])
            left_point_y = box[:, 1][np.where(box[:, 0] == left_point_x)][0]
            right_point_y = box[:, 1][np.where(box[:, 0] == right_point_x)][0]
            top_point_x = box[:, 0][np.where(box[:, 1] == top_point_y)][0]
            bottom_point_x = box[:, 0][np.where(box[:, 1] == bottom_point_y)][0]
            vertices = np.array([[top_point_x, top_point_y], [bottom_point_x, bottom_point_y], [left_point_x, left_point_y],[right_point_x, right_point_y]])
        oldimg = cv2.drawContours(img, [box], 0, (0, 0, 255), 2)
        # print(car_contours)
        cv_show('oldimg', oldimg)

resultado de la operación

Experimentado con algunas imágenes, ¡el efecto no es malo!
1. Leer la imagen original
Leer imagen original
2. Después del método de preprocesamiento y posicionamiento basado en la información de color
Después del preprocesamiento y el posicionamiento de la matrícula
3. Después de la operación morfológica
Después del procesamiento morfológico
4. Posicionamiento y filtrado de la placa de matrícula según las características ¡El
Después de la revisión de la matrícula
siguiente artículo trata sobre la corrección de imagen!

Supongo que te gusta

Origin blog.csdn.net/dongjinkun/article/details/104757169
Recomendado
Clasificación