注:这是依然一个简单的车牌识别demo

1.前言

在上一篇Python+Opencv简易车牌识别(一):基于HSV颜色空间的图像分割中,我们讲了如何仅基于颜色来进行简单粗暴的车牌分割。今天我们考虑对图像进行一些更复杂的预处理,来使我们的程序能够识别更复杂情境下的车牌。
原图依旧如下:

完整代码于文章末尾给出。

2.分析

2.1.读取图片

程序开始,读取图片。在这里我们将图片进行等比例放缩,宽度固定为400像素,以防止图片分辨率过高影响处理的性能。然后将图片转化为灰度图以供进一步的处理。

# -*- coding: utf-8 -*-
import cv2
import numpy as np#读取图片
img = cv2.imread(r'D:\car1.png')
m = 400 * img.shape[0] / img.shape[1]
#调整图像尺寸
img = cv2.resize(img, (400, int(m)), interpolation = cv2.INTER_AREA)
#转化为灰度图
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

这一阶段得到的灰度图gray_img长这样:

2.2.图像分割

2.2.1.顶帽

在这一阶段,我们采用开运算闭运算这两种形态学运算的方法来对图像进行分割。
开运算:

  • 是一个基于几何运算的滤波器
  • 本质是先腐蚀运算,再膨胀运算
  • 能够除去孤立的小点,毛刺,并保持总体的位置和形状不发生改变

闭运算:

  • 是一个基于几何运算的滤波器
  • 本质是先膨胀运算,再腐蚀运算
  • 能够填平小孔,弥合小裂缝,并保持总体的位置和形状不发生改变

现在,我们先计算一个顶帽。所谓顶帽:

  • 值为原图像 - 开运算
  • 开运算能放大裂缝或者局部亮度较低区域
  • 因此从原图中减去开运算后的图,能够突出比轮廓周围更明亮的区域
  • 可以用来分离比邻近点亮一些的亮斑。在一幅图像具有大幅的背景,而微小物品比较有规律的情况下,可以使用顶帽进行背景提取
#结构元素(kernel)为半径为16的圆
r = 16
h = w = r * 2 + 1
kernel = np.zeros((h, w), np.uint8)
cv2.circle(kernel, (r, r), r, 1, -1)
#开运算
open_img = cv2.morphologyEx(gray_img, cv2.MORPH_OPEN, kernel)
#顶帽
hat_img = cv2.absdiff(gray_img, open_img)

这一阶段得到的顶帽hat_img长这样:

可以看到背景变暗,而车牌、车标等较亮区域得到了增强。

2.2.2.边缘检测

我们上一步增强了图像中几个较亮的区域,其中便包括了我们感兴趣的车牌。现在我们用Canny算子进行边缘检测。
注意在边缘检测之前,要先对图像进行二值化处理。

#二值化函数
def binaryzation(img):maxi = float(img.max())mini = float(img.min())x = maxi - ((maxi - mini) / 2)ret, thresh = cv2.threshold(img, x, 255, cv2.THRESH_BINARY)return thresh
#图像二值化
binary_img = binaryzation(hat_img)
#canny边缘检测
canny = cv2.Canny(binary_img, binary_img.shape[0], binary_img.shape[1])

这一阶段得到的边缘检测结果canny长这样:

2.2.3.填充边缘

边缘检测后能够得到线条形式的图像边缘。现在我们利用闭运算来填平小孔,对边缘内部进行填充:

#闭运算核
kernel = np.ones((5, 19), np.uint8)
#闭运算
close_img = cv2.morphologyEx(canny, cv2.MORPH_CLOSE, kernel)

这一阶段得到的闭运算图像close_img长这样:

2.2.4.噪声消除

可以看到经过上一步的边缘填充后,我们车牌的主体区域已经被标记出来了,但除此之外图像中还存在着许多小的噪点,因此我们进行连续两次开运算尝试把它们消去:

#开运算
open_img = cv2.morphologyEx(close_img, cv2.MORPH_OPEN, kernel)
#更换结构元素
kernel = np.ones((11, 5), np.uint8)
#开运算
open_img = cv2.morphologyEx(open_img, cv2.MORPH_OPEN, kernel)

这一阶段得到的开运算图像open_img长这样:

可见噪声已被大大消除,图像被分割成了8个区域。接下来我们要做的是从这8个区块中找到我们想要的车牌。

2.3.车牌定位

2.3.1.位置提取

在上一节中我们从可视化结果的角度,明确了图片被分割成了8个区域,那么如何获得这8个区域的位置特征(如坐标)呢?
先给出代码:

