python - 边缘检测最小线长?
问题描述
我试图从我精明的边缘检测中过滤掉短线。这是我目前正在使用的内容以及简要说明:
我首先获取图像的单个通道并运行 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)
源图像:
解决方案
您正在应用的操作称为区域打开。我认为 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)
。
推荐阅读
- r - 在 R 中调整 Shiny 中的绘图和数据表布局;更新绘图和数据表后保持对齐
- ruby-on-rails - how can call rails service in vue
- r - 为什么 R 表示的数字比文本文件中给出的“精度更高”?
- amazon-web-services - 如何修复 S3 存储桶和 SQS 之间的循环依赖关系?
- javascript - 对 Vue 3 中数组中的对象属性更改做出反应
- python - 在python中跟踪视频中的选定点
- netsuite - “请输入金额的值。” 在美国境外创建具有自定义价格水平的折扣发票时
- google-sheets - 如何仅获得两个重复值之一
- visual-studio-code - Vscode用“ctrl-click”打开文件和相对路径
- c++ - 检测到堆损坏(动态数组)