OpenCV:检测清晰描绘的对象边界失败

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

我有以下图片:

我想检测图像中放在桌子上的文档的边缘。我尝试了以下代码(早期的方法已被注释掉)。

def detectDocEdge(imagePath):
    image = loadImage(imagePath)
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    # Approach 1
    # equalized_image = cv2.equalizeHist(gray_image)
    # blurred = cv2.GaussianBlur(equalized_image, (15, 15), 0)  # TODO: May not be required
    # edges = cv2.Canny(blurred, 5, 150, apertureSize=3)
    # kernel = np.ones((15, 15), np.uint8)
    # dilated_edges = cv2.dilate(edges, kernel, iterations=1)

    # Approach 2
    # blurred = cv2.GaussianBlur(gray_image, (5, 5), 0)
    # thresh = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)
    # kernel = np.ones((5, 5), np.uint8)
    # dilated_edges = cv2.dilate(thresh, kernel, iterations=1)

    # Approach 3
    # Apply morphological operations
    # kernel = np.ones((3, 3), np.uint8)
    # closed_image = cv2.morphologyEx(thresholded_image, cv2.MORPH_CLOSE, kernel)

    # Approach 4
    blurred = cv2.GaussianBlur(gray_image, (5, 5), 0)
    edges = cv2.Canny(blurred, 50, 150)
    dilated = cv2.dilate(edges, None, iterations=5)
    eroded = cv2.erode(dilated, None, iterations=5)

    contours, hierarchy = cv2.findContours(eroded, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    contour_img = image.copy()
    cv2.drawContours(contour_img, contours, -1, (0, 255, 0), 2)
    showImage(contour_img)

    max_contour = None
    max_measure = 0  # This could be area or combination of area and perimeter
    max_area = 0

    for contour in contours:
        area = cv2.contourArea(contour)
        perimeter = cv2.arcLength(contour, True)

        # Here we use a combination of area and perimeter to select the contour
        measure = area + perimeter  # You can also try different combinations

        # if measure > max_measure:
        #     max_measure = measure
        #     max_contour = contour

        if area > max_area:
            max_area = area
            max_contour = contour

    contour_img = image.copy()
    cv2.drawContours(contour_img, [max_contour], -1, (0, 255, 0), 2)
    showImage(contour_img)

这些方法似乎都不起作用,我总是得到以下优势:

您能提出修复建议吗?我需要代码尽可能通用,以便它可以在尽可能多的条件下检测文档边缘。

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

我可以通过缩小图像并放大轮廓来获得文档周围的轮廓。

import cv2
import numpy as np

def detectDocEdge(imagePath):
    image = cv2.imread(imagePath, cv2.IMREAD_COLOR)

    scale_factor = .25
    small_image = cv2.resize(image, None, fx=scale_factor, fy=scale_factor)
    gray = cv2.cvtColor(small_image, cv2.COLOR_BGR2GRAY)
    edges = cv2.Canny(gray, 50, 150)
    kernel = np.ones((5, 5), np.uint8)
    edges = cv2.dilate(edges, kernel, iterations=1)
    contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    contour = sorted(contours, key=cv2.contourArea, reverse=True)[0]
    contour[:, :, 0] = contour[:, :, 0] / scale_factor
    contour[:, :, 1] = contour[:, :,  1] / scale_factor

    contour_img = image.copy()
    cv2.drawContours(contour_img, [contour], -1, (0, 255, 0), 10)
    cv2.namedWindow('Image', cv2.WINDOW_NORMAL)
    cv2.imshow('Image', contour_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
© www.soinside.com 2019 - 2024. All rights reserved.