车牌识别——图像分割

完整项目博客

​​​​​​利用CNN卷积神经网络实现车牌识别(tensorflow)附完整项目代码_SOBE_rrr的博客-CSDN博客_基于卷积神经网络的车牌识别

 

直接拿来的 以后可以参考学习

from cv2 import cv2
import numpy as np
import os

"""
通过对车牌的颜色、面积、倾斜度进行识别。
代码如下:
在识别图片时,首先要调整图片的比例,也就是n,图片的大小,决定了车牌面积的大小,决定了能不能识别出来,一般图片要占到屏幕面积的1/4左右。
车牌的相应信息,储存在box中,可以选择输出,此程序输出了面积,角度和比例。

在opencv中,坐标系原点在左上角,相对于x轴,逆时针旋转角度为负,顺时针旋转角度为正。
所以,θ∈(-90度,0]。程序中也根据角度大小进行排除区域,如果太斜的话,识别不出来。
"""
class picDeal(object):

    def __init__(self, path):
        self.pathDir = './result/'
        self.path = path
        self.subPic()
        self.dealPic()

    def takefirst(self, elem):
        return elem[0]

    def subPic(self):
        lower_blue = np.array([90, 90, 0])
        upper_blue = np.array([120, 210, 250])
        img = cv2.imread(self.path)
        # 设置图片的比例,只有图片的显示面积合适,才能定位出车牌,需要调节
        n = 0.8
        sp = img.shape
        height = round(n * sp[0])
        weight = round(n * sp[1])
        new_img = cv2.resize(img, (weight, height))
        # cv2.imshow('img', new_img)

        hsv = cv2.cvtColor(new_img, cv2.COLOR_BGR2HSV)
        mark = cv2.inRange(hsv, lower_blue, upper_blue)
        # 形态学分割是识别的白色区域。如果在mark中车牌的颜色是黑色,需要翻转
        # mark = cv2.bitwise_not(mark)
        # cv2.imshow("mark", mark)

        # 腐蚀和膨胀
        kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (4, 5))  # 定义矩形结构元素
        # 腐蚀和膨胀的次数也可以根据情况调节
        img_erode = cv2.erode(mark, kernel, iterations=1)
        img_dilated = cv2.dilate(mark, kernel, iterations=3)
        # cv2.imshow('erode', img_dilated)

        # 寻找轮廓
        contours, hierarchy = cv2.findContours(img_dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        # print(contours)
        # 如果报错 too many values to unpack 试试binary,contours,hierarchy= cv2.findContours()

        for i in range(len(contours)):
            area = cv2.contourArea(contours[i])
            # print(area)
            if area > 4000:
                rect = cv2.minAreaRect(contours[i])  # 提取矩形坐标
                box = cv2.boxPoints(rect)
                box = np.int0(box)
                angle = abs(abs(rect[2]) - 45)
                length = max(rect[1])
                wideth = min(rect[1])
                bili = length / (wideth + 0.01)

                area = rect[1][0] * rect[1][1]
                if area > 20000 or angle < 30:
                    continue

                if bili > 3.3 or bili < 2.5:
                    continue

                cv2.drawContours(new_img, [box], 0, (0, 0, 255), 2)
                if abs(rect[2]) < 45:
                    a = rect[0][0] - 0.5 * rect[1][0]
                    b = rect[0][0] + 0.5 * rect[1][0]
                    c = rect[0][1] - 0.5 * rect[1][1]
                    d = rect[0][1] + 0.5 * rect[1][1]
                else:
                    a = rect[0][0] - 0.5 * rect[1][1]
                    b = rect[0][0] + 0.5 * rect[1][1]
                    c = rect[0][1] - 0.5 * rect[1][0]
                    d = rect[0][1] + 0.5 * rect[1][0]
                    # print(a,b,c,d)
                license_image = new_img[round(c):round(d), round(a):round(b)]
        n_license = 3
        sp = license_image.shape
        weight_license = round(n_license * sp[1])
        height_license = round(n_license * sp[0])

        license_image = cv2.resize(license_image, (weight_license, height_license))

        license_image_gray = cv2.cvtColor(license_image, cv2.COLOR_BGR2GRAY)

        ret, license_image_erzhi = cv2.threshold(license_image_gray, 160, 255, cv2.THRESH_BINARY)

        # cv2.imshow('img', license_image_erzhi)

        img_erode = cv2.erode(license_image_erzhi, kernel, iterations=1)
        img_dilated = cv2.dilate(img_erode, kernel, iterations=2)
        # cv2.imshow('erode', img_dilated)

        if not os.path.exists(self.path):
            os.mkdir(self.path)

        location_list = []
        contours, hierarchy = cv2.findContours(img_dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        count = 0

        for i in range(len(contours)):

            x, y, w, h = cv2.boundingRect(contours[i])
            # 在img图像画出矩形,(x, y), (x + w, y + h)是矩形坐标,(0, 255, 0)设置通道颜色,2是设置线条粗度
            area = w * h
            length = max(w, h)
            wideth = min(w, h)
            bili = length / (wideth + 0.01)
            if area < 1000 or area > 10000 or bili > 3:
                continue

            location_list.append((x, y, w, h))
            count = count + 1



        # 指定第一个元素排序
        location_list.sort(key=self.takefirst)
        print(location_list)

        for i in range(0, count):
            license_image_1 = img_dilated[location_list[i][1]:location_list[i][1] + location_list[i][3],
                              location_list[i][0]: location_list[i][0] + location_list[i][2]]
            file_name = 'img' + str(i + 1) + '.jpg'
            cv2.imwrite(self.pathDir + file_name, license_image_1)
            cv2.rectangle(license_image_erzhi, (location_list[i][0], location_list[i][1] - 10),
                          (location_list[i][0] + location_list[i][2], location_list[i][1] + location_list[i][3]),
                          (255, 255, 255), 4)


    def dealPic(self):  #将图片转成2*40的灰度图
        for i in range(1, 8):
            path = "./result/img%s.jpg" % (i)
            img = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
            if img is not None:
                print("111111111")
                img = cv2.resize(img, (32, 40))
                cv2.imwrite("./result/imgs%s.jpg" % (i), img)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值