日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

opencv进阶篇---银行卡数字识别

發(fā)布時間:2024/3/24 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 opencv进阶篇---银行卡数字识别 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

執(zhí)行結(jié)果:

主要思想:對模板圖像以及待檢測圖像進(jìn)行外輪廓檢測,并得到各自外接矩形,將模板圖像的外接矩形做resize()操作,使其外接矩形的大小與待檢測圖像外接矩形的大小相一致,然后與待檢測圖形做模板匹配
準(zhǔn)備工作:
1、轉(zhuǎn)為為灰度圖像
2、轉(zhuǎn)化為二值圖像,才能做輪廓檢測
3、根據(jù)輪廓的長寬比例的不同,過濾掉一些銀行卡上無用的干擾信息
4、上面的步驟僅能得到一些大致的輪廓,還需做一些形態(tài)學(xué)操作,然后對數(shù)字進(jìn)行拆分,得到更為精確的數(shù)字信息
注意:在找模板時,應(yīng)該找字體十分接近的字體作為模板

(1)模板預(yù)處理過程:將模板中的每一個數(shù)字分別進(jìn)行灰度轉(zhuǎn)換、二值化、輪廓查找、輪廓繪制、resize()輪廓的大小并且將每個數(shù)字的輪廓值(排好序的)存入字典類型的變量中
模板圖:

預(yù)處理之后的模板圖:

代碼片段:

img=cv.imread("E:\OpenCVTests\Samples\sample/nine/template-matching-ocr\images\ocr_a_reference.png") gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY) ret,ref=cv.threshold(gray,10,255,cv.THRESH_BINARY_INV)#此步驟,應(yīng)該加前面的ret,否則會報錯 refCnts,hierarchy=cv.findContours(ref.copy(),cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE) #后面還要繼續(xù)使用ref,因此需使用ref.copy(),否則會對原圖做出改變;第二個參數(shù)為指定檢測外輪廓;第三個參數(shù)為輪廓逼近的一種方法 cv.drawContours(img,refCnts,-1,(0,0,255),3)#-1表示繪制所有輪廓,當(dāng)指定為其他值時,只在圖像中選擇一個繪制單個輪廓 refCnts=contours.sort_contours(refCnts,method="left-to-right")[0]#返回排序完的輪廓 digits={}#建立一個字典類型,i是輪廓索引,c是輪廓----字典類型:每個索引號對應(yīng)一個索引值 for(i,c)in enumerate(refCnts):#i是輪廓索引,c是對應(yīng)輪廓,則完成了對檢測出來的輪廓進(jìn)行了排序(x,y,w,h)=cv.boundingRect(c)#得到?jīng)]一個外接矩形的左上坐標(biāo)點以及長度、寬度roi=ref[y:y+h,x:x+w]#每個數(shù)字的外接矩形的尺寸roi=cv.resize(roi,(57,88))#重置外接矩形的尺寸至合適大小digits[i]=roi#每個數(shù)字對應(yīng)一個模板

(2)待檢測圖像預(yù)處理過程:主要包括形態(tài)學(xué)操作去噪點、灰度轉(zhuǎn)換、二值化、Sobel()函數(shù)求梯度、輪廓相關(guān)操作(輪廓的查找、輪廓的繪制、外接輪廓、根據(jù)輪廓的長寬比來對輪廓就行篩選、排序)再到遍歷每一塊中的每一個數(shù)字
待檢測圖像原圖:

執(zhí)行一次頂帽操作:

執(zhí)行一次Sobel()求X方向上的梯度操作:求圖中較為明亮的區(qū)域

執(zhí)行一次閉操作:使圖像上的內(nèi)容成塊出現(xiàn)

執(zhí)行一次二值化操作:過濾掉雜亂信息

再執(zhí)行一次閉操作:填補(bǔ)白色塊中的小黑塊

執(zhí)行輪廓檢測、輪廓繪制:

后續(xù)再根據(jù)輪廓的長寬比對輪廓進(jìn)行篩選,篩選出需要的輪廓信息,工寄檢測出4組有用的輪廓信息,并循環(huán)遍歷這四組輪廓中的每一個數(shù)字,方法與上面同。

完整代碼:

