import sensor, image, time, lcd
from pyb import millis
from os import listdir
lcd.init()
library_province = listdir('/library_province')#读取省份模板文件名
library_province.sort()#排序
province_template = [] #省份模板图片
province_similarity = [] #每次识别后所有模板的相似度########
'''for n in range(len(library_province)):
province_template.append(image.Image('/library_province/'+library_province[n]))#存入省份模板图
province_template[n].invert()
province_similarity.append(0) #每次识别后所有模板的相似度'''
library_alphanumeric = listdir('/library_alphanumeric')#读取数字字母模板文件名
library_alphanumeric.sort()#排序
alphanumeric_template = [] #数字字母模板图片
alphanumeric_similarity = [] #每次识别后所有模板的相似度
for n in range(len(library_alphanumeric)):
alphanumeric_template.append(image.Image('/library_alphanumeric/'+library_alphanumeric[n]))#存入数字字母模板图
alphanumeric_template[n].invert()
alphanumeric_similarity.append(0) #每次识别后所有模板的相似度
license_number = []#存储识别到的结果
for n in range(7):
license_number.append(' ')#省位的h
sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.RGB565) # or sensor.RGB565
sensor.set_framesize(sensor.QQVGA) # or sensor.QVGA (or others)
sensor.set_windowing(320,172)
sensor.set_contrast(2)
sensor.set_vflip(True)
sensor.set_hmirror(True)
clock = time.clock() # Tracks FPS.
img_GRAYSCALE = sensor.alloc_extra_fb(320,172,sensor.GRAYSCALE)
img_GRAYSCALE_2 = sensor.alloc_extra_fb(320,172,sensor.GRAYSCALE)
img_targets = []
img_targets.append(sensor.alloc_extra_fb(35,55,sensor.GRAYSCALE))
for n in range(6):
img_targets.append(sensor.alloc_extra_fb(28,45,sensor.GRAYSCALE))
invert = False#是否反转颜色,以适应黑色字符的车牌
while(True):
clock.tick() # Track elapsed milliseconds between snapshots().
#if button.right.state():
#sensor.ioctl(sensor.IOCTL_TRIGGER_AUTO_FOCUS)#自动对焦
target_blob_max = None
img = sensor.snapshot() # Take a picture and return the image.
#一、处理图像并选中数字字母区域
img_GRAYSCALE.draw_image(img,0,0) #原图绘制到灰度画布上,用于定位字符
if invert:
img_GRAYSCALE.invert()
img_GRAYSCALE_2.draw_image(img_GRAYSCALE,0,0) #复制第二份灰度图,用于识别
#img_GRAYSCALE_2.binary([(10,255)]) #按阈值二值化
img_GRAYSCALE.laplacian(1) #通过拉普拉斯变换,突出色彩分界线(数值越大效果越好,但越慢。所以用最小值,再提高画面亮度)
img_GRAYSCALE.gamma_corr(gamma=1.2,contrast=25) #提高画面伽马值、对比度、亮度
#识别浅色区域,加上尺寸、连续度的限制
blobs = img_GRAYSCALE.find_blobs([(2,255)], x_stride=2,y_stride=1,pixels_threshold=50, area_threshold=50, margin=10)
#二、通过设置条件判断,筛选出符合车牌号特征的区域集,并排序,待模板匹配使用
timer = millis()#用于计这段消耗的时间,如果耗时过长,需要优化或移植到底层(C语言)
#1.遍历筛选所有识别结果,筛选条件:自己和其他4个以上元素 高度 和 y坐标 相互相似的目标
target_blobs=[]
for n1 in range(len(blobs)):
find_out_times = 0
for n2 in range(len(blobs)):
#判断高度差、Y轴差异度
if abs(blobs[n1].h() - blobs[n2].h()) < (blobs[n1].h() * 0.2) and \
abs(blobs[n1].cy() - blobs[n2].cy()) < (blobs[n1].h() * 0.3):
find_out_times += 1
if find_out_times > 4:#超过5次符合,记录
target_blobs.append(blobs[n1])
break
#2.结果按y轴排序
target_blobs.sort(key = lambda b: b.y())#按选择框cy排序
#3.在结果中记录每行的结束序号,比如 [(45,3),(85,3),(78,20),(23,20)],第二个元素为第一行的结束序号
line_ending = []#记录每一行目标最后一项的序号
for n in range(0,len(target_blobs)-1):
if abs(target_blobs[n].cy() - target_blobs[n+1].cy()) > target_blobs[n].h()*0.3:#两个Y差大于40%
line_ending.append(n)
line_ending.append(len(target_blobs))#上述方法不能记录最后一行,在此加入最后一行结束点。如果target_blobs没有内容,会加入0
#4.分割每行,并排序、淘汰每行少于5个的元素
target_blob_lines = []#存储以行为单位,完成排序的目标坐标结果
if line_ending and line_ending != [0]:#如果有目标
for n in range(len(line_ending)):#循环遍历
if n == 0:#首行
if line_ending[n] - 0 > 5: #如果大于5个元素,存储内容,否则抛弃内容
target_blob_lines.append(target_blobs[ : line_ending[n]])#转存内容
target_blob_lines[-1].sort(key = lambda b: b[0])#按选择框x坐标排序
elif line_ending[n] - line_ending[n-1] > 5: #非首行。如果大于5个元素,存储内容,否则抛弃内容
target_blob_lines.append(target_blobs[line_ending[n-1] + 1 : line_ending[n]])#转存内容
target_blob_lines[-1].sort(key = lambda b: b[0])#按选择框x坐标排序
#5.进一步筛选掉每行,前后出现的,间距不符的元素
n = 0
while True:
for n in range(len(target_blob_lines)):#行遍历,如果最后一位与倒数第二位间距,不符合倒数第二、第三位间距,则删除最后一位
if (target_blob_lines[n][-2].cx() - target_blob_lines[n][-3].cx())*0.8 <\
(target_blob_lines[n][-1].cx() - target_blob_lines[n][-2].cx()) > \
(target_blob_lines[n][-2].cx() - target_blob_lines[n][-3].cx())*1.2:
del target_blob_lines[n][-1]
break
if n >= len(target_blob_lines)-1:
break
for n in range(len(target_blob_lines)):#行遍历,删除 从后向前数6个以外的其他元素
if len(target_blob_lines[n]) > 6:
del target_blob_lines[n][0 : len(target_blob_lines[n]) - 6]
#6.只保留像素最大的一行
if target_blob_lines:#如果有目标
target_blob_max = max(target_blob_lines, key = lambda b: b[0][4])#每行第一位面积为判断,保留最大的一行
#7.补充省位选择框
h_average = 0 #平均高度
spacing_average = 0 #平均间距(后段相邻部分)
y_difference_average = 0 #平均y坐标差(后段相邻部分)
length = len(target_blob_max)
for n in range(length):
h_average += target_blob_max[n].h()
if n > 1:
spacing_average += target_blob_max[n].cx() - target_blob_max[n-1].cx()
y_difference_average += target_blob_max[n].cy() - target_blob_max[n-1].cy()
h_average = round(h_average / length)
w_average = round(h_average / 2)
spacing_average = round(spacing_average / (length - 2 ))
y_difference_average = round(y_difference_average / (length - 2))
target_blob_max.insert(0, [round(target_blob_max[0].x() - (spacing_average * 1.2)),\
round(target_blob_max[0].y() - (y_difference_average * 1.1)-2),\
round(w_average * 1.4),\
round(h_average * 1.2)])
else: #没找到目标
invert = not invert #通知反转画面,以待识别黑色字符
if target_blob_max:
try: #此处常遇报错,用try跳过报错
for n in range(len(target_blob_max)):
img_targets[n].clear()
if n == 0:
img_targets[n].draw_image(img_GRAYSCALE_2, 0, 0, x_scale = 40 / h_average, y_scale = 40 / h_average,\
roi = (target_blob_max[n][0] - 2,\
target_blob_max[n][1] - 1,\
target_blob_max[n][2] + 5,\
target_blob_max[n][3] + 5))
else:
img_targets[n].draw_image(img_GRAYSCALE_2, 0, 0, x_scale = 40 / target_blob_max[n][3], y_scale = 40 / target_blob_max[n][3],\
roi = (target_blob_max[n][0] - 1,\
target_blob_max[n][1] - 1,\
target_blob_max[n][2] + 5,\
target_blob_max[n][3] + 5))
img.draw_rectangle(target_blob_max[n][:4], color=(255,0,0))
#img.draw_image(img_targets[n], n*40, 0,) #将剪切结果绘制到主画布上,以观察效果
except:
continue
for n in range(len(target_blob_max)):
if n == 0:
matching_rate = 0.75 #初始匹配率
result = None #识别结果
while True:
blob_num = 0 #识别到的目标数量
'''for n1 in range(len(library_province)):
blob = img_targets[n].find_template(province_template[n1], matching_rate, step=2, search = image.SEARCH_EX)
if blob: #如果识别到目标
blob_num += 1 #目标数量+1
result = n1 #保存结果'''
if blob_num == 1: #如果唯一目标
license_number[n] = library_province[result][:-4] #保存结果
#print('成功匹配,匹配率:'+str(matching_rate))
break #结束循环
elif blob_num == 0 and matching_rate > 0.4: #如果匹配率>0.4 且 没找到目标
matching_rate -= 0.1 #匹配率降低
#print('降低匹配率'+str(matching_rate))
else: #多个结果(小概率事件),0个结果 或 匹配率降低到0.4
break #结束循环
else:
matching_rate = 0.75 #初始匹配率
result = None #识别结果
#print('开始匹配第'+str(n)+'位')
while True:
if target_blob_max[n][3] / target_blob_max[n][2] > 3: #窄体,只有1
license_number[n] = '1'
break
blob_num = 0
for n1 in range(len(library_alphanumeric)):
blob = img_targets[n].find_template(alphanumeric_template[n1],0.75, step=2, search = image.SEARCH_EX)
if blob and library_alphanumeric[n1][:-4] != 'I' and library_alphanumeric[n1][:-4] != 'O':
blob_num += 1 #目标数量+1
result = n1 #保存结果
if blob_num == 1: #如果唯一目标
license_number[n] = library_alphanumeric[result][:-4] #保存结果
#print('成功匹配,匹配率:'+str(matching_rate))
break #结束循环
elif blob_num == 0 and matching_rate > 0.4: #如果匹配率>0.4 且 没找到目标
matching_rate -= 0.2 #匹配率降低
#print('降低匹配率'+str(matching_rate))
else: #多个结果(小概率事件),0个结果 或 匹配率降低到0.4
break #结束循环
#img.draw_text(font, target_blob_max[0][0], target_blob_max[0][1]-34, license_number[0]+license_number[1]+license_number[2]+\
#license_number[3]+license_number[4]+license_number[5]+license_number[6],scale=2,GB=True,color=(255,0,0))
img.draw_string(0,0,license_number[1]+license_number[2]+license_number[3]+license_number[4]+license_number[5]+license_number[6],color =(255,0,0),scale=2)
print(license_number)
lcd.display(img)
这是具体代码,下面是显示的情况,不能识别出来
