该案例主要巩固所学opencv基础知识,有轮廓检测,形态学知识以及模板匹配。以及python基础知识和对矩阵的运算
该案例分为两部分,第一部分使用鼠标选取数字部分,并保存。
```python
import cv2
import numpy as np
cv2.namedWindow('cardNum')
card = cv2.imread('./img/images/credit_card_01.png')
model = cv2.imread('./img/images/ocr_a_reference.png')
card2 = card.copy()
#鼠标截取范围
StartX = 0
StartY = 0
w = 0
h = 0
flag_c = 0
flag_rect = False
def mouse(event,x,y,flags,userdata):
global StartX, StartY,w,h,flag_rect,card
if event == cv2.EVENT_LBUTTONDOWN:
flag_rect = True
StartX = x
StartY = y
#print("left down")
elif event == cv2.EVENT_LBUTTONUP:
flag_rect = False
cv2.rectangle(card,(StartX,StartY), (x,y), (0,255,0), 2)
w = abs(StartX-x)
h = abs(StartY-y)
print(StartX,StartY,w,h)
elif event == cv2.EVENT_MOUSEMOVE:
if flag_rect == True:
card = card2.copy()
cv2.rectangle(card,(StartX,StartY),(x,y),(0,255,0),2)
#print("move")
cv2.setMouseCallback('cardNum',mouse)
#ROI = card[rect[0]:rect[0]+rect[2],rect[1]:rect[1]+rect[3]]
print(StartX,StartY,w,h)
while True:
cv2.imshow('cardNum',card)
if flag_c ==1:
ROI = card[StartY:StartY+h-1,StartX:StartX+w-1]
cv2.imwrite('./img/images/roi.png',ROI)
#cv2.imshow('ROI2',card_Gray4)
#cv2.imshow('model',model)
# cv2.imshow('ROI',ROI)
k =cv2.waitKey(100)
if k== 27:
break
if k == ord('o'):
flag_c = 1
cv2.destroyAllWindows()
第二部分为图像处理和识别部分
import cv2
import numpy as np
ka = cv2.imread('./img/images/credit_card_02.png')
ka2 = ka.copy()
#card = ka2[189:233,42:541]
card = cv2.imread('./img/images/roi2.png')
model = cv2.imread('./img/images/ocr_a_reference.png')
#更改大小-和template大小相似
Gray2 = cv2.resize(card,(2*card.shape[1],2*card.shape[0]))
model = cv2.resize(model,(int(0.7*model.shape[1]),int(0.7*model.shape[0])))
#数字排序
def sequence(image):
contours, _ = cv2.findContours(image,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
#cv2.drawContours(Gray2,contours,-1,(0,0,255),2)
n = len(contours)
#创建n*4的矩阵
RectBoxes0 = np.ones((n,4),dtype = int)
for i in range(n):
RectBoxes0[i] = cv2.boundingRect(contours[i])
RectBoxes = np.ones((n,4),dtype = int)
for i in range(n):
ftemp = 0
for j in range(n):
if RectBoxes0[i][0] > RectBoxes0[j][0]:
ftemp = ftemp+1
RectBoxes[ftemp] = RectBoxes0[i]
ImgBoxs = [[] for i in range(n)]
for i in range(n):
x,y,w,h = RectBoxes[i]
ROI = image[y:y+h,x:x+w]
ROI = cv2.resize(ROI,(50,80))
_,ROI = cv2.threshold(ROI,200,255,cv2.THRESH_BINARY)
ImgBoxs[i] = ROI
return RectBoxes,ImgBoxs
#灰度化
card_Gray = cv2.cvtColor(Gray2,cv2.COLOR_BGR2GRAY)
model_Gray = cv2.cvtColor(model,cv2.COLOR_BGR2GRAY)
#自适应二值化 高斯确定阈值法 21:自适应确定阈值的邻域大小 3:平均值减去的数
thresh = cv2.adaptiveThreshold(card_Gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,21,3)
_,thresh_model = cv2.threshold(model_Gray,200,255,cv2.THRESH_BINARY)
thresh_model = cv2.bitwise_not(thresh_model)
#逻辑非运算-黑白转换
thresh = cv2.bitwise_not(thresh)
#发现轮廓
contours,_ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#如果轮廓面积小于60变为黑色
for i in range(len(contours)):
if cv2.contourArea(contours[i]) < 60:
threshs = cv2.drawContours(thresh,contours,i,(0,0,0),-1)
#黑帽运算--
kernel = np.ones((15,15),dtype=np.uint8)
blackhat = cv2.morphologyEx(threshs,cv2.MORPH_BLACKHAT,kernel)
#腐蚀运算
kernel2 = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))
erodes = cv2.erode(blackhat,kernel2,iterations=1)
#closes = cv2.morphologyEx(erodes,cv2.MORPH_CLOSE,kernel2,iterations=3)
contours,_ = cv2.findContours(erodes,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
#根据图像面积和长宽比进行选取
for i in range(len(contours)):
x,y,w,h = cv2.boundingRect(contours[i])
aspect_ratio = float(w)/h
A = float(w)*h
if A<700 or A>4000:
erodes = cv2.drawContours(erodes,contours,i,(0,0,0),-1)
elif aspect_ratio>7.0 or aspect_ratio <0.5:
erodes = cv2.drawContours(erodes,contours,i,(0,0,0),-1)
#膨胀后,model和value数字宽度合适
dilation = cv2.dilate(erodes,kernel2,iterations=1)
rectBox,ROIbox = sequence(dilation)
ModelBox,ModelROIbox = sequence(thresh_model)
#模板匹配
score = np.zeros(len(ModelROIbox),dtype=int)
for i in range(len(ROIbox)):
for j in range(len(ModelROIbox)):
score[j] = cv2.matchTemplate(ROIbox[i],ModelROIbox[j],cv2.TM_SQDIFF)
min_val,max_val,min_indx,max_indx = cv2.minMaxLoc(score)
string=str(min_indx[1])
cv2.putText(ka,string,(90+i*25,195),2,1,(0,0,255))
#print(rect)
cv2.imshow('dilation',ka)
#cv2.imshow('r',r)
cv2.waitKey()
![在这里插入图片描述](https://img-blog.csdnimg.cn/249bfbcc1fdc44e9a647d71ef898c848.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54Ok57qi6Jav6YWN6bG_6bG85Lid,size_14,color_FFFFFF,t_70,g_se,x_16#pic_center)