import cv2 import numpy as np import warnings warnings.filterwarnings('ignore') def sort_contours(cnts, method="left-to-right"): reverse = False i = 0 if method == "right-to-left" or method == "bottom-to-top": reverse = True if method == "top-to-bottom" or method == "bottom-to-top": i = 1 boundingBoxes = [cv2.boundingRect(c) for c in cnts] #用一个最小的矩形,把找到的形状包起来x,y,h,w (cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes), key=lambda b: b[1][i], reverse=reverse)) return cnts, boundingBoxes def resize(image, width=None, height=None, inter=cv2.INTER_AREA): dim = None (h, w) = image.shape[:2] if width is None and height is None: return image if width is None: r = height / float(h) dim = (int(w * r), height) else: r = width / float(w) dim = (width, int(h * r)) resized = cv2.resize(image, dim, interpolation=inter) return resized img=cv2.imread('number.png') ref=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) _,ref=cv2.threshold(ref,10,255,cv2.THRESH_BINARY_INV) refCnts,_=cv2.findContours(ref,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) # cv2.drawContours(img,refCnts,-1,(0,0,255),3) refCnts = sort_contours(refCnts, method="left-to-right")[0]#排序,从左到右,从上到下 digits={} for (i,c) in enumerate(refCnts): (x,y,w,h)=cv2.boundingRect(c) # cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2) roi=ref[y:y+h,x:x+w] roi=cv2.resize(roi,(57,88)) digits[i]=roi # print(len(digits)) rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3)) sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) img=cv2.imread('testimage.png') img=resize(img,width=300) gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) gradX=cv2.Sobel(gray,ddepth=cv2.CV_32F,dx=1,dy=0,ksize=-1) gradX=np.absolute(gradX) minVal,maxVAL=np.min(gradX),np.max(gradX) gradX=255*((gradX-minVal)/(maxVAL-minVal)) gradX=gradX.astype(np.uint8) gradX=cv2.morphologyEx(gradX,cv2.MORPH_CLOSE,rectKernel) _,thres=cv2.threshold(gradX,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) #只要灰度大于0的都设为255 thres=cv2.morphologyEx(thres,cv2.MORPH_CLOSE,sqKernel) threshCnts,_=cv2.findContours(thres,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) # cv2.drawContours(img,threshCnts,-1,(0,255,0),3) cnts=threshCnts locs=[] for i,c in enumerate(cnts): x,y,w,h=cv2.boundingRect(c) if h>w: h,w=w,h acr=w/h if 2.5<acr<4.0: if (40<w<55) and (10<h<20): locs.append((x,y,w,h)) output=[] locs = sorted(locs, key=lambda x:x[0]) for (i, (gX, gY, gW, gH)) in enumerate(locs): # initialize the list of group digits groupOutput = [] # 根据坐标提取每一个组 group = gray[gY - 5:gY + gH + 5, gX - 5:gX + gW + 5] _,group=cv2.threshold(group,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) digitCnts,_=cv2.findContours(group,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) digitCnts = sort_contours(digitCnts, method="left-to-right")[0] for c in digitCnts: x,y,w,h=cv2.boundingRect(c) roi=group[y:y+h,x:x+w] roi=cv2.resize(roi,(57,88)) scores=[] for (digit, digitROI) in digits.items(): # 模板匹配 result = cv2.matchTemplate(roi, digitROI, cv2.TM_CCOEFF) (_, score, _, _) = cv2.minMaxLoc(result) scores.append(score) # 得到最合适的数字 groupOutput.append(str(np.argmax(scores))) # print(groupOutput) # 画出来 cv2.rectangle(img, (gX - 5, gY - 5), (gX + gW + 5, gY + gH + 5), (0, 0, 255), 1) cv2.putText(img, "".join(groupOutput), (gX, gY - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2) # 得到结果 output.extend(groupOutput) # 打印结果 print("Credit Card #: {}".format("".join(output))) cv2.imshow('1',img) cv2.waitKey()
python+opencv信用卡卡号识别
最新推荐文章于 2022-08-11 23:36:33 发布