使用 Python 检测图像中的矩形

Detect rectangles in an image with Python

我收集了大量像这样的二进制图像:

在每张图片上,我需要检测白色矩形。这些矩形具有不同的尺寸和方向,有时它们被黑线打断(见图 2)。

我觉得如果能把嘈杂的背景去掉,这个问题就很容易解决了。 因此,我首先尝试使用 OpenCV 的 filter2D 函数:

import cv2

img = cv2.imread(file_name)
mean_filter_kernel = np.ones((5,5),np.float32)/(5*5)
filtered_image = cv2.filter2D(image,-1,mean_filter_kernel)

但这似乎没有任何效果,可能是因为我处理的不是灰度图像。

接下来我想到检测轮廓并将所有尺寸较小的轮廓填充为黑色:

import cv2

img = cv2.imread(file_name)
blurred = cv2.GaussianBlur(img, (5, 5), 0)
canny = cv2.Canny(blurred, 100, 50)
contours, _ = cv2.findContours(canny, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

for cnt in contours:
    area = cv2.contourArea(cnt)
    if area > 1000:
        continue
    cv2.drawContours(img, [cnt], -1, 0, -1)
    

这有助于消除噪音,但远非完美。

有没有人知道如何改进我的方法,或者有没有办法在不去除背景噪音的情况下直接检测矩形?

应用多重过滤、边缘检测和阈值处理会给您一个可接受的结果,您可以使用形态学或一些数学来确定矩形的角和角度来改进结果。

import numpy as np
import matplotlib.pyplot as plt
from skimage.io import imread
from skimage.filters import median, gaussian, threshold_otsu, sobel
from skimage.morphology import binary_erosion

orig = imread('4.png',as_gray=True)
img = orig.copy()
img[img<1] = 0

gauss = gaussian(img, sigma=3)

SE = np.ones((7,7))
med = median(gauss, selem=SE)

edges = sobel(med)

thresh = threshold_otsu(edges)
binary = edges > thresh

SE2 = np.ones((3,3))
result = binary_erosion(binary, selem=SE2)

plt.subplot(121)
plt.imshow(orig, cmap='gray')
plt.axis('off')
plt.subplot(122)
plt.imshow(result, cmap='gray')
plt.axis('off')
plt.show()