import cv2 as cv from imutils import contours import matplotlib as plt import numpy as np FIRST_NUMBER = {"3": "American Express","4": "Visa","5": "MasterCard","6": "Discover Card" } #對模板圖像做預(yù)處理img=cv.imread("E:\OpenCVTests\Samples\sample/nine/template-matching-ocr\images\ocr_a_reference.png") gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY) ret,ref=cv.threshold(gray,10,255,cv.THRESH_BINARY_INV)#此步驟,應(yīng)該加前面的ret,否則會報錯 refCnts,hierarchy=cv.findContours(ref.copy(),cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE) #后面還要繼續(xù)使用ref,因此需使用ref.copy(),否則會對原圖做出改變;第二個參數(shù)為指定檢測外輪廓;第三個參數(shù)為輪廓逼近的一種方法 cv.drawContours(img,refCnts,-1,(0,0,255),3)#-1表示繪制所有輪廓,當(dāng)指定為其他值時,只在圖像中選擇一個繪制單個輪廓 refCnts=contours.sort_contours(refCnts,method="left-to-right")[0]#返回排序完的輪廓 digits={}#建立一個字典類型,i是輪廓索引,c是輪廓----字典類型:每個索引號對應(yīng)一個索引值 for(i,c)in enumerate(refCnts):#i是輪廓索引,c是對應(yīng)輪廓,則完成了對檢測出來的輪廓進(jìn)行了排序(x,y,w,h)=cv.boundingRect(c)#得到?jīng)]一個外接矩形的左上坐標(biāo)點以及長度、寬度roi=ref[y:y+h,x:x+w]#每個數(shù)字的外接矩形的尺寸roi=cv.resize(roi,(57,88))#重置外接矩形的尺寸至合適大小digits[i]=roi#每個數(shù)字對應(yīng)一個模板#對待檢測圖像做預(yù)處理 recKernel=cv.getStructuringElement(cv.MORPH_RECT,(10,3))#為保證檢測信息準(zhǔn)確,需去除銀行卡頁面雜亂信 sqKernel=cv.getStructuringElement(cv.MORPH_RECT,(2,2))#因此需要對圖像做形態(tài)學(xué)操作,故在此設(shè)立卷積核image=cv.imread("E:\OpenCVTests\Samples\sample/nine/template-matching-ocr\images\credit_card_01.png") image=cv.resize(image,(250,200)) gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY) tophat=cv.morphologyEx(gray,cv.MORPH_TOPHAT,recKernel)#根據(jù)字體的大小來選定合適的核;頂帽操作來突出明亮的區(qū)域gradx=cv.Sobel(tophat,ddepth=cv.CV_32F,dx=1,dy=0,ksize=3)#對X還是對Y需要或者同時需要根據(jù)實際需要來設(shè)定,圖像梯度 gradx=np.absolute(gradx)#取絕對值 (minVal,maxVal)=(np.min(gradx),np.max(gradx))#歸一化 gradx=(255*((gradx-minVal)/(maxVal-minVal))) gradx=gradx.astype("uint8")gradx=cv.morphologyEx(gradx,cv.MORPH_CLOSE,recKernel)#執(zhí)行閉操作,使圖像上的內(nèi)容成塊出現(xiàn) ret,thresh=cv.threshold(gradx,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)#低閾值之所以設(shè)為0,是因為后面的方法選用了OTSU自動設(shè)定閾值,適合雙峰的圖像操作 thresh=cv.morphologyEx(thresh,cv.MORPH_CLOSE,sqKernel)#本次閉操作是為了填補(bǔ)二值化圖像中塊中的不完整小塊 Cnts,hierarchy=cv.findContours(thresh.copy(),cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE) cnts=Cnts curImage=image.copy() cv.drawContours(curImage,cnts,-1,(0,0,255),3)#此處輪廓不是原圖像的輪廓,而是經(jīng)歷了一些列運(yùn)算之后的圖像的輪廓 locs=[] for (i,c)in enumerate(cnts):(x,y,w,h)=cv.boundingRect(c)#做出每個輪廓的外接矩形ar=w/float(h)#根據(jù)外接矩形的長寬比來篩選有用的矩形,并將其添加到元組中if ar>2.5 and ar<4.0:if(w>40 and w<55)and(h>10 and h<20):locs.append((x,y,w,h)) locs=sorted(locs,key=lambda x:x[0])#經(jīng)篩選之后的輪廓 output=[] for (i,(gx,gy,gw,gh))in enumerate(locs):#遍歷每一塊中的每一個數(shù)字groupOutput=[]group=gray[gy-5:gy+gh+5,gx-5:gx+gw+5]#取輪廓及其周圍的區(qū)域cv.imshow("group",group)group=cv.threshold(group,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)[1]#后面的[]要加,否則會報錯元組類型不能copy,下面再對每個塊進(jìn)行輪廓檢測、繪制digitCnts,hierarchy=cv.findContours(group.copy(),cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)#每一個group再進(jìn)行輪廓檢測、繪制digitCnts=contours.sort_contours(digitCnts,method="left-to-right")[0]for c in digitCnts:#計算每一組數(shù)中的每一個數(shù)值(x,y,w,h)=cv.boundingRect(c)roi=group[y:y+h,x:x+w]roi=cv.resize(roi,(57,88))#尺寸需與模板的尺寸對應(yīng),得到每一個數(shù)字所在的區(qū)域scores=[]#新建一個空列表,用來存儲檢測到的數(shù)字for (digit,digitROI)in digits.items():#在模板預(yù)處理中建立了數(shù)值的字典類型,一個為索引、一個為值result=cv.matchTemplate(roi,digitROI,cv.TM_CCOEFF)#匹配,返回與之匹配度最高的數(shù)值(_,score,_,_)=cv.minMaxLoc(result)#做10次匹配,取最大值(注意:取最大值還是最小值跟選取的模板匹配方法有關(guān))scores.append(score)groupOutput.append(str(np.argmax(scores)))cv.rectangle(image,(gx-5,gy-5),(gx+gw+5,gy+gh+5),(0,0,255),1)#第一組的矩形框cv.putText(image,"".join(groupOutput),(gx,gy-15),cv.FONT_HERSHEY_SIMPLEX,0.65,(0,0,255),2)output.extend(groupOutput) print("Credit Card Type: {}".format(FIRST_NUMBER[output[0]])) print("Credit Card #: {}".format("".join(output))) cv.imshow("Image",image)cv.waitKey(0) cv.destroyAllWindows()

總結(jié)

以上是生活随笔為你收集整理的opencv进阶篇---银行卡数字识别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。