Python+Opencv简易车牌识别(二):形态学运算,HSV颜色空间筛选与图像分割
注:这是依然一个简单的车牌识别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颜色空间筛选与图像分割相关推荐
- 2021-01-07 python opencv实现车牌识别 颜色定位
python opencv实现车牌识别 颜色定位 主要代码参考https://blog.csdn.net/wzh191920/article/details/79589506 GitHub:https ...
- 【开源分享】基于Python+OpenCV+PyQt5车牌识别(GUI界面)
亲测无错:基于Python+OpenCV+PyQt5车牌识别(GUI界面)绝对可以用的!!!!! 基于Python+OpenCV+PyQt5车牌识别(GUI界面) 参考文档
- 基于Python opencv实现车牌识别及二维码条形码识别系统 附完整源码
完整代码:https://download.csdn.net/download/qq_38735017/87416699 原理简介 车牌字符识别使用的算法是 opencv 的 SVM opencv 的 ...
- 基于python+Opencv的车牌识别
车牌识别包括车牌检测(通过图像分割.特征提取获得车牌位置)+车牌识别(对检测到的车牌进行字符内容识别). 一.基本流程如下: 1.车牌检测 1)读取需要进行车牌识别的图片: 2)对图像进行灰度化处理( ...
- 车牌识别系统论文python_毕业设计 python opencv实现车牌识别 界面
#-*- coding: utf-8 -*- __author__ = '樱花落舞' importtkinter as tkfrom tkinter.filedialog import * from ...
- python车牌矫正_毕业设计 python opencv实现车牌识别 矩形矫正
defimg_Transform(car_contours,oldimg,pic_width,pic_hight): car_imgs=[]for car_rect incar_contours:if ...
- python基础教程:python+OpenCV实现车牌号码识别
这篇文章主要介绍了python+OpenCV实现车牌号码识别,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 基于python+OpenCV的车牌号码识别,供大家参考,具 ...
- 基于python+OpenCV的车牌号码识别
基于python+OpenCV的车牌号码识别 车牌识别行业已具备一定的市场规模,在电子警察.公路卡口.停车场.商业管理.汽修服务等领域已取得了部分应用.一个典型的车辆牌照识别系统一般包括以下4个部分: ...
- Python 基于 opencv 的车牌识别系统, 可以准确识别车牌号
大家好,我是程序员徐师兄,6 年大厂程序员经验,点击关注我 简介 毕业设计基于Opencv的车牌识别系统 车牌搜索识别找出某个车牌号 对比识别车牌系统 车牌数据库认证系统 车牌图文搜索系统 车牌数据库 ...
最新文章
- image转pixmap qt_Qt 编程指南10 QImage Mat QPixmap转换
- [Luogu 3258] JLOI2014 松鼠的新家
- [转载] python元组 tuple
- png、jpg、gif那些事情
- php中session总结,PHP5中Session总结(一)
- shiro 同时实现url和按钮的拦截_shiro笔记 【四】
- 怎么将文件转换成linux文件,你如何在linux中创建一个将文件转换为大写...
- windows10常用快捷键
- 【GNN框架系列】DGL第一讲:使用Deep Graph Library实现GNN进行节点分类
- 计算机操作系统--UNIX操作系统
- vue实现播放rtmp直播视频流
- 苹果科学计算机使用方法,iPhone的计算器五大使用技巧
- 城市数据大脑:小汽车儿堵成翔?NONONO!
- 设置来电铃声、卡2来电铃声、短信铃声、提示铃声、闹铃铃声
- 【高并发】假如你网站一天有千万级访问量高并发,如何破解?
- 关于函数凹凸性两种定义与二阶导数符号之间的联系证明
- strstr的用法(转)
- conda虚拟环境pip装包总装载总环境中解决办法
- API:BUMO Keypair 指导
- 性格内向,不爱说话的人,是如何一步步成为领导的