首页 > 解决方案 > 边缘检测最小线长?

问题描述

我试图从我精明的边缘检测中过滤掉短线。这是我目前正在使用的内容以及简要说明:

我首先获取图像的单个通道并运行 CV2 的 Canny 边缘检测。之后,我扫描每个像素并检测它周围是否有任何白色(真,255)。如果是,我将它添加到一组真实像素中,然后检查它周围的每个像素(并继续循环直到没有白色/真实像素留下。然后如果组数较少,我将所有像素替换为黑色/错误比指定的阈值(在本例中为 100 像素)。

虽然这有效(如下所示),但速度非常慢。我想知道是否有更快,更简单的方法来做到这一点。

import cv2

img = cv2.imread("edtest.jpg")
img_r = img.copy()
img_r[:, :, 0] = 0
img_r[:, :, 1] = 0
img_r = cv2.GaussianBlur(img_r, (3, 3), 0)
basic_edge = cv2.Canny(img_r, 240, 250)

culled_edge = basic_edge.copy()
min_threshold = 100

for x in range(len(culled_edge)):
    print(x)
    for y in range(len(culled_edge[x])):
        test_pixels = [(x, y)]
        true_pixels = [(x, y)]

        while len(test_pixels) != 0:

            xorigin = test_pixels[0][0]
            yorigin = test_pixels[0][1]
            if 0 < xorigin < len(culled_edge) - 1 and 0 < yorigin < len(culled_edge[0]) - 1:
                for testx in range(3):
                    for testy in range(3):
                        if culled_edge[xorigin-1+testx][yorigin - 1 + testy] == 255 and (xorigin-1+testx, yorigin-1+testy) not in true_pixels:
                            test_pixels.append((xorigin-1+testx, yorigin-1+testy))
                            true_pixels.append((xorigin-1+testx, yorigin-1+testy))
            test_pixels.pop(0)

        if 1 < len(true_pixels) < min_threshold:
            for i in range(len(true_pixels)):
                culled_edge[true_pixels[i][0]][true_pixels[i][1]] = 0

cv2.imshow("basic_edge", basic_edge)
cv2.imshow("culled_edge", culled_edge)
cv2.waitKey(0)

源图像:

源图像

Canny 检测和过滤(理想)结果: 在此处输入图像描述

标签: pythonopencvimage-processing

解决方案


您正在应用的操作称为区域打开。我认为 OpenCV 中没有实现,但您可以在 scikit-image ( skimage.morphology.area_opening) 或 DIPlib ( dip.BinaryAreaOpening) 中找到一个。

例如,使用 DIPlib(披露:我是作者),您将修改您的代码,如下所示:

import diplib as dip

# ...
basic_edge = cv2.Canny(img_r, 240, 250)
min_threshold = 100
culled_edge = dip.BinaryAreaOpening(basic_edge > 0, min_threshold)

输出 ,culled_edge现在是一个dip.Image对象,它与 NumPy 数组兼容,您应该能够在许多情况下使用它。如果有问题,那么您可以将其转换回 NumPy 数组culled_edge = np.array(culled_edge)


推荐阅读