Python opencv的轮廓检测 基于车牌的字符分割

题目:将车牌的每个汉字和字母框出

0f9a12f5aec046928b58869fd3424eb0.jpeg

本文涉及到的函数在我的上一篇文章Python opencv 加载、显示、保存、图像转换、轮廓检测

均有提及。

目录

1、图像预处理,导入,灰度转换、二值化、反色处理:

2、图像操作,腐蚀、膨胀,轮廓筛选

去除无用信息(边框、螺丝口)

轮廓筛选

3、文字整体检测,画出方框

汉字连接

轮廓检测再筛选

矩形绘制

4、补充

 

1、图像预处理,导入,灰度转换、二值化、反色处理:

得到待检测图像,进行导入,灰度转换、二值化、反色处理(白底黑字好看)

import cv2
import numpy as np
# 读取文件
img2=cv2.imread("opencv_img/img3.jpg")
cv2.imshow("img2",img2)
cv2.waitKey(0)
# 灰度
gray= cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
cv2.imshow("gray",gray)
cv2.waitKey(0)
# 二值化
ret,thresh=cv2.threshold(gray,175,255,cv2.THRESH_BINARY)
cv2.imshow("thresh",thresh)
cv2.waitKey(0)
#反色
thresh = cv2.bitwise_not(thresh)
cv2.imshow("thresh0",thresh)
cv2.waitKey(0)

原图:

adfd7f265eb647c08d37e7d90438ae12.png 

灰度:

 307f25cda670499988c07a80d807506a.png

二值化:

061b5e4cf51546eca80d9bd05854ba26.png

反色:

25eedbc60cf744d297714776be6d8cb4.png

2、图像操作,腐蚀、膨胀,轮廓筛选

进行腐蚀、膨胀操作,去除无用信息(边框、螺丝口)

# 腐蚀 膨胀运算
kernel = np.ones((3,3),np.uint8)

thresh = cv2.dilate(thresh,kernel,iterations= 2)
cv2.imshow("thresh1",thresh)
cv2.waitKey(0)

thresh = cv2.erode(thresh,kernel,iterations= 2)
cv2.imshow("thresh2",thresh)
cv2.waitKey(0)

由于汉字笔画太细的问题,迭代次数设置为2。

注意!注意!以黑色为底色,变肥变瘦的对象为白色图形,所以图中先进行膨胀操作,后进行腐蚀操作。

759d791d0ee748459fef1327e9b781a4.png

8cbc57acf14743668efa414fbf74d631.png

经过操作可以看到螺丝的小圈圈已经消失,但是螺丝孔仍然还在,我们仍需要想办法去除螺丝孔。

轮廓筛选

# 小轮廓去除
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
draw_img1 = cv2.cvtColor(thresh, cv2.COLOR_GRAY2RGB)
res=cv2.drawContours(draw_img1,contours,-1,(0,0,255),2)
cv2.imshow("res3",res)
cv2.waitKey(0)
fill=[]
for contour in contours:
    area = cv2.contourArea((contour))
    if area < 220:
        fill.append(contour)
        # print(area)

thresh=cv2.fillPoly(thresh,fill,(255,255,255))

cv2.imshow("thresh0",thresh)
cv2.waitKey(0)

使用轮廓检测查看所有轮廓:

注意:绘制轮廓 res=cv2.drawContours(draw_img1,contours,-1,(0,0,255),2) 中,将draw_img1进行颜色转换,把灰度图变回了RGB图像,否则会出现轮廓也为黑色分辨不出的问题。

ac9fa8e6d4774e3a9299a4f2e6558984.png

使用for循环筛选周长较小的轮廓,并将其append到新列表fill

使用fillpoly函数将小轮廓堵上。就能得到干净的文字了。

c87ff8d9bc3341f0a036815e411ad76d.png

3、文字整体检测,画出方框

汉字连接

#腐蚀 膨胀
thresh = cv2.erode(thresh,kernel,iterations= 6)
cv2.imshow("thresh2",thresh)
cv2.waitKey(0)

thresh = cv2.dilate(thresh,kernel,iterations= 6)
cv2.imshow("thresh3",thresh)
cv2.waitKey(0)

我们已经得到了干净的车牌号,但是汉字的轮廓有多个,我们需要将其变成一个轮廓,就需要用到开(闭)运算,也就是腐蚀和膨胀操作。

a4604a760b6e4a5aa3d3cbb83fdc3652.png

9164837cbe784b7b9a35fc339920518e.png

经过腐蚀膨胀操作,我们成功的让汉字的笔画都连在了一起,这样就可以进行轮廓检测了。

轮廓检测再筛选

#找轮廓
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
draw_img2=img2.copy()

#筛选轮廓:
need_contours=[]
for contour in contours:
    x, y, w, h = cv2.boundingRect(contour)
    rectangle_area=w*h
    # print(rectangle_area)
    if ( rectangle_area < 10000 and rectangle_area > 4000 ):
        need_contours.append(contour)


res=cv2.drawContours(draw_img2,need_contours,-1,(0,0,255),2)
cv2.imshow("res",res)
cv2.waitKey(0)

再次轮廓检测,并且再次进行一次基于矩形面积的轮廓筛选,就只剩下汉字和字母的轮廓了

基于矩形面积筛选轮廓的原因是每个汉字和字母的矩形大小都差不多,可以有效筛选内轮廓和车牌大轮廓,矩形提取下一步会讲到。

918ca740b1c64c9c9a34ba7a855f815e.png

矩形绘制

#轮廓
draw_img2=img2.copy()
for contour in need_contours:
    x,y,w,h = cv2.boundingRect(contour)
    draw_img2 =cv2.rectangle(draw_img2,(x,y),(x+w,y+h),(0,0,255),2)
cv2.imshow("img3",draw_img2)
cv2.waitKey(0)

提取轮廓的 x,y,w,h 其中(x,y)是轮廓绘制的起始坐标,(w,h)是轮廓外接矩形的宽和高。

直接使用for循环在图上绘制即可。

16744751ccba42d899fd89e77ad1b840.png

4、补充

本例中最大的困难是如何在不影响汉字的情况下去除螺丝孔,两个轮廓筛选的工作都是由人工不断尝试寻找阈值的。不同的汉字经过膨胀和腐蚀后的形态变换不同,可能也存在个别笔画被腐蚀消失的情况,也可能存在相近的两个数字膨胀之后粘连在一起的情况。读者可以使用在线网站生成多个车牌,寻找最佳阈值。

小汽车-车牌预览(在线版)

汉字与字母分割开后,可以使用模板匹配方法 cv2.matchTemplate() 匹配字符,转换为字符串。

 

本文涉及到的函数在我的上一篇文章Python opencv 加载、显示、保存、图像转换、轮廓检测

 均有提及。

 

 

 

 

  • 0
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值