OpenCV-车牌号检测

本文介绍了一种使用OpenCV的传统图像处理方法进行车牌号检测的过程,包括灰度处理、双边滤波、边缘检测、轮廓分析和车牌区域判断。尽管在特定场景下效果有限,但展示了无监督学习在车牌识别中的应用和对比有监督学习的局限性。
摘要由CSDN通过智能技术生成

OpenCV-车牌号检测

在github上看到一个小项目觉得挺有意思:借助传统图像处理技巧,通过opencv进行车牌号位置检测。虽然我实际测试后效果不太好,但也能学到另一种处理思路。

原作者链接:https://github.com/Aqsa-K/Car-Number-Plate-Detection-OpenCV-Python

一、传统图像处理方法

输入一张原始图片,要求检测出车牌号位置。

第1步:对图像进行resize、灰度处理、双边滤波降噪,得到一张更加干净的图片。
第2步:利用cv2.Canny函数做边缘检测,检测出图片中主要物体的边缘信息。
第3步:利用cv2.findContours函数查找物体的轮廓,分别归到不同的类别。相当于利用物体的轮廓信息,对图片中不同的物体做了聚类处理。
第4步:对不同的聚类结果,利用cv2.approxPolyDP函数分别进行曲线拟合。
第5步:针对每次拟合的结果,添加if语句进行车牌号判别。

二、效果

原始输入图片,并进行resize:

在这里插入图片描述

进行灰度处理:

在这里插入图片描述
通过双边滤波降噪,得到一张更加干净的图片:

在这里插入图片描述
利用cv2.Canny函数做边缘检测:

在这里插入图片描述
利用cv2.findContours函数查找物体的轮廓,根据边缘检测结果分类可得到263个区域。我们对其中合适大小的区域进行cv2.approxPolyDP曲线拟合,如果拟合出的形状接近长方形,且长宽比例合适,我们就认为它是车牌号位置区域。

在这里插入图片描述

三、深入思考

说实话,这个项目实际场景的应用效果并不好。我从网上随意找了10张图片进行测试,大概只有1-2张图片能准确检测出车牌号位置。

在这里插入图片描述
因为算法主要依靠边缘特征进行处理,因此它在车牌号的边缘非常明显的情况下检测效果不错,例如这种车辆的图片:

在这里插入图片描述
在这里插入图片描述
从项目效果可以看出,相比于无监督学习,有监督学习的算法效果往往能好很多。突然发现,在计算机专业学习时,自己接触到的大部分图像处理算法,都是借助无监督的思路来设计的;而在数学专业学习时,自己接触到的大部分图像处理算法,却都是借助有监督的思路来设计的。

四、源码

代码如下:

import numpy as np
import cv2
import imutils

# Read the image file
image = cv2.imread('0.jpg')
# (423, 640, 3)

# Resize the image - change width to 500
image = imutils.resize(image, width=500)
# (330, 500, 3)
cv2.namedWindow("image")
cv2.imshow("image", image)
cv2.waitKey(0)

# RGB to Gray scale conversion
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# (330, 500)
cv2.namedWindow("Grayscale Conversion")
cv2.imshow("Grayscale Conversion", gray)
cv2.waitKey(0)

# Noise removal with iterative bilateral filter(removes noise while preserving edges)
gray = cv2.bilateralFilter(gray, 11, 17, 17)
cv2.namedWindow("Bilateral Filter")
cv2.imshow("Bilateral Filter", gray)
cv2.waitKey(0)

# Find Edges of the grayscale image
edged = cv2.Canny(gray, 170, 200)
# (330, 500)
cv2.namedWindow("Canny Edges")
cv2.imshow("Canny Edges", edged)
cv2.waitKey(0)


# Find contours based on Edges
(cnt, _) = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
# sort contours based on their area keeping minimum required area
# as '30' (anything smaller than this will not be considered)
cnt = sorted(cnt, key=cv2.contourArea, reverse=True)[:30]


# we currently have no Number plate contour
NumberPlateCnt = None

# loop over our contours to find the best possible approximate contour of number plate
for c in cnt:
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.01 * peri, True)

    if len(approx) == 4:

        approx = approx[:, 0, :]
        x1 = np.min(approx[:, 0])
        y1 = np.min(approx[:, 1])
        x2 = np.max(approx[:, 0])
        y2 = np.max(approx[:, 1])

        w = x2 - x1
        h = y2 - y1
        ratio = w/h

        if 3 < ratio < 6:
            NumberPlateCnt = approx
            print(x1, y1, x2, y2, ratio)
            cv2.drawContours(image, [NumberPlateCnt], -1, (0, 255, 0), 3)


# Drawing the selected contour on the original image
cv2.namedWindow("Final Image")
cv2.imshow("Final Image", image)
cv2.waitKey(0)

五、项目链接

如果代码跑不通,可以去下载项目链接:https://blog.csdn.net/Twilight737

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值