计算机视觉cv2入门之车牌号码识别

前边我们已经讲解了使用cv2进行图像预处理与边缘检测等方面的知识,这里我们以车牌号码识别这一案例来实操一下。

大致思路

车牌号码识别的大致流程可以分为这三步:图像预处理-寻找车牌轮廓-车牌OCR识别

接下来我们按照这三步来进行讲解。

图像预处理

首先,在网上随便找一张车牌照:

读取图像

python 复制代码
#读取原始图像
import cv2
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
src_path=r'LicensePlate.jpg'
src_image=cv2.imread(filename=src_path,flags=cv2.IMREAD_COLOR_RGB)
print(src_image.shape)
plt.title('原始图像')
plt.imshow(src_image)

这里我使用matplotlib的imshow函数来显示图像,这样在jupyter环境中可以不打开任何弹窗直接显示图像,比较方便。

转为灰度图

python 复制代码
#转为灰度图
gray_image=cv2.cvtColor(src=src_image,code=cv2.COLOR_RGB2GRAY)
plt.title('原始图像(灰度图)')
plt.imshow(gray_image,cmap='gray')

将原始图像转化为灰度图是为了后续的检测等操作,在计算机视觉任务中,基本上所有的操作都是针对灰度图来进行的,灰度图是将原始图像的多个通道按照一定权重求和叠加而来,这样一来多通道变成了单通道(),在计算量上也会比较友好。

阈值化

python 复制代码
#阈值化
thresh,binary_image=cv2.threshold(src=gray_image,thresh=128,maxval=255,type=cv2.THRESH_OTSU+cv2.THRESH_BINARY)
plt.imshow(binary_image,cmap='gray')

阈值化是为了后续的边缘检测,通常在边缘检测前都需要对图像进行阈值化操作,这样识别出来的边缘相对准确。这里阈值化我们使用cv2.THRESH+cv2.THRESH-OTSU方法来自动对图像进行二值化阈值分割。

边缘检测

python 复制代码
#canny边缘检测
edges=cv2.Canny(image=binary_image,threshold1=0.5*thresh,threshold2=thresh,apertureSize=5,L2gradient=True)
plt.imshow(edges,cmap='gray')

边缘检测是为了初步提取出车牌的轮廓,便于后续的轮廓查找。常用的边缘检测算法有Canny、Sobel、Prewitt等,其中Canny算法具有较高的准确性和鲁棒性,因此在本系统中采用Canny算法进行边缘检测。不太熟悉边缘检测的小伙伴可以去看看我的往期文章:

https://blog.csdn.net/weixin_73953650/article/details/146284620?sharetype=blogdetail&sharerId=146284620&sharerefer=PC&sharesource=weixin_73953650&spm=1011.2480.3001.8118https://blog.csdn.net/weixin_73953650/article/details/146284620?sharetype=blogdetail&sharerId=146284620&sharerefer=PC&sharesource=weixin_73953650&spm=1011.2480.3001.8118

车牌轮廓查找

python 复制代码
#寻找矩形区域轮廓
contours,hiercahy=cv2.findContours(edges,mode=cv2.RETR_TREE,method=cv2.CHAIN_APPROX_SIMPLE)
contours=sorted(contours,key=cv2.contourArea,reverse=True)[:10]
rectangle=None
for point in contours:
    peri=cv2.arcLength(point,True)
    polygons=cv2.approxPolyDP(curve=point,epsilon=0.018*peri,closed=True)
    if len(polygons)==4:
        rectangle=polygons
        plateArea=point
        break
gray_image_copy=gray_image.copy()
src_image_copy=src_image.copy()
cv2.drawContours(image=src_image_copy,contours=[rectangle],contourIdx=0,color=(255,0,0),thickness=5)
cv2.drawContours(image=gray_image_copy,contours=[rectangle],contourIdx=0,color=255,thickness=5)
figure=plt.figure(figsize=(10,10),dpi=100)
plt.subplot(1,2,1),plt.imshow(src_image_copy),plt.title('车牌定位结果(原始图像)')
plt.subplot(1,2,2),plt.imshow(gray_image_copy,cmap='gray'),plt.title('车牌定位结果(灰度图)')

查找轮廓时我们通常使用findContours函数来进行查找**(返回值为所有可能的轮廓点contours以及这些点之间的拓扑结构hierachy)** ,考虑到车牌是矩形区域,因此我们可以在查找到的轮廓点中使用cv2.approxPolyDP函数来对查找到的轮廓进行多边形拟合**(返回值为各个顶点的坐标构成的列表)**只要拟合出的多边形顶点个数为4,那么必然是车牌位置。

然后,我们再使用cv2.drawContours函数将其在原始图像中标记出来即可。

车牌分割

python 复制代码
# #分割提取车牌
x=[location[0][0] for location in plateArea]
y=[location[0][1] for location in plateArea]
Licenseplate=gray_image[min(y):max(y),min(x):max(x)]#切片图像
plt.imshow(Licenseplate,cmap='gray')
cv2.imwrite('Plate.jpg',Licenseplate)

将车牌从原始图像中分割出来的思路也很简单,就是根据我们查找到的轮廓点,来查找其在图像中的位置。PlatArea是矩形车牌轮廓点构成的列表,其内部为各个点的坐标,其中对于任意一点location来说,location[0][0]表示x坐标,location[0][1]表示y坐标。那么,我们只需找到所有x坐标中的最小值与最大值,y坐标中的最小值与最大值,即可确定这个矩形区域在原图像中的范围。