#找到能够包围给定区块的最小矩形的左下角坐标(min(x),min(y))与右上角坐标(max(x),max(y))
def find_rectangle(contour):x = []y = []for p in contour:y.append(p[0][0])x.append(p[0][1])       return [min(y), min(x), max(y), max(x)]
#提取轮廓
contours, hierarchy = cv2.findContours(open_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
#存储每个块的矩形坐标
block = []
for c in contours:r = find_rectangle(c)block.append(r)

首先是这个findContours函数,其功能为提取区域的边缘。而在cv2.RETR_EXTERNAL模式下,会返回边缘"顶点"坐标构成的数组,例如对于矩形会有四个边缘顶点,三角形会有三个边缘顶点。
然后,对于每个区域,我们尝试找到一个最小的矩形来将其覆盖,这就是find_rectangle方法的作用。

2.3.2.基于HSV颜色空间的筛选

上一篇我们采用的也是基于颜色空间筛选的思想来分割车牌。在这里,我们先将分割出来的图像区域b转化成hsv颜色空间,然后利用"掩膜"来筛选出区域中位于上下界范围内的像素点。最后,对比8个区域颜色范围的满足情况,最符合蓝色颜色区间的区域便是车牌区域。

max_weight = 0
max_index = -1
#遍历分割出来的各个区域
for i in range(len(block)):b = img[block[i][1] : block[i][3], block[i][0] : block[i][2]]#转化为hsv颜色空间hsv = cv2.cvtColor(b, cv2.COLOR_BGR2HSV)#蓝色下界lower = np.array([100, 50, 50])#蓝色上界upper = np.array([140, 255, 255])#利用掩膜进行筛选mask = cv2.inRange(hsv, lower, upper)#计算当前区域的满足情况w1 = 0for m in mask:print(m)w1 += m / 255w2 = 0for n in w1:w2 += nif w2 > max_weight:max_index = imax_weight = w2

现在我们看看选出来的"最可能为车牌"的区域长啥样:

cv2.imshow('ovo', img[block[max_index][1] : block[max_index][3], block[max_index][0] : block[max_index][2]])
cv2.waitKey(0)

2.3.3.标注

最后给选出的区域上框就好了:

#最可能为车牌的区域对应的矩形坐标
rect = block[max_index]
#画框
cv2.rectangle(img, (rect[0], rect[1]), (rect[2], rect[3]),(0, 255, 0), 2)
cv2.imshow('ovo', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

3.完整代码

# -*- coding: utf-8 -*-
import cv2
import numpy as np#二值化
def binaryzation(img):maxi = float(img.max())mini = float(img.min())x = maxi - ((maxi - mini) / 2)ret, thresh = cv2.threshold(img, x, 255, cv2.THRESH_BINARY)return thresh#找到能够包围给定区块的最小矩形的左下角坐标(min(x),min(y))与右上角坐标(max(x),max(y))
def find_rectangle(contour):x = []y = []for p in contour:y.append(p[0][0])x.append(p[0][1])       return [min(y), min(x), max(y), max(x)]
#读取图片
img = cv2.imread(r'D:\car1.png')
m = 400 * img.shape[0] / img.shape[1]
#调整图像尺寸
img = cv2.resize(img, (400, int(m)), interpolation = cv2.INTER_AREA)
#转化为灰度图
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#结构元素(kernel)为半径为16的圆
r = 16
h = w = r * 2 + 1
kernel = np.zeros((h, w), np.uint8)
cv2.circle(kernel, (r, r), r, 1, -1)
#开运算
open_img = cv2.morphologyEx(gray_img, cv2.MORPH_OPEN, kernel)
#顶帽
hat_img = cv2.absdiff(gray_img, open_img)
#图像二值化
binary_img = binaryzation(hat_img)
#canny边缘检测
canny = cv2.Canny(binary_img, binary_img.shape[0], binary_img.shape[1])
#闭运算核
kernel = np.ones((5, 19), np.uint8)
#闭运算
close_img = cv2.morphologyEx(canny, cv2.MORPH_CLOSE, kernel)
#开运算
open_img = cv2.morphologyEx(close_img, cv2.MORPH_OPEN, kernel)
#更换结构元素
kernel = np.ones((11, 5), np.uint8)
#开运算
open_img = cv2.morphologyEx(open_img, cv2.MORPH_OPEN, kernel)
#提取轮廓
contours, hierarchy = cv2.findContours(open_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
#存储每个块的矩形坐标
block = []
for c in contours:r = find_rectangle(c)block.append(r)max_weight = 0
max_index = -1
#遍历分割出来的各个区域
for i in range(len(block)):b = img[block[i][1] : block[i][3], block[i][0] : block[i][2]]#转化为hsv颜色空间hsv = cv2.cvtColor(b, cv2.COLOR_BGR2HSV)#蓝色下界lower = np.array([100, 50, 50])#蓝色上界upper = np.array([140, 255, 255])#利用掩膜进行筛选mask = cv2.inRange(hsv, lower, upper)#计算当前区域的满足情况w1 = 0for m in mask:w1 += m / 255w2 = 0for n in w1:w2 += nif w2 > max_weight:max_index = imax_weight = w2
#最可能为车牌的区域对应的矩形坐标
rect = block[max_index]
#画框
cv2.rectangle(img, (rect[0], rect[1]), (rect[2], rect[3]),(0, 255, 0), 2)
cv2.imshow('ovo', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Python+Opencv简易车牌识别(二):形态学运算,HSV颜色空间筛选与图像分割相关推荐

  1. 2021-01-07 python opencv实现车牌识别 颜色定位

    python opencv实现车牌识别 颜色定位 主要代码参考https://blog.csdn.net/wzh191920/article/details/79589506 GitHub:https ...

  2. 【开源分享】基于Python+OpenCV+PyQt5车牌识别(GUI界面)

    亲测无错:基于Python+OpenCV+PyQt5车牌识别(GUI界面)绝对可以用的!!!!! 基于Python+OpenCV+PyQt5车牌识别(GUI界面) 参考文档

  3. 基于Python opencv实现车牌识别及二维码条形码识别系统 附完整源码

    完整代码:https://download.csdn.net/download/qq_38735017/87416699 原理简介 车牌字符识别使用的算法是 opencv 的 SVM opencv 的 ...

  4. 基于python+Opencv的车牌识别

    车牌识别包括车牌检测(通过图像分割.特征提取获得车牌位置)+车牌识别(对检测到的车牌进行字符内容识别). 一.基本流程如下: 1.车牌检测 1)读取需要进行车牌识别的图片: 2)对图像进行灰度化处理( ...

  5. 车牌识别系统论文python_毕业设计 python opencv实现车牌识别 界面

    #-*- coding: utf-8 -*- __author__ = '樱花落舞' importtkinter as tkfrom tkinter.filedialog import * from ...

  6. python车牌矫正_毕业设计 python opencv实现车牌识别 矩形矫正

    defimg_Transform(car_contours,oldimg,pic_width,pic_hight): car_imgs=[]for car_rect incar_contours:if ...

  7. python基础教程:python+OpenCV实现车牌号码识别

    这篇文章主要介绍了python+OpenCV实现车牌号码识别,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 基于python+OpenCV的车牌号码识别,供大家参考,具 ...

  8. 基于python+OpenCV的车牌号码识别

    基于python+OpenCV的车牌号码识别 车牌识别行业已具备一定的市场规模,在电子警察.公路卡口.停车场.商业管理.汽修服务等领域已取得了部分应用.一个典型的车辆牌照识别系统一般包括以下4个部分: ...

  9. Python 基于 opencv 的车牌识别系统, 可以准确识别车牌号

    大家好,我是程序员徐师兄,6 年大厂程序员经验,点击关注我 简介 毕业设计基于Opencv的车牌识别系统 车牌搜索识别找出某个车牌号 对比识别车牌系统 车牌数据库认证系统 车牌图文搜索系统 车牌数据库 ...

最新文章

  1. image转pixmap qt_Qt 编程指南10 QImage Mat QPixmap转换
  2. [Luogu 3258] JLOI2014 松鼠的新家
  3. [转载] python元组 tuple
  4. png、jpg、gif那些事情
  5. php中session总结,PHP5中Session总结(一)
  6. shiro 同时实现url和按钮的拦截_shiro笔记 【四】
  7. 怎么将文件转换成linux文件,你如何在linux中创建一个将文件转换为大写...
  8. windows10常用快捷键
  9. 【GNN框架系列】DGL第一讲:使用Deep Graph Library实现GNN进行节点分类
  10. 计算机操作系统--UNIX操作系统
  11. vue实现播放rtmp直播视频流
  12. 苹果科学计算机使用方法,iPhone的计算器五大使用技巧
  13. 城市数据大脑:小汽车儿堵成翔?NONONO!
  14. 设置来电铃声、卡2来电铃声、短信铃声、提示铃声、闹铃铃声
  15. 【高并发】假如你网站一天有千万级访问量高并发,如何破解?
  16. 关于函数凹凸性两种定义与二阶导数符号之间的联系证明
  17. strstr的用法(转)
  18. conda虚拟环境pip装包总装载总环境中解决办法
  19. API:BUMO Keypair 指导
  20. 性格内向,不爱说话的人,是如何一步步成为领导的

热门文章

  1. 请列举出html中两个单标签,HTML基础有哪些单标签
  2. 华硕和超微服务器主板稳定性,华硕、超微、泰安三款双路服务器主板横测
  3. java server 参数_java serversocket参数详解
  4. Xilinx FPGA开发板
  5. 子序列问题sequence(【CCF】NOI Online能力测试2 提高组第二题 )
  6. 洛谷 | P1605 迷宫(DFS) C++
  7. 1007 素数对猜想(C语言)
  8. R语言中读取xlsx文件的方法
  9. Java使用代理服务器
  10. hiho一下 第六十六周