Python做的车牌识别

查看 150|回复 10
作者:sgbyg   
[Python] 纯文本查看 复制代码import cv2
import numpy as np
import glob
def get_plate(image_):
    global plate
    rawImage = image_.copy()
    # 去噪处理
    image_ = cv2.GaussianBlur(image_, (3, 3), 0)
    # 色彩空间转换
    image_ = cv2.cvtColor(image_, cv2.COLOR_BGR2GRAY)
    # Sobel算子
    Sobel_x = cv2.Sobel(image_, cv2.CV_16S, 1, 0)
    absX = cv2.convertScaleAbs(Sobel_x)
    image_ = absX
    # 阈值处理
    ret, image_ = cv2.threshold(image_, 0, 255, cv2.THRESH_OTSU)
    # 闭运算 先膨胀后腐蚀 车牌各个字符是分散的 让车牌构成一体
    kernelX = cv2.getStructuringElement(cv2.MORPH_RECT, (17, 5))
    image_ = cv2.morphologyEx(image_, cv2.MORPH_CLOSE, kernelX)
    # 开运算 先腐蚀后膨胀 去除噪声
    kernelY = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 19))
    image_ = cv2.morphologyEx(image_, cv2.MORPH_OPEN, kernelY)
    # 中值滤波 去除噪声
    image_ = cv2.medianBlur(image_, 15)
    # 查找轮廓
    contours, w1 = cv2.findContours(image_, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    # 逐个遍历 将宽度>3倍高度的轮廓确定为车牌
    for item in contours:
        rect = cv2.boundingRect(item)
        x = rect[0]
        y = rect[1]
        weight = rect[2]
        height = rect[3]
        if weight > (height * 3):
            plate = rawImage[y:y + height, x:x + weight]
    return plate
def preprocessor(image_):
    # 图像去噪灰度处理
    image_ = cv2.GaussianBlur(image_, (3, 3), 0)
    # 色彩空间转换
    gray_image = cv2.cvtColor(image_, cv2.COLOR_RGB2GRAY)
    # 阈值处理
    ret, image_ = cv2.threshold(gray_image, 0, 255, cv2.THRESH_OTSU)
    # 膨胀处理 让一个字构成一个整体
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
    image_ = cv2.dilate(image_, kernel)
    return image_
def split_plate(image_):
    # 查找轮廓,各个字符的轮廓
    contours, hierarchy = cv2.findContours(image_, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    words = []
    # 遍历所有轮廓
    for item in contours:
        rect = cv2.boundingRect(item)
        words.append(rect)
    # 按照x轴坐标值排序(自左向右排序)
    words = sorted(words, key=lambda s: s[0], reverse=False)
    # 用word存放左上角起始点及长宽值
    plateChars = []
    for word in words:
        # 筛选字符的轮廓(高宽比在1.5-8之间,宽度大于3)
        if (word[3] > (word[2] * 1.5)) and (word[3]  3):
            plateChar = image_[word[1]:word[1] + word[3], word[0]:word[0] + word[2]]
            plateChars.append(plateChar)
    return plateChars
template_dict = {0: '0', 1: '1', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7', 8: '8', 9: '9',
                 10: 'A', 11: 'B', 12: 'C', 13: 'D', 14: 'E', 15: 'F', 16: 'G', 17: 'H',
                 18: 'J', 19: 'K', 20: 'L', 21: 'M', 22: 'N', 23: 'P', 24: 'Q', 25: 'R',
                 26: 'S', 27: 'T', 28: 'U', 29: 'V', 30: 'W', 31: 'X', 32: 'Y', 33: 'Z',
                 34: '京', 35: '津', 36: '冀', 37: '晋', 38: '蒙', 39: '辽', 40: '吉', 41: '黑',
                 42: '沪', 43: '苏', 44: '浙', 45: '皖', 46: '闽', 47: '赣', 48: '鲁', 49: '豫',
                 50: '鄂', 51: '湘', 52: '粤', 53: '桂', 54: '琼', 55: '渝', 56: '川', 57: '贵',
                 58: '云', 59: '藏', 60: '陕', 61: '甘', 62: '青', 63: '宁', 64: '新',
                 65: '港', 66: '澳', 67: '台'}
def get_characters():
    c = []
    for i_ in range(0, 67):
        words = []
        words.extend(glob.glob(f'template/{template_dict.get(i_)}/*.*'))
        c.append(words)
    return c
def get_match_value(template, image_):
    # 读取模板图像
    templateImage = cv2.imdecode(np.fromfile(template, dtype=np.uint8), 1)
    # 模板图像色彩空间转换 BGR-->灰度
    templateImage = cv2.cvtColor(templateImage, cv2.COLOR_BGR2GRAY)
    # 模板图像阈值处理 灰度-->二值
    ret, templateImage = cv2.threshold(templateImage, 0, 255, cv2.THRESH_OTSU)
    # 获取待识别图像的尺寸
    height, width = image_.shape
    # 将模板图像调整为与待识别图像尺寸一致
    templateImage = cv2.resize(templateImage, (width, height))
    # 计算模板图像、待识别图像的模板匹配值
    result = cv2.matchTemplate(image_, templateImage, cv2.TM_CCOEFF)
    # 将计算结果返回
    return result[0][0]
def match_chars(plates, chars_):
    # 存储所有的识别结果
    results_ = []
    # 逐个遍历要识别的字符
    for i_ in plates:
        # 最佳匹配
        best_match = []
        # words 对应的是每一个字符
        for words in chars_:
            match = []
            for word in words:
                result = get_match_value(word, i_)
                match.append(result)
            best_match.append(max(match))
        i_ = best_match.index(max(best_match))
        r = template_dict[i_]
        results_.append(r)
    return results_
if __name__ == '__main__':
    # 读取原始图像
    image = cv2.imread("test_img.jpg")
    # 获取车牌
    image = get_plate(image)
    # 预处理
    image = preprocessor(image)
    # 分割车牌 将每个字符独立出来
    plate_chars = split_plate(image)
    # 获取所有模板文件
    chars = get_characters()
    # 使用模板chars逐个识别字符集plates
    results = match_chars(plate_chars, chars)
    # 将列表转换为字符串并输出识别结果
    print("".join(results))
附件解压密码为 52pj

图像, 车牌

1634091415   

if weight > (height * 3):
            plate = rawImage[y:y + height, x:x + weight] 为什么找的图片这里的条件永远无法满足
cat-   

project.7z中的main.pyj 空文件
shojnhv   

谢谢楼主,学习一下
sgbyg
OP
  


cat- 发表于 2024-6-2 16:46
project.7z中的main.pyj 空文件

代码已经在帖子里了
xjlyg   

有大门口抬杆代码吗
Networktest2022   

PY简化这么多
inkoo   

感谢分享
ZhjhJZ   

Python还能做这个!厉害
天空宫阙   

找到候选框再识别的方案不多见了,不知道准确率咋样?
您需要登录后才可以回帖 登录 | 立即注册

返回顶部