最后,我们还需将这个车牌号码保存一下以便后续的字符识别

OCR识别

考虑到车牌是标准的印刷体,这里我们使用现成的OCR字符识别库,这里我使用的是ddddocr

获取方式

python 复制代码
pip install ddddocr

OCR识别

python 复制代码
#使用ddddocr进行光学识别
import ddddocr
ocr=ddddocr.DdddOcr(show_ad=False,beta=True)
image=open('Plate.jpg','rb')
answer=ocr.classification(image.read())
image.close()
print(f'车牌号为:{answer.upper()}')
plt.imshow(src_image,cmap='gray')
plt.text(x=src_image.shape[1]//4,y=src_image.shape[0]/2,s=f'车牌号为:{answer.upper()}',size=20,color='red')

使用ddddocr时需要传入的图像数据是Bytes类型,因此我们使用open('.jpg','rb').read()语句即可实现读取图像的bytes数据,最后我们再将得到的结果其标注在原始图像上。

完整代码

python 复制代码
#读取原始图像
import cv2
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
src_path=r'LicensePlate.jpg'
src_image=cv2.imread(filename=src_path,flags=cv2.IMREAD_COLOR_RGB)
print(src_image.shape)
plt.title('原始图像')
plt.imshow(src_image)
#转为灰度图
gray_image=cv2.cvtColor(src=src_image,code=cv2.COLOR_RGB2GRAY)
plt.title('原始图像(灰度图)')
plt.imshow(gray_image,cmap='gray')
#阈值化
thresh,binary_image=cv2.threshold(src=gray_image,thresh=128,maxval=255,type=cv2.THRESH_OTSU+cv2.THRESH_BINARY)
plt.imshow(binary_image,cmap='gray')
#canny边缘检测
edges=cv2.Canny(image=binary_image,threshold1=0.5*thresh,threshold2=thresh,apertureSize=5,L2gradient=True)
plt.imshow(edges,cmap='gray')
#寻找矩形区域轮廓
contours,hiercahy=cv2.findContours(edges,mode=cv2.RETR_TREE,method=cv2.CHAIN_APPROX_SIMPLE)
contours=sorted(contours,key=cv2.contourArea,reverse=True)[:10]
rectangle=None
for point in contours:
    peri=cv2.arcLength(point,True)
    polygons=cv2.approxPolyDP(curve=point,epsilon=0.018*peri,closed=True)
    if len(polygons)==4:
        rectangle=polygons
        plateArea=point
        break
gray_image_copy=gray_image.copy()
src_image_copy=src_image.copy()
cv2.drawContours(image=src_image_copy,contours=[rectangle],contourIdx=0,color=(255,0,0),thickness=5)
cv2.drawContours(image=gray_image_copy,contours=[rectangle],contourIdx=0,color=255,thickness=5)
figure=plt.figure(figsize=(10,10),dpi=100)
plt.subplot(1,2,1),plt.imshow(src_image_copy),plt.title('车牌定位结果(原始图像)')
plt.subplot(1,2,2),plt.imshow(gray_image_copy,cmap='gray'),plt.title('车牌定位结果(灰度图)')
# #分割提取车牌
x=[location[0][0] for location in plateArea]
y=[location[0][1] for location in plateArea]
Licenseplate=gray_image[min(y):max(y),min(x):max(x)]#切片图像
plt.imshow(Licenseplate,cmap='gray')
cv2.imwrite('Plate.jpg',Licenseplate)
#使用ddddocr进行光学识别
import ddddocr
ocr=ddddocr.DdddOcr(show_ad=False,beta=True)
image=open('Plate.jpg','rb')
answer=ocr.classification(image.read())
image.close()
print(f'车牌号为:{answer.upper()}')
plt.imshow(src_image,cmap='gray')
plt.text(x=src_image.shape[1]//4,y=src_image.shape[0]/2,s=f'车牌号为:{answer.upper()}',size=20,color='red')

总结

以上便是计算机视觉cv2入门之车牌号码识别的所有内容,如果本文对你有用,还劳驾各位一键三连支持一下博主。

相关推荐
缘友一世1 分钟前
Pytorch常用统计和矩阵运算
人工智能·pytorch·python
饺子大魔王的男人5 分钟前
从零搭建AI工作站:Gemma3大模型本地部署+WebUI配置全套方案
人工智能
alpha xu6 分钟前
Qwen智能体qwen_agent与Assistant功能初探
数据库·人工智能·python·oracle·智能体·千问agent
1296004521 小时前
神经元和神经网络定义
人工智能·深度学习·神经网络
大模型最新论文速读1 小时前
在Text-to-SQL任务中应用过程奖励模型
数据库·人工智能·sql·深度学习·语言模型·自然语言处理
测试者家园1 小时前
安装Python和配置开发环境
开发语言·软件测试·人工智能·python·职场和发展·零基础·质量效能
明明跟你说过1 小时前
深入理解Embedding Models(嵌入模型):从原理到实战(下)
人工智能·语言模型·embedding
满怀10152 小时前
【人工智能核心技术全景解读】从机器学习到深度学习实战
人工智能·python·深度学习·机器学习·tensorflow
Blossom.1182 小时前
探索边缘计算:赋能物联网的未来
开发语言·人工智能·深度学习·opencv·物联网·机器学习·边缘计算
-曾牛2 小时前
Spring AI 与 Hugging Face 深度集成:打造高效文本生成应用
java·人工智能·后端·spring·搜索引擎·springai·deepseek