赞
踩
原图 -> 灰度处理 -> 二值化处理(数字部分为白色)-> 膨胀处理 -> 寻找轮廓
找出所有数字的轮廓,分别传入识别函数
(穿针法识别:tubo_roi为各段的区域,通过判断abcdefg有哪几个是白色,来组合成不同的数字)
特殊数字:1 ,通过长宽比大于2来判断为数字1
经过多重处理,成功识别出1,2,3,4,5,6,7,8,9
仅本测试图片可用,其他测试场景可能需要优化图片预处理逻辑
使用测试图片可直接运行,注意图片名称以及路径
import cv2 import numpy as np #原图 image = cv2.imread('photo.jpg',cv2.IMREAD_COLOR) cv2.imshow("image",image) #灰度图处理 image_gry = cv2.imread('photo.jpg',cv2.IMREAD_GRAYSCALE) if image_gry is None: print("not read") exit() cv2.imshow("image_gry", image_gry) #二值化 _, image_bin = cv2.threshold(image_gry,80,255,cv2.THRESH_BINARY) cv2.imshow("image_bin",image_bin) #进行膨胀处理 element = cv2.getStructuringElement(cv2.MORPH_RECT,(20,20)) image_dil = cv2.dilate(image_bin, element) cv2.imshow("image_dil",image_dil) #轮廓寻找 contours_out,hierarchy=cv2.findContours(image_dil, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) #cv2.drawContours(image_bin,contours,-1,(0,255,0),2) num_location = [cv2.boundingRect(contour) for contour in contours_out] num_location.sort(key=lambda x: x[0]) inmage_with_contours = cv2.cvtColor(image_bin,cv2.COLOR_GRAY2BGR) cv2.drawContours(inmage_with_contours,contours_out,-1,(0,225,0),2) cv2.imshow("Contours",inmage_with_contours) # 定义判断区域是否全为白色的函数 def is_all_white(image, row_start, row_end, col_start, col_end): white_num = 0 j=row_start i=col_start while(j <= row_end): while(i <= col_end): if(image[j][i] == 255): white_num+=1 i+=1 j+=1 i=col_start #print('white num is',white_num) if(white_num >= 5): return True else: return False # 定义穿线法识别数字的函数 def tube_identification(inputmat): tube = 0 tubo_roi = [ [inputmat.shape[0] * 0/3, inputmat.shape[0] * 1/3, inputmat.shape[1] * 1/2,inputmat.shape[1] * 1/2], #a [inputmat.shape[0] * 1/3, inputmat.shape[0] * 1/3, inputmat.shape[1] * 2/3,inputmat.shape[1] - 1 ], #b [inputmat.shape[0] * 2/3, inputmat.shape[0] * 2/3, inputmat.shape[1] * 2/3,inputmat.shape[1] - 1 ], #c [inputmat.shape[0] * 2/3, inputmat.shape[0] -1 , inputmat.shape[1] * 1/2,inputmat.shape[1] * 1/2], #d [inputmat.shape[0] * 2/3, inputmat.shape[0] * 2/3, inputmat.shape[1] * 0/3,inputmat.shape[1] * 1/3], #e [inputmat.shape[0] * 1/3, inputmat.shape[0] * 1/3, inputmat.shape[1] * 0/3,inputmat.shape[1] * 1/3], #f [inputmat.shape[0] * 1/3, inputmat.shape[0] * 2/3, inputmat.shape[1] * 1/2,inputmat.shape[1] * 1/2] #g ] i = 0 while(i < 7): if(is_all_white(inputmat,int(tubo_roi[i][0]),int(tubo_roi[i][1]), int(tubo_roi[i][2]),int(tubo_roi[i][3]))): tube = tube + pow(2,i) cv2.line(inputmat, ( int(tubo_roi[i][3]),int(tubo_roi[i][1])), (int(tubo_roi[i][2]), int(tubo_roi[i][0])), (255,0,0), 1) i += 1 if (inputmat.shape[0] / inputmat.shape[1] > 2): # 1 is special, which is much narrower than others tube = 6 if(tube==63): onenumber = 0 elif(tube==6): onenumber = 1 elif(tube==91): onenumber = 2 elif(tube==79): onenumber = 3 elif(tube==102 or tube==110): #110是因为有干扰情况 onenumber = 4 elif(tube==109): onenumber = 5 elif(tube==125): onenumber = 6 elif(tube==7): onenumber = 7 elif(tube==127): onenumber = 8 elif(tube==111): onenumber = 9 else: print("error tube = ",tube) onenumber = -1 return onenumber # 存储通过穿线法识别的数字 detected_numbers = [] # 遍历每个数字区域 for i in range(len(num_location)): x, y, w, h = num_location[i] num_region = image_dil[y:y+h, x:x+w] # 提取数字区域 # 调用穿线法识别数字 detected_number = tube_identification(num_region) detected_numbers.append(detected_number) # 显示数字区域 #cv2.imshow(str(i), num_region) # 输出识别到的数字 print("Detected Numbers:", detected_numbers) cv2.waitKey(0) cv2.destroyAllWindows()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。