OpenCV+Python车牌字符分割和识别入门 (含新能源车牌识别)

本文介绍了使用OpenCV进行车牌识别的核心步骤——字符分割识别,包括图片灰度化、二值化、校正和去噪等处理,以及后续的图像切割和识别。虽然仅实现第二步,但提到了训练提高识别率的方法,如GAN和Tesseract,并提供了代码演示。
该文章已生成可运行项目,

车牌识别三大步骤:

 

1、从图中找出车牌

2、从车牌中识别车牌号

3、通过训练提高识别率

       本次仅实现第二步,这也是核心,其他两个属于附属功能,第三个可以通过GAN或Tesseract来进行训练,这个下篇再进行介绍。

核心步骤:

       图片处理:1、将图片灰度化;2、将灰度图片二值化;3、校正;4、去燥;

       图像切割识别:1、图像切割;2、图像识别

代码演示(注释):

        需要导入,引入库为:opencv-python

#!/usr/bin/env python
# -*- coding:utf-8 -*-

"""
    Author Alexantao By Charm
"""

import cv2

# 定义,都可根据应用进行调整
binary_threshold = 100
segmentation_spacing = 0.9  # 普通车牌值0.95,新能源车牌改为0.9即可


# 1、读取图片,并做灰度处理
img = cv2.imread('img/nycar_num_test1.png')
img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
cv2.imshow('gray',img_gray)
cv2.waitKey(0)


# 2、将灰度图二值化,设定阀值为140
img_thre = img_gray
cv2.threshold(img_gray, binary_threshold, 255, cv2.THRESH_BINARY_INV, img_thre)
cv2.imshow('threshold', img_thre)
cv2.waitKey(0)

# 3、保存黑白图片
cv2.imwrite('img/thre_res.png',img_thre)

# 4、分割字符
white = []  # 记录每一列的白色像素总和
black = []  # 记录每一列的黑色像素总和
height = img_thre.shape[0]
width = img_thre.shape[1]
print(width, height)
white_max = 0   # 仅保存每列,取列中白色最多的像素总数
black_max = 0   # 仅保存每列,取列中黑色最多的像素总数

# 循环计算每一列的黑白色像素总和
for i in range(width):
    w_count = 0     # 这一列白色总数
    b_count = 0     # 这一列黑色总数
    for j in range(height):
        if img_thre[j][i] == 255:
            w_count += 1
        else:
            b_count += 1
    white_max = max(white_max, w_count)
    black_max = max(black_max, b_count)
    white.append(w_count)
    black.append(b_count)


# False表示白底黑字;True表示黑底白字
arg = black_max > white_max


# 分割图像,给定参数为要分割字符的开始位
def find_end(start_):
    end_ = start_ + 1
    for m in range(start_+1, width - 1):
        if(black[m] if arg else white[m]) > (segmentation_spacing * black_max if arg else segmentation_spacing * white_max):
            end_ = m
            break
    return end_


n = 1
start = 1
end = 2
while n < width - 1:
    n += 1
    if(white[n] if arg else black[n]) > ((1 - segmentation_spacing) * white_max if arg else (1 - segmentation_spacing) * black_max):
        # 上面这些判断用来辨别是白底黑字还是黑底白字
        start = n
        end = find_end(start)
        n = end
        if end - start > 5:
            print(start, end)
            cj = img_thre[1:height, start:end]
            cv2.imwrite('img/{0}.png'.format(n), cj)      #此句是输出每个字符,当时未输出直接看的时候因为刷新问题,解决好久,后来发现只是显示刷新的问题
            cv2.imshow('cutChar', cj)
            cv2.waitKey(0)

图片:

          

          

     二值图片:(白底黑字)

         

     分割后:

          一个一个字符分割显示。

 理工男(作者)自己的公众号:

        一个理工男的成长之路,如果你是理工男,带你“不正经”;如果你想了解理工男,带你认识理工男,他们是生活百事通,他们的生活简约而不简单。

不正经的原则:合规合法,信息保真能看懂,字越少事越大,学到真东西享受真实惠,有兴趣加入我一起“不正经”。

本文章已经生成可运行项目
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值