如何使用OpenCV-Python识别扫描身份证图像的四边形边界
OpenCV-Python 识别扫描身份证四边形区域解决方案

以下是可直接运行的实现方案,可根据实际扫描场景调整参数优化准确率:
- 步骤1:图像预处理,降噪并提取边缘
import cv2 import numpy as np # 读取扫描图像 img = cv2.imread("scan_id_card.jpg") # 统一缩放尺寸,降低后续计算量 scale = 500 / img.shape[0] img_resize = cv2.resize(img, (0, 0), fx=scale, fy=scale) # 转灰度+高斯模糊降噪,避免误检边缘 gray = cv2.cvtColor(img_resize, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(gray, (5, 5), 0) # Canny边缘检测 edged = cv2.Canny(blur, threshold1=75, threshold2=200)
- 步骤2:轮廓筛选,定位身份证四边形外轮廓
# 提取所有外层轮廓 contours, _ = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 按轮廓面积从大到小排序,取面积最大的前5个轮廓排查 contours = sorted(contours, key=cv2.contourArea, reverse=True)[:5] card_contour = None for c in contours: perimeter = cv2.arcLength(c, closed=True) # 轮廓多边形近似,0.02*perimeter为近似精度,可根据图像清晰度调整 approx = cv2.approxPolyDP(c, epsilon=0.02*perimeter, closed=True) # 身份证为矩形,近似后为4个顶点 if len(approx) == 4: card_contour = approx break
- 步骤3:透视变换,提取校正后的身份证区域
# 顶点坐标重排序:左上、右上、右下、左下 def order_points(pts): rect = np.zeros((4, 2), dtype="float32") s = pts.sum(axis=1) rect[0] = pts[np.argmin(s)] rect[2] = pts[np.argmax(s)] diff = np.diff(pts, axis=1) rect[1] = pts[np.argmin(diff)] rect[3] = pts[np.argmax(diff)] return rect # 透视变换实现图像校正 def four_point_transform(origin_img, pts, scale): rect = order_points(pts.reshape(4, 2)) / scale (tl, tr, br, bl) = rect # 计算校正后图像的宽高 max_width = max(int(np.sqrt(((br[0] - bl[0])**2) + ((br[1] - bl[1])**2))), int(np.sqrt(((tr[0] - tl[0])**2) + ((tr[1] - tl[1])**2)))) max_height = max(int(np.sqrt(((tr[0] - br[0])**2) + ((tr[1] - br[1])**2))), int(np.sqrt(((tl[0] - bl[0])**2) + ((tl[1] - bl[1])**2)))) # 目标坐标映射 dst = np.array([[0, 0], [max_width-1, 0], [max_width-1, max_height-1], [0, max_height-1]], dtype="float32") # 计算变换矩阵并执行透视变换 M = cv2.getPerspectiveTransform(rect, dst) warped = cv2.warpPerspective(origin_img, M, (max_width, max_height)) return warped if card_contour is not None: result_id_card = four_point_transform(img, card_contour, scale) cv2.imwrite("extracted_id_card.jpg", result_id_card)
- 优化适配建议
- 若扫描图像存在严重反光,可先执行自适应阈值处理或直方图均衡化,再做边缘检测
- 若背景干扰较多,可先通过HSV颜色空间筛选身份证的底色范围,缩小检测区域
- 可加入宽高比校验:二代身份证宽高比约为1.58:1,符合该比例的轮廓再判定为身份证,可大幅降低误检率
- 图像清晰度较低时,可适当调大轮廓近似的精度参数,避免识别到过多细碎边缘
内容的提问来源于stack exchange,提问作者Buoy Rina
相关产品推荐
相关产品推荐

