实验目的:提取银行卡数字
等待输入(Your DataSet)
输入加载完成(Update Status)
图像CV展示失败
问题解决Easy
边缘识别算法: def extract_card_number(image_path): img = cv2.imread(image_path) if img is None: print(f"无法读取图片: {image_path}") return None # 预处理(缩放到合适宽度) h, w = img.shape[:2] if w > 1000: scale = 800 / w new_w = 800 new_h = int(h * scale) img = cv2.resize(img, (new_w, new_h)) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 形态学操作 + Sobel 边缘检测 rect_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3)) tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rect_kernel) gradX = cv2.Sobel(tophat, cv2.CV_32F, dx=1, dy=0, ksize=-1) gradX = np.absolute(gradX) gradX = (255 * ((gradX - gradX.min()) / (gradX.max() - gradX.min()))).astype("uint8") gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rect_kernel) thresh = cv2.threshold(gradX, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1] thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, rect_kernel) # 寻找卡号区域轮廓 cnts, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) candidates = [] for c in cnts: x, y, w, h = cv2.boundingRect(c) ar = w / float(h) if ar > 2.5 and ar < 7.0 and w > 100: candidates.append((x, y, w, h)) if not candidates: print("未找到卡号区域") return None # 合并相邻区域 candidates = sorted(candidates, key=lambda b: b[0]) merged = [] for (x, y, w, h) in candidates: if not merged: merged.append([x, y, w, h]) else: last = merged[-1] if x - (last[0] + last[2]) < 20: last[2] = x + w - last[0] last[3] = max(last[3], h) last[1] = min(last[1], y) else: merged.append([x, y, w, h]) # 取面积最大的区域 card_roi = max(merged, key=lambda b: b[2] * b[3]) x, y, w, h = card_roi x = max(0, x - 10) y = max(0, y - 10) w = min(img.shape[1] - x, w + 20) h = min(img.shape[0] - y, h + 20) roi = img[y:y+h, x:x+w] # OCR 识别 roi_gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY) roi_thresh = cv2.threshold(roi_gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1] custom_config = r'--oem 3 --psm 8 -c tessedit_char_whitelist=0123456789' text = pytesseract.image_to_string(roi_thresh, config=custom_config) card_number = re.sub(r'\D', '', text) # 格式化输出 if len(card_number) >= 16: formatted = ' '.join([card_number[i:i+4] for i in range(0, 16, 4)]) print(f"识别的银行卡号:{formatted}") else: print(f"识别的银行卡号(未完整):{card_number}") return card_number银行卡号提取:33(未完整)/待调整
45min训练到此为止,后续更。
保存收工,还有其他活要干!
参考文章
CSDN博主:m沐沐.【计算机视觉】OpenCV 模板匹配银行卡数字识别---上(2026-06-11)[2026-06-12].https://blog.csdn.net/m0_66822255/article/details/161901272