使用 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()
我收集了大量像这样的二进制图像:
在每张图片上,我需要检测白色矩形。这些矩形具有不同的尺寸和方向,有时它们被黑线打断(见图 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()