opencv 图像匹配python(OpenCV+Python识别车牌和字符分割的实现)
opencv 图像匹配python
OpenCV+Python识别车牌和字符分割的实现本篇文章主要基于python语言和opencv库(cv2)进行车牌区域识别和字符分割,开篇之前针对在python中安装opencv的环境这里不做介绍,可以自行安装配置!
车牌号检测需要大致分为四个部分:
1.车辆图像获取
2.车牌定位、
3.车牌字符分割
4.车牌字符识别
具体介绍
车牌定位需要用到的是图片二值化为黑白后进canny边缘检测后多次进行开运算与闭运算用于消除小块的区域,保留大块的区域,后用cv2.rectangle选取矩形框,从而定位车牌位置
车牌字符的分割前需要准备的是只保留车牌部分,将其他部分均变为黑色背景。这里我采用cv2.grabcut方法,可将图像分割成前景与背景。分割完成后,再经过二值化为黑白图后即可进行字符分割。由于图像中只有黑色和白色像素,因此我们需要通过图像的白色像素和黑色像素来分割开字符。即分别通过判断每一行每一列的黑色白色像素值的位置,来定位出字符。
具体步骤如下:
1.灰度转换:将彩色图片转换为灰度图像,常见的r=g=b=像素平均值。
2.高斯平滑和中值滤波:去除噪声。
3.sobel算子:提取图像边缘轮廓,x方向和y方向平方和开跟。
4.二值化处理:图像转换为黑白两色,通常像素大于127设置为255,小于设置为0。
5.膨胀和细化:放大图像轮廓,转换为一个个区域,这些区域内包含车牌。
6.通过算法选择合适的车牌位置,通常将较小的区域过滤掉或寻找蓝色底的区域。
7.标注车牌位置
8.图像切割和识别
通过代码实现:
|
# -*- coding: utf-8 -*- """ @email:cuiran2001@163.com @author: cuiran """ import cv2 import numpy as np from pil import image import os.path from skimage import io,data def stretch(img): ''' 图像拉伸函数 ''' maxi = float (img. max ()) mini = float (img. min ()) for i in range (img.shape[ 0 ]): for j in range (img.shape[ 1 ]): img[i,j] = ( 255 / (maxi - mini) * img[i,j] - ( 255 * mini) / (maxi - mini)) return img def dobinaryzation(img): ''' 二值化处理函数 ''' maxi = float (img. max ()) mini = float (img. min ()) x = maxi - ((maxi - mini) / 2 ) #二值化,返回阈值ret 和 二值化操作后的图像thresh ret,thresh = cv2.threshold(img,x, 255 ,cv2.thresh_binary) #返回二值化后的黑白图像 return thresh def find_rectangle(contour): ''' 寻找矩形轮廓 ''' y,x = [],[] for p in contour: y.append(p[ 0 ][ 0 ]) x.append(p[ 0 ][ 1 ]) return [ min (y), min (x), max (y), max (x)] def locate_license(img,afterimg): ''' 定位车牌号 ''' img,contours,hierarchy = cv2.findcontours(img,cv2.retr_external,cv2.chain_approx_simple) #找出最大的三个区域 block = [] for c in contours: #找出轮廓的左上点和右下点,由此计算它的面积和长度比 r = find_rectangle(c) a = (r[ 2 ] - r[ 0 ]) * (r[ 3 ] - r[ 1 ]) #面积 s = (r[ 2 ] - r[ 0 ]) * (r[ 3 ] - r[ 1 ]) #长度比 block.append([r,a,s]) #选出面积最大的3个区域 block = sorted (block,key = lambda b: b[ 1 ])[ - 3 :] #使用颜色识别判断找出最像车牌的区域 maxweight,maxindex = 0 , - 1 for i in range ( len (block)): b = afterimg[block[i][ 0 ][ 1 ]:block[i][ 0 ][ 3 ],block[i][ 0 ][ 0 ]:block[i][ 0 ][ 2 ]] #bgr转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 = 0 for m in mask: w1 + = m / 255 w2 = 0 for n in w1: w2 + = n #选出最大权值的区域 if w2>maxweight: maxindex = i maxweight = w2 return block[maxindex][ 0 ] def find_license(img): ''' 预处理函数 ''' m = 400 * img.shape[ 0 ] / img.shape[ 1 ] #压缩图像 img = cv2.resize(img,( 400 , int (m)),interpolation = cv2.inter_cubic) #bgr转换为灰度图像 gray_img = cv2.cvtcolor(img,cv2.color_bgr2gray) #灰度拉伸 stretchedimg = stretch(gray_img) '''进行开运算,用来去除噪声''' r = 16 h = w = r * 2 + 1 kernel = np.zeros((h,w),np.uint8) cv2.circle(kernel,(r,r),r, 1 , - 1 ) #开运算 openingimg = cv2.morphologyex(stretchedimg,cv2.morph_open,kernel) #获取差分图,两幅图像做差 cv2.absdiff('图像1','图像2') strtimg = cv2.absdiff(stretchedimg,openingimg) #图像二值化 binaryimg = dobinaryzation(strtimg) #canny边缘检测 canny = cv2.canny(binaryimg,binaryimg.shape[ 0 ],binaryimg.shape[ 1 ]) '''消除小的区域,保留大块的区域,从而定位车牌''' #进行闭运算 kernel = np.ones(( 5 , 19 ),np.uint8) closingimg = cv2.morphologyex(canny,cv2.morph_close,kernel) #进行开运算 openingimg = cv2.morphologyex(closingimg,cv2.morph_open,kernel) #再次进行开运算 kernel = np.ones(( 11 , 5 ),np.uint8) openingimg = cv2.morphologyex(openingimg,cv2.morph_open,kernel) #消除小区域,定位车牌位置 rect = locate_license(openingimg,img) return rect,img def cut_license(afterimg,rect): ''' 图像分割函数 ''' #转换为宽度和高度 rect[ 2 ] = rect[ 2 ] - rect[ 0 ] rect[ 3 ] = rect[ 3 ] - rect[ 1 ] rect_copy = tuple (rect.copy()) rect = [ 0 , 0 , 0 , 0 ] #创建掩膜 mask = np.zeros(afterimg.shape[: 2 ],np.uint8) #创建背景模型 大小只能为13*5,行数只能为1,单通道浮点型 bgdmodel = np.zeros(( 1 , 65 ),np.float64) #创建前景模型 fgdmodel = np.zeros(( 1 , 65 ),np.float64) #分割图像 cv2.grabcut(afterimg,mask,rect_copy,bgdmodel,fgdmodel, 5 ,cv2.gc_init_with_rect) mask2 = np.where((mask = = 2 )|(mask = = 0 ), 0 , 1 ).astype( 'uint8' ) img_show = afterimg * mask2[:,:,np.newaxis] return img_show def deal_license(licenseimg): ''' 车牌图片二值化 ''' #车牌变为灰度图像 gray_img = cv2.cvtcolor(licenseimg,cv2.color_bgr2gray) #均值滤波 去除噪声 kernel = np.ones(( 3 , 3 ),np.float32) / 9 gray_img = cv2.filter2d(gray_img, - 1 ,kernel) #二值化处理 ret,thresh = cv2.threshold(gray_img, 120 , 255 ,cv2.thresh_binary) return thresh def find_end(start,arg,black,white,width,black_max,white_max): end = start + 1 for m in range (start + 1 ,width - 1 ): if (black[m] if arg else white[m])>( 0.98 * black_max if arg else 0.98 * white_max): end = m break return end if __name__ = = '__main__' : img = cv2.imread( 'test_images/car001.jpg" alt="opencv 图像匹配python(OpenCV+Python识别车牌和字符分割的实现)" border="0" /> #预处理图像 rect,afterimg = find_license(img) #框出车牌号 cv2.rectangle(afterimg,(rect[ 0 ],rect[ 1 ]),(rect[ 2 ],rect[ 3 ]),( 0 , 255 , 0 ), 2 ) cv2.imshow( 'afterimg' ,afterimg) #分割车牌与背景 cutimg = cut_license(afterimg,rect) cv2.imshow( 'cutimg' ,cutimg) #二值化生成黑白图 thresh = deal_license(cutimg) cv2.imshow( 'thresh' ,thresh) cv2.waitkey( 0 ) #分割字符 ''' 判断底色和字色 ''' #记录黑白像素总和 white = [] black = [] height = thresh.shape[ 0 ] #263 width = thresh.shape[ 1 ] #400 #print('height',height) #print('width',width) white_max = 0 black_max = 0 #计算每一列的黑白像素总和 for i in range (width): line_white = 0 line_black = 0 for j in range (height): if thresh[j][i] = = 255 : line_white + = 1 if thresh[j][i] = = 0 : line_black + = 1 white_max = max (white_max,line_white) black_max = max (black_max,line_black) white.append(line_white) black.append(line_black) print ( 'white' ,white) print ( 'black' ,black) #arg为true表示黑底白字,false为白底黑字 arg = true if black_max<white_max: arg = false n = 1 start = 1 end = 2 s_width = 28 s_height = 28 while n<width - 2 : n + = 1 #判断是白底黑字还是黑底白字 0.05参数对应上面的0.95 可作调整 if (white[n] if arg else black[n])>( 0.02 * white_max if arg else 0.02 * black_max): start = n end = find_end(start,arg,black,white,width,black_max,white_max) n = end if end - start> 5 : cj = thresh[ 1 :height,start:end] # new_image = cj.resize((s_width,s_height),image.bilinear) # cj=cj.reshape(28, 28) print ( "result/%s.jpg" alt="opencv 图像匹配python(OpenCV+Python识别车牌和字符分割的实现)" border="0" /> #保存分割的图片 by cayden # cj.save("result/%s.jpg" alt="opencv 图像匹配python(OpenCV+Python识别车牌和字符分割的实现)" border="0" /> infile = "result/%s.jpg" alt="opencv 图像匹配python(OpenCV+Python识别车牌和字符分割的实现)" border="0" /> io.imsave(infile,cj) # im = image.open(infile) # out=im.resize((s_width,s_height),image.bilinear) # out.save(infile) cv2.imshow( 'cutlicense' ,cj) cv2.waitkey( 0 ) cv2.waitkey( 0 ) cv2.destroyallwindows() |
运行效果如图所示
车牌定位并进行处理
车牌分割如图所示
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持开心学习网。
原文链接:https://blog.csdn.net/cuiran/article/details/86706441
- python小程序编程代码(python实现烟花小程序)
- python中lambda函数是什么意思(python ---lambda匿名函数介绍)
- python ip代理池(Python 实现域名解析为ip的方法)
- 在python中如何删除指定的行(Python删除n行后的其他行方法)
- python和mysql实战(由Python编写的MySQL管理工具代码实例)
- 用python图片转字符串(python实现图片转字符小工具)
- pythonexcel生成报表(python生成每日报表数据Excel并邮件发送的实例)
- python 文本文件读取方法(Python逐行读取文件中内容的简单方法)
- python操作pandas(详解Python学习之安装pandas)
- python参模块使用教程(Python参数解析模块sys、getopt、argparse使用与对比分析)
- python数据分析pandas教程(11个Python Pandas小技巧让你的工作更高效附代码实例)
- python对于gbk处理(Python 2/3下处理cjk编码的zip文件的方法)
- python实现列表删除重复元素(Python代码实现删除一个list里面重复元素的方法)
- python对mysql数据分析(python使用adbapi实现MySQL数据库的异步存储)
- python中字符串常用函数或方法(Python3.5字符串常用操作实例详解)
- python中for语句的无限循环(python使用for循环计算0-100的整数的和方法)
- 天热没胃口 这道菜开胃又下饭,2个小技巧新手一学就会(这道菜开胃又下饭)
- 指天椒紫苏爆炒牛肉(指天椒紫苏爆炒牛肉)
- 谷雨前,吃牛羊肉别忘了吃河鲜,除湿还清热,加紫苏一炒特解馋(吃牛羊肉别忘了吃河鲜)
- 紫苏牛肉锅里滚一滚,香的鼻子都要掉了(紫苏牛肉锅里滚一滚)
- 每天都吃水果的好处(每天吃水果的好处与功效)
- 苹果15价格(苹果15价格512g官网)
热门推荐
- ASP.NET中XML和JSON互转
- 手机无法与服务器建立安全连接(ftp无法与服务器建立连接)
- dedecms的dedesql.class.php on line 489错误的解决方法(dedecms的dedesql.class.php on line 489错误的解决方法)
- mysql自增锁(深入剖析 MySQL 自增锁)
- supersocket分布式架构(ServerSocket默认邦定IP实现过程详解)
- html中的特殊符号编码
- css怎么快速布局(css重绘与重排的方法)
- 云主机的优势是什么(云主机有哪些用途和优势)
- laravel数据查询(laravel按天、按小时,查询数据的实例)
- vue调用组件内部的方法(Vue如何实现组件间通信)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9