第十三周周总结

2020.05.16

本周完成了视频中截取帧图篇,并识别图片中车牌号的功能。

识别基本思路:先是车牌提取,识别图中车牌位置并保存车牌图片(流程:高斯去噪、灰度处理、sobel边缘检测、自适应阈值处理、闭运算、中值滤波去除噪点、轮廓绘制、遍历所有轮廓,去除车牌(车牌 宽>2倍高、为了识别准确,只识别靠近摄像头的车牌号,远处车牌号太不清楚,选择y>500,x<1250、轮廓宽<100 并且>50))

# 导入所需模块
import cv2
from matplotlib import pyplot as plt


def cp_tiqu(name):
    # 加载图片
    rawImage = cv2.imread(name)
    # plt_show0('yuantu',rawImage)

    # 高斯去噪
    image = cv2.GaussianBlur(rawImage, (3, 3), 0)
    # 预览效果
    # plt_show0('GaussianBlur',image)
    # 灰度处理
    gray_image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    plt_show('COLOR_RGB2GRAY', gray_image)

    # sobel算子边缘检测(做了一个y方向的检测)
    Sobel_x = cv2.Sobel(gray_image, cv2.CV_16S, 1, 0)
    # Sobel_y = cv2.Sobel(image, cv2.CV_16S, 0, 1)
    absX = cv2.convertScaleAbs(Sobel_x)  # 转回uint8
    # absY = cv2.convertScaleAbs(Sobel_y)
    # dst = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
    image = absX
    plt_show('Sobel bianyuan', image)

    # 自适应阈值处理
    ret, image = cv2.threshold(image, 0, 255, cv2.THRESH_OTSU)
    plt_show('threshold yuzhi', image)

    # 闭运算,是白色部分练成整体
    kernelX = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    print(kernelX)
    image = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernelX, iterations=2)
    plt_show('biyunsuan', image)
    # 去除一些小的白点
    kernelX = cv2.getStructuringElement(cv2.MORPH_RECT, (20, 1))
    kernelY = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 19))
    '''


    # 膨胀,腐蚀
    image = cv2.dilate(image, kernelX)
    image = cv2.erode(image, kernelX)
    # 腐蚀,膨胀
    image = cv2.erode(image, kernelY)
    image = cv2.dilate(image, kernelY)

    plt_show('pengzhangfushi',image)
    '''
    # 中值滤波去除噪点
    image = cv2.medianBlur(image, 15)
    plt_show('chu zao', image)

    # 轮廓检测
    # cv2.RETR_EXTERNAL表示只检测外轮廓
    # cv2.CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息
    contours, hierarchy = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    # 绘制轮廓
    image1 = rawImage.copy()
    cv2.drawContours(image1, contours, -1, (0, 255, 0), 5)
    plt_show0('lunkuo', image1)

    # 筛选出车牌位置的轮廓
    # 这里我只做了一个车牌的长宽比在3:1到4:1之间这样一个判断
    num = 1
    for item in contours:

        # cv2.boundingRect用一个最小的矩形,把找到的形状包起来
        rect = cv2.boundingRect(item)
        x = rect[0]
        y = rect[1]
        weight = rect[2]
        height = rect[3]
        # 440mm×140mm
        # if (weight > (height * 3)) and (weight < (height * 4)) and y > 500:
        if (weight > (height * 2)) and y > 500 and x < 1250 and weight < 100 and weight > 50:
            image = rawImage[y:y + height, x:x + weight]
            #         cv_show('image',image)
            # 图像保存

            image_name = 'car' + str(num) + '.jpg'
            print(image_name)
            plt_show0('save', image)
            cv2.imwrite(image_name, image)
            num += 1

if __name__ == '__main__':

    cp_tiqu("120.jpg")

  原图:

 

 获取车牌图片信息:

 

 

 

 

第二步:将车牌图篇分割为一个个字符图片

思路:高斯去噪、灰度处理、自适应阈值、计算二值、轮廓绘制、筛选各个字符位置的轮廓

# 导入所需模块
import cv2
from matplotlib import pyplot as plt

def zifu_tiqu(name):
    # 加载图片
    rawImage = cv2.imread(name)
    plt_show0('yuantu', rawImage)

    # 高斯去噪
    image = cv2.GaussianBlur(rawImage, (3, 3), 0)
    # 预览效果
    plt_show0('GaussianBlur', image)

    # 灰度处理
    gray_image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    plt_show('gray image', gray_image)

    # 自适应阈值处理
    ret, image = cv2.threshold(gray_image, 0, 255, cv2.THRESH_OTSU)
    plt_show('yuzhi', image)

    # 计算二值图像黑白点的个数,处理绿牌照问题,让车牌号码始终为白色
    area_white = 0
    area_black = 0
    height, width = image.shape
    print(image.shape)
    for i in range(height):
        for j in range(width):
            if image[i, j] == 255:
                area_white += 1
            else:
                area_black += 1
    #if area_white > area_black:
       # ret, image = cv2.threshold(gray_image, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY_INV)
        #plt_show('erzhi', image)

    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 1))
   contours, hierarchy = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    # 绘制轮廓
    image1 = rawImage.copy()
    cv2.drawContours(image1, contours, -1, (0, 255, 0), 1)
    plt_show0('lun kuo', image1)

    # 筛选出各个字符的位置的轮廓
    words = []
    for item in contours:
        # cv2.boundingRect用一个最小的矩形,把找到的形状包起来
        word = []
        rect = cv2.boundingRect(item)
        x = rect[0]
        y = rect[1]
        weight = rect[2]
        height = rect[3]
        word.append(x)
        word.append(y)
        word.append(weight)
        word.append(height)
        words.append(word)

    words = sorted(words, key=lambda s: s[0], reverse=False)

    print(words)
    i = 0
    for word in words:
        if (word[3] > (word[2])) and (word[3] < (word[2] * 5)):
            i = i + 1
            image = rawImage[word[1]:word[1] + word[3], word[0]:word[0] + word[2]]
            plt_show0('single', image)
            print('test2_' + str(i) + '.jpg')
            cv2.imwrite('chepai/test2_' + str(i) + '.jpg', image

  

posted @ 2020-05-16 18:23  HHHarden13  阅读(165)  评论(0编辑  收藏  举报