无法在Python中使用openCV2正确裁剪

问题描述 投票:0回答:1

我想从扫描件上剪下身份证 example german id 请注意,id 下有很多空白(直到这里)

首先,我对图像进行预处理:

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

然后我用它来裁剪图像:

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

但是,生成的裁剪图像如下所示:(我添加了一个我想要裁剪的红色矩形) enter image description here

我尝试删除/更改预处理步骤中的一些步骤,但无济于事。

python opencv computer-vision crop
1个回答
0
投票

问题是您感兴趣的对象连接到左上角的黑色角。 这已经发生在 cv2.equalizeHist() 步骤中:

import matplotlib.pyplot as plt
plt.imshow(equalized)
plt.axis('off')
plt.show()

equalized image

只需忽略该步骤并采用第二大轮廓即可完成工作:

denoised = cv2.fastNlMeansDenoising(gray, None, h=20, templateWindowSize=7, searchWindowSize=21)

# ...

preprocessed_image = adaptive_thresh

#sort by area
contours = cv2.findContours(preprocessed_image, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
contours = sorted(contours, key=cv2.contourArea, reverse=True)

#select 2nd largest contour
x,y,w,h = cv2.boundingRect(contours[1])

cropped_image=original_image[y:y+h,x:x+w]

#display cropped image
plt.imshow(cropped_image)
plt.axis('off')
plt.show()

#display the respective contour
cv2.drawContours(original_image, [contours[1]], -1, (0, 255, 0), 20)
plt.imshow(original_image)
plt.axis('off')
plt.show()

裁剪后的图像:

cropped image

感兴趣的轮廓:

2nd largest contours

© www.soinside.com 2019 - 2024. All rights reserved.