我有以下图片:
我想检测图像中放在桌子上的文档的边缘。我尝试了以下代码(早期的方法已被注释掉)。
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)
您能提出修复建议吗?我需要代码尽可能通用,以便它可以在尽可能多的条件下检测文档边缘。
我可以通过缩小图像并放大轮廓来获得文档周围的轮廓。
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()