Python中使用OpenCV无法正确裁剪身份证扫描件的问题求助
Python中使用OpenCV无法正确裁剪身份证扫描件的问题求助
大家好,我最近在处理身份证扫描件的裁剪任务,想把扫描图里的身份证单独裁出来,但扫描件下方有一大片空白区域,目前写的代码没能正确识别身份证的边界,裁剪结果不符合预期。
先给大家看下原始的扫描件:
原始扫描件:画面上方是身份证,下方延伸出大量空白区域的扫描图像
我先写了一个预处理图像的函数,用来增强图像特征,方便后续轮廓检测:
def preprocess_before_crop_2(scan_path, output_dir): # Read the image original_image = cv2.imread(scan_path) # Grayscale gray = cv2.cvtColor(original_image, cv2.COLOR_BGR2GRAY) # Histogram Equalization on grayscale image equalized = cv2.equalizeHist(gray) # Initial Denoising denoised = cv2.fastNlMeansDenoising(equalized, None, h=20, templateWindowSize=7, searchWindowSize=21) # Sharpening kernel kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]]) sharpened = cv2.filter2D(denoised, -1, kernel) # Bilateral filter bilateral_filtered = cv2.bilateralFilter(sharpened, d=9, sigmaColor=75, sigmaSpace=75) # Increase Contrast clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) contrast = clahe.apply(bilateral_filtered) # Apply slight Gaussian blur before binarization for anti-aliasing blurred = cv2.GaussianBlur(contrast, (3, 3), 0) # Binary conversion with Otsu's thresholding _, binary = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # Adaptive thresholding adaptive_thresh = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2) return adaptive_thresh
接着是裁剪用的函数,思路是通过轮廓检测找到最大的符合宽高比的 bounding box,然后裁剪:
def crop_document(scan_path, output_dir): original_image = cv2.imread(scan_path) # preprocess image preprocessed_image = preprocess_before_crop(scan_path, output_dir) contours, hierarchy = cv2.findContours(preprocessed_image,cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) # Find object with the biggest bounding box mx = (0,0,0,0) # biggest bounding box so far mx_area = 0 areas = [] for cont in contours: x,y,w,h = cv2.boundingRect(cont) area = w*h ratio = float(w) / float(h) areas.append((area,ratio)) if area > mx_area and ratio > 1: mx = x,y,w,h mx_area = area x,y,w,h = mx # Crop and save cropped_image=original_image[y:y+h,x:x+w] return cropped_image
但现在的问题是,裁剪出来的区域不对,我用红色框在结果图里标出了真正想要裁剪的范围——应该是完整的身份证,但目前代码裁出来的部分没覆盖全身份证,或者说没正确识别它的边界。
裁剪结果图:当前裁剪出的区域不符合预期,红色矩形标注了目标的身份证完整区域
我试过调整预处理步骤,比如去掉一些滤波步骤、更换阈值方法,但都没能解决问题,想请教下各位有没有什么改进的思路?
另外补充一下,这是我最初上传的原始扫描件,避免大家混淆:
原始扫描件(补充版):包含身份证和下方空白区域的完整扫描图
备注:内容来源于stack exchange,提问作者Selphiron




