哪里可以做网站啊,重庆网站开发设计公司电话,网站开发发布,建造网站目录
信用卡数字识别系统#xff1a;前言与代码解析
前言
项目代码
结果演示
代码模块解析
1. 参数解析模块
2. 轮廓排序函数
3. 图像预处理模块
4. 输入图像处理流程
5. 卡号区域定位
6. 数字识别与输出
系统优势 信用卡数字识别系统#xff1a;前言…目录
信用卡数字识别系统前言与代码解析
前言
项目代码
结果演示
代码模块解析
1. 参数解析模块
2. 轮廓排序函数
3. 图像预处理模块
4. 输入图像处理流程
5. 卡号区域定位
6. 数字识别与输出
系统优势 信用卡数字识别系统前言与代码解析
前言
信用卡数字识别是金融自动化处理的核心技术之一通过计算机视觉技术自动提取卡面信息可应用于支付验证、身份认证等场景。本系统基于模板匹配和图像处理技术实现对信用卡卡号的自动识别。系统通过预处理、轮廓检测和特征匹配三个关键阶段准确识别信用卡上的16位数字并自动判断发卡机构Visa/MasterCard等。以下将详细解析代码各模块功能。 项目代码
import argparse
import imutils
import numpy as np
import myutils
from imutils import contours
import cv2# 设置参数结果
ap argparse.ArgumentParser()
ap.add_argument(-i, --image, requiredTrue,helppath to input image containing credit card)
ap.add_argument(-t, --template, requiredTrue,helppath to input template image)
args vars(ap.parse_args())# 指定信用卡类型
FIRST_NUMBER {3: American Express,4: Visa,5: MasterCard,6: Discover Card
}def sort_contours(cnts, methodleft-to-right):reverse Falsei 0if method right-to-left or method bottom-to-top:reverse Trueif method top-to-bottom or method bottom-to-top:i 1boundingBoxes [cv2.boundingRect(c) for c in cnts] # 用一个最小的矩形把找到的形状包起来x,y,h,w(cnts, boundingBoxes) zip(*sorted(zip(cnts, boundingBoxes),keylambda b: b[1][i], reversereverse))return cnts, boundingBoxesdef resize(image, widthNone, heightNone, intercv2.INTER_AREA):dim None(h, w) image.shape[:2]if width is None and height is None:return imageif 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, interpolationinter)return resized# 绘图展示
def cv_show(name,img):cv2.imshow(name,img)cv2.waitKey(0)cv2.destroyAllWindows()return None# 读取一个模板
imgcv2.imread(args[template])
cv_show(img,img)# 灰度图展示
refcv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv_show(ref,ref)# 二值图像
refcv2.threshold(ref,10,255,cv2.THRESH_BINARY_INV)[1]
cv_show(ref,ref)# 计算轮廓果
ref_,refCnts cv2.findContours(ref.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img,ref_,-1,(0,0,255),3)
cv_show(img,img)
print(np.array(refCnts).shape)
refCnts sort_contours(ref_, methodleft-to-right)[0]
digits {}# 遍历模板轮廓
for (i,c) in enumerate(refCnts):(x,y,w,h) cv2.boundingRect(c)roi ref[y:yh,x:xw]roi cv2.resize(roi,(57,88))digits[i] roi# 初始化卷积核
rectKernel cv2.getStructuringElement(cv2.MORPH_RECT,(9,3))
squareKernel cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))# 读取输入图像、预处理
image cv2.imread(args[image])
cv_show(image,image)
image resize(image,width300)
gary cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
cv_show(gary,gary)# 礼帽操作突出更明亮的区域
tophat cv2.morphologyEx(gary,cv2.MORPH_TOPHAT,rectKernel)
cv_show(tophat,tophat)
gradxcv2.Sobel(tophat,ddepthcv2.CV_32F,dx1,dy0,ksize-1)
gradx np.absolute(gradx)
(minVal,maxVal) (np.min(gradx),np.max(gradx))
gradx (255 * ((gradx - minVal) / (maxVal - minVal)))
gradx gradx.astype(uint8)
print(np.array(gradx).shape)
cv_show(gradx,gradx)# 通过闭操作(先膨胀再腐蚀)将数字连在一起
gradx cv2.morphologyEx(gradx,cv2.MORPH_CLOSE,rectKernel)
cv_show(gradx,gradx)
# THRESH_OTSU会自动寻找全局阈值适合双峰,需要把阈值参数设置为0
thresh cv2.threshold(gradx,0,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv_show(thresh,thresh)# 再来一个闭操作
thresh cv2.morphologyEx(thresh,cv2.MORPH_CLOSE,squareKernel)
cv_show(thresh,thresh)# 计算轮廓
thresh_,threshCnts cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts thresh_
cur_imgimage.copy()
cv2.drawContours(cur_img,cnts,-1,(0,0,255),3)
cv_show(cur_img,cur_img)
locs[]# 遍历轮廓
for (i,c) in enumerate(cnts):(x,y,w,h)cv2.boundingRect(c)ar w / float(h)# 选择合适的区域根据实际任务来这里的基本都是四个数字一组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,keylambda x:x[0])
output[]
# 遍历每一个轮廓中的数字
for (i,(gx,gy,gw,gh)) in enumerate(locs):# initialzie the list of group digitsgroupOutput []# 根据坐标提取数字的区域group gary[gy-5:gygh5,gx-5:gxgw5]cv_show(group,group)# 预处理group cv2.threshold(group,0,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]cv_show(group,group)# 计算每一组的轮廓group_,groupCnts cv2.findContours(group.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)group_ contours.sort_contours(group_,methodleft-to-right)[0]# 计算每一个组中的数字for c in group_:(x,y,w,h) cv2.boundingRect(c)digit group[y:yh,x:xw]digit cv2.resize(digit,(57,88))cv_show(digit,digit)# 计算匹配得分scores []# 在模板中计算每一个得分for (digitt,digitTempl) in digits.items():result cv2.matchTemplate(digit,digitTempl,cv2.TM_CCOEFF)(_,score,_,_) cv2.minMaxLoc(result)scores.append(score)# 获得匹配得分最适合的数字groupOutput.append(str(np.argmax(scores)))# 画出来cv2.rectangle(image,(gx-5,gy-5),(gxgw5,gygh5),(0,0,255),1)cv2.putText(image,.join(groupOutput),(gx,gy-15),cv2.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)))
cv2.imshow(Image, image)
cv2.waitKey(0)
注意事项
由于作者用于较新的PyCharm版本是2024版本它与传统的PyCharm有区分而且作者在学习过程中同样发现一些问题这个代码前面可以不用写排序而最新版本里面不知什么原因调用接口时候报错说没有这个模块函数于是作者只能将排序等需要的模块分开出来写入项目中。
结果演示 代码模块解析
1. 参数解析模块
ap argparse.ArgumentParser()
ap.add_argument(-i, --image, requiredTrue, help输入信用卡图像路径)
ap.add_argument(-t, --template, requiredTrue, help模板图像路径)
args vars(ap.parse_args())功能通过命令行参数接收输入图像和模板图像路径参数说明 -i/--image待识别的信用卡图像-t/--template数字模板图像包含0-9标准数字
PyCharm2024通过argparse模块操作命令行设置方法如下,接下来的步骤是中文展示作者PyCharm已经汉化若未汉化也可记作者选择按钮的位置点击
第一步将需要的图片存放在本人知道的文件路径
原图片如下 模板图片如下 我存放的路径如下 第二步右击项目代码选择“更多运行/调试”后在选择下拉列表中的“修改运行配置” 第三步在新打开的对话框选择“运行”栏下最后一行点击“展开” 第四步输入之前存放模板和原图片的路径 注由于作者存放图片和模板与项目同一个文件夹目录下因此可以省略具体的路径若用户存放不在同一个文件夹目录下那么需要你加上如下格式
--image
盘符:\文件夹1名称\文件夹2名称\.....\图片名称和后缀名(.png,.jpg等等)
--template
盘符:\文件夹1名称\文件夹2名称\.....\图片名称和后缀名(.png,.jpg等等)
2. 轮廓排序函数
def sort_contours(cnts, methodleft-to-right):reverse Falsei 0if method right-to-left or method bottom-to-top:reverse Trueif method top-to-bottom or method bottom-to-top:i 1boundingBoxes [cv2.boundingRect(c) for c in cnts] # 用一个最小的矩形把找到的形状包起来x,y,h,w(cnts, boundingBoxes) zip(*sorted(zip(cnts, boundingBoxes),keylambda b: b[1][i], reversereverse))return cnts, boundingBoxes功能对检测到的轮廓按空间位置排序排序逻辑 计算每个轮廓的边界框 (x,y,w,h)按method参数选择排序基准X轴或Y轴坐标支持四种排序方向左→右、右→左、上→下、下→上
3. 图像预处理模块
# 模板预处理流程
ref cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度化
ref cv2.threshold(ref,10,255,cv2.THRESH_BINARY_INV)[1] # 二值化反转关键操作 灰度转换将RGB图像转为单通道灰度图二值化通过阈值处理突出数字区域轮廓提取findContours定位每个数字的独立轮廓模板存储将0-9数字按索引存入字典digits
4. 输入图像处理流程
# 核心处理链
image resize(image, width300) # 尺寸标准化
gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 灰度化
tophat cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel) # 顶帽运算
gradx cv2.Sobel(tophat, ddepthcv2.CV_32F, dx1, dy0) # Sobel边缘检测
gradx cv2.morphologyEx(gradx, cv2.MORPH_CLOSE, rectKernel) # 闭运算处理阶段 尺寸归一化固定宽度为300像素保持比例顶帽运算突出亮色区域信用卡数字通常为亮色Sobel算子检测垂直边缘数字的竖直笔画形态学闭操作连接数字笔画形成连续区域
5. 卡号区域定位
# 数字区域筛选
for (i,c) in enumerate(cnts):(x,y,w,h) cv2.boundingRect(c)ar w / float(h) # 宽高比if 2.5 ar 4.0 and 40w55 and 10h20:locs.append((x,y,w,h)) # 保存候选区域筛选条件 宽高比 $2.5 \frac{w}{h} 4.0$信用卡数字的典型比例宽度 $40 w 55$ 像素高度 $10 h 20$ 像素 结果获得4组数字区域的坐标 locs
6. 数字识别与输出
# 模板匹配识别
for c in group_:digit cv2.resize(roi, (57,88)) # 标准化尺寸scores []for digitTempl in digits.values():score cv2.matchTemplate(digit, digitTempl, cv2.TM_CCOEFF)scores.append(score) # 存储匹配得分groupOutput.append(str(np.argmax(scores))) # 选择最高分对应数字# 可视化输出
cv2.rectangle(image, (gx-5,gy-5), (gxgw5,gygh5), (0,0,255), 1)
cv2.putText(image, .join(groupOutput), (gx,gy-15), cv2.FONT_HERSHEY_SIMPLEX, ...)
# 得到结果
output.extend(groupOutput)
# 打印结果
print(Credit Card Type: {}.format(FIRST_NUMBER[output[0]]))
print(Credit Card #: {}.format(.join(output)))
cv2.imshow(Image, image)
cv2.waitKey(0)识别流程 截取单个数字区域并缩放至模板尺寸与0-9模板进行相似度匹配TM_CCOEFF相关系数法选择最高匹配得分对应的数字 输出形式 红色矩形框标记数字组区域在区域上方显示识别出的4位数字 系统优势
形态学操作链通过顶帽、闭操作等组合优化数字区域提取动态模板匹配适应不同字体和尺寸的数字空间约束利用宽高比和尺寸过滤误检区域实时可视化各阶段结果可实时显示便于调试 该系统实现了从原始图像到卡号识别的完整流程准确率依赖模板质量和图像清晰度可通过优化预处理参数进一步提升性能。