opencv图像识别车牌

放假前写的代码,pip更新了连注释都不能写,现在看一下真不知道自己写了什么鬼。最邪的是我的能在当前py文件下调用函数生成imread的对象,但是在测试文件就不行,检查过绝对路径和相对路径没有中文,我尝试通过导入imread对象还是None,我纳闷了。所以我决定还是把测试写到同一个地方吧。车牌已经打马赛克。

目录

1 安装

2 代码实现

2.1  调整图片

2.2  去噪声

2.3 Candy边缘检测

2.4 提取车牌号


 

1 安装

正常pip就行,pycharm会有init错误,Linux下没有错误。

2 代码实现

2.1  调整图片

def pic_resize(img, max_width=1000):
    """
    调整车牌的大小
    :param img: 传入的图片
    :param max_width: 最大的宽度默认1000
    :return: 返回车牌
    """
    print("168h,The function'{}' is running.".format(sys._getframe().f_code.co_name))
    height, width = img.shape[:2]
    if width > max_width:
        change_rate = max_width / width
        # 基于局部像素的重采样
        img = cv2.resize(img, (max_width, numpy.int(change_rate * height)), interpolation=cv2.INTER_AREA)
    return img

测试

if __name__ == '__main__':
    img = cv2.imread(JPG)

    # test pic_resiz

    height, width = img.shape[:2]
    print("164h,The original height:", height, "px width:", width, "px")
    res = pic_resize(img)
    print("169h,The original height:", res.shape[0], "px width:", res.shape[1], "px")

结果

64h,The original height: 1632 px width: 2048 px
168h,The function'pic_resize' is running.
169h,The original height: 796 px width: 1000 px

Process finished with exit code 0

 

2.2  去噪声

# erode&dita
def pic_open(img):
    # 转成灰度图像
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 阈值处理
    ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY)
    # 返回符合的地方,并用矩形圈起来
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    # 去燥有一些小的矩形,去除边缘毛躁
    er = cv2.erode(binary, kernel)
    # 进行膨胀操作
    di = cv2.dilate(binary, kernel)
    img = cv2.add(er, di)
    return img

测试

# main函数中
    cv2.imshow("carshow",img)
    img = pic_open(img)
    cv2.imshow("pic_open", img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

结果

 

 

2.3 Candy边缘检测

def pic_extract_edge(binary):
    """
    candy边缘检测
    :param binary:
    :return:
    """
    can_res = cv2.Canny(binary, 50, 150)
    # cv2.imwrite("write_pic/car_plate_pic/edge50_150.jpg", can_res)
    kernel = numpy.ones((25, 25), numpy.uint8)
    img_edge = cv2.morphologyEx(can_res, cv2.MORPH_CLOSE, kernel)
    img_edge = cv2.morphologyEx(img_edge, cv2.MORPH_OPEN, kernel)
    # cv2.imwrite("write_pic/car_plate_pic/pic_tract_edge_openclose_25.jpg", img_edge)
    contours, hierarchy = cv2.findContours(img_edge, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    return contours

因为之前有write结果所以直接看图片

 

 

2.4 提取车牌号

要用提取最小的矩形,因为从图片可知马路上会有虚线或者是旁边的草丛或者是其他很多的干扰。

def get_ratio(rect):
    """
    用于计算长宽之比
    rect:传入一个矩形
    """
    width, height = rect[1]
    if width > height:
        ratio = width / height
    else:
        ratio = height / width
    return ratio


def is_car_plate_box(rect):
    "假如比例是2.5到4自检都是可以检测出车牌的"
    if 2.5 < get_ratio(rect) < 4:
        return True
    return False


# extract car plate
def pic_extract_car_plate(contours, minarea=8100, maxarea=11400):
    car_plates = []
    for contour in contours:
        if minarea < cv2.contourArea(contour) < maxarea:
            #找最小面积的矩形
            rect = cv2.minAreaRect(contour)
            if is_car_plate_box(rect):
                car_plates.append(contour)
    # print(len(car_plates))
    return car_plates

图取到以后就可以把它在原图标识出来

def pic_draw_car_plates(src, car_plates):
    if len(car_plates) != 1:
        print("The length of the car_plates should be 1. I need to adjust the parameters.")
        return
    plate_result = None
    for plate in car_plates:
        ltx, lty, rbx, rby = get_position(plate)
        cv2.rectangle(src, (ltx, lty), (rbx, rby), (0, 0, 255), 2)
        # print(ltx, lty, rbx, rby)
        plate_result = src[lty:rby, ltx:rbx, :]
    return plate_result
    # cv2.imshow("carshow", src)
    # cv2.imshow("plate_result", plate_result)
    # cv2.imwrite("write_pic/car_plate_pic/pic_draw_car_plates(src).jpg", src)
    # cv2.imwrite("write_pic/car_plate_pic/pic_draw_car_plates(plate_result).jpg", plate_result)

结果

 

 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值