参考:
OpenCV C++案例实战二十《银行卡号识别》_Zero___Chen的博客-CSDN博客_opencv c++ card检测
Python中出现问题:ValueError: not enough values to unpack (expected x, got x)的可能汇总及解决办法_左手の明天的博客-CSDN博客
10.银行卡号识别_Suyuoa的博客-CSDN博客_银行卡卡号识别
Python+OpenCV银行卡数字识别(含完整代码)_nicec1的博客-CSDN博客基于Python+Opencv的银行卡号识别系统(附完整代码)_稍微有点难的的博客-CSDN博客_ref_, refcnts, hierarchy = cv2.findcontours(ref.co
由于有关的项目实操都在openCV4版本更新后,所以在更新前后部分函数的使用以及参数的数量等等一些语法运用规则已经有所改变,下面总结一下我在完成该项目时所遇到的卡点以及解决方法。
我的openCV版本:
参数问题:
在实现轮廓检测的时候,需要用到cv2.findcontours函数,在旧版本当中,是有三个返回值的,网上很多教程和代码都是用三个返回值,往往都会报错,这里只需要两个返回值就可以。
digitCnts,hierarchy = cv2.findContours(group.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
groupOutput类型不对:
项目中,最后在银行卡卡面上画出轮廓时需要用到cv2.putText函数将检测到的数字打印出来,而参数中出现的join函数只允许可迭代str类型的变量,在部分的代码中,这一部分出现报错的原因,很有可能就是groupOut的类型不对,可能是list类型,以至于报错,
cv2.rectangle(image,(gX-5,gY-5),(gX+gW+5,gY+gH+5),(0,0,255),1)
cv2.putText(image,''.join(groupOutput),(gX,gY-15),cv2.FONT_HERSHEY_SIMPLEX,0.65,(0,0,255),2)
cv_show('image',image)
output.extend(groupOutput)
可以尝试使用遍历的方法逐个打印
cv2.putText(image_input, "".join((for i in groupOutput)), (gX, gY - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)
但我在尝试这种方法的时候,发现结果出现问题
初步感觉是对待检测图像轮廓检测后获得的轮廓进行筛选时获得ROI的这一流程出现问题
放出该部分的代码
#计算轮廓
threshCnts,hierarchy = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = threshCnts
cur_img = image_input.copy()
cv2.drawContours(cur_img,cnts,-1,(0,0,255),3)
cv_show('img',cur_img)
locs = []
#遍历轮廓
for (i,c) in enumerate(cnts):
(x,y,w,h) = cv2.boundingRect(c)
ar = w /float(h)
if 2.5 < ar < 4.0 and (40 < w < 55) and (10 < h < 20):
locs.append((x,y,w,h))
#将符合的轮廓从左到右排序
locs = sorted(locs, key = lambda ix: ix[0])
output = []
#遍历每一个轮廓中的数字
for (i,(gX,gY,gW,gH)) in enumerate(locs):
groupOutput = []
group = gray[gY - 5:gY+gH +5 ,gX-5 :gX + gW +5]
cv_show('group',group)
#预处理
group = cv2.threshold(group,0,255,cv2.THRESH_OTSU)[1]
cv_show('group',group)
#计算每一组轮廓
digitCnts,hierarchy = cv2.findContours(group.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
digitCnts = imutils.contours.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))
cv_show('roi',roi)
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)))