opencv车牌识别——简单版

车牌识别

车牌识别1.0版本,只实现了纯数字的识别,可以持续关注我滴博客,查看新改良版本
主体思路:把模板图片与输入图片分别处理,得到轮廓,再利用函数boundingRect(c)函数得到轮廓信息(在原图像坐标),再把用此轮廓信息把图片切割下来,这样就得到了模板与输入图像的切割图像,然后让这些切割图像进行匹配。
除杂处理——>轮廓信息——>切割图像——>切割图像匹配

处理模板及输入图像

模板图像处理

因为模板图像没有杂点,所以画轮廓时不会有多余轮廓,因此不需要膨胀腐蚀操作再与空面板相减
先二值化即可
在这里插入图片描述

输入图像处理

这个输入的图像就会有边界什么的了,先二值化,我采样的是空模板相减,但是考虑到尺寸的缩放以及位置的偏差,所以再对空模板做膨胀操作,让外框更大,然后更好的除掉无关图像
在这里插入图片描述

在这里插入图片描述
核心代码:

input_img,thresh2 = being_binary(input_address,127, 255, cv2.THRESH_BINARY)
null_img,thresh_null = being_binary("D:/python/pycharm/chepai_null.png",127, 255, cv2.THRESH_BINARY)
y,x = null_img.shape
kernel = np.ones((5, 5), np.uint8)
null_img = cv2.dilate(null_img,kernel,iterations=4)
thresh2 = cv2.resize(thresh2,(x,y))
thresh2 = cv2.subtract(thresh2, null_img)

轮廓信息提取

没什么好说的,就是一个findcontours函数,就是提取出来的轮廓要打印一下contours的数量,即len(contours),与数字个数比较要相等,要不然很可能画到了杂点轮廓

# 寻找轮廓函数
contours, hierarachy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

取出模板的切割图片

代码:

def cutting_(thresh,contours):
    name = 0
    img_all = []
    station = []
    for c in contours:
        # 边界矩形--其实就是用获得边界信息,然后再用画矩形函数画一个矩形
        x, y, w, h = cv2.boundingRect(c)
        station.append(x)
        img = thresh[y:y+h,x:x+w]
        img_all.append(img)
    img_all = [img_temp  for _, img_temp in sorted(zip(station,img_all))]

    for t in img_all:
        cv2.imwrite(f"D:/python/{name}.jpg",t)
        name += 1
    return img_all

如何对应图像对应数字

这里数字顺序就是按照切割顺序来的,所以得到的切割图像列表的下标就代表数字

再处理输入图像

考虑到输入图像的性状杂点可能会比较多,防止未排除杂点轮廓的影响,再一步处理,这次采样的是只取最大的前7个轮廓(因为车牌全为数字的话一般只有7位),精度再一步提高

# 获得所有面积,以后方便排序
area_all = []
for cnt in contours2:
    area = cv2.arcLength(cnt, True)
    area_all.append(area)
# 将面积切片,因为车牌全为数字的话一般只有7位,取面积最大的7个就可以了
# zip主要目的是想与下标连接起来画轮廓,与主线无关。zip完了之后如果是两个不同的数据类型记得强制指定一下数据类型,要不然不男不女
zip_contours2 = sorted(zip(area_all,list(range(len(area_all)+1))),reverse=True)[:8]
print(zip_contours2)
for _,i in zip_contours2:
    cv2.drawContours(input0, contours2[i], -1, (0, 0, 255), 2)

切割输入图片并模板匹配

和切割模板图片一样,这个取出感兴趣区。得到输入图片的7张感兴趣区(也就是被切割图片),模板有10个,就这样每一个感兴趣区都要与10个模板匹配一次,但是匹配函数返回的是一个二维数组,这时用于其搭配的函数:minmax,获取最值,具体是大还是小代表匹配程度高,这个要去看匹配函数使用的模式,我这里是取最小值,一个切割图像匹配10次会获得10个最小值,我们取这些最小值中的最小的那一个,就是匹配程度最高的了。

for contour in contours2:
    x, y, w, h = cv2.boundingRect(contour)  # 获取轮廓的外接矩形
    digit_roi = thresh2[y:y + h, x:x + w]  # 从图像中提取数字的感兴趣区域
    digit_roi = cv2.copyMakeBorder(digit_roi, 300, 300, 300, 300, cv2.BORDER_CONSTANT, value=0)
    min_score = 100
    min_match_index = None
    for i in range(len(img_all)):

        result_ = cv2.matchTemplate(digit_roi, img_all[i], cv2.TM_SQDIFF_NORMED)
        match_score, _, _, _ = cv2.minMaxLoc(result_)

        if match_score < min_score:
            min_score = match_score
            min_match_index = i

    cv2.putText(input_draw, f'{min_match_index}',(x,y), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)

结果

这里我是画在图片上,当然也可以打印出来
在这里插入图片描述

下一阶段:从大背景提取车牌并识别

预期涉及基本图像图像处理(膨胀腐蚀找边界)以及resize改变大小

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值