如何在此类图像中找到最大的空白空间?

Posted

技术标签:

【中文标题】如何在此类图像中找到最大的空白空间?【英文标题】:How do I find the largest empty space in such images? 【发布时间】:2021-07-28 22:33:55 【问题描述】:

我想在类似于我在下面发布的图像中找到空白区域(黑色区域),我在其中散布了随机大小的块。

通过空格,我指的是这种可能的开放领域(我对该区域没有特别的下限,但我想提取图像中存在的前 3-4 个最大的区域。)也没有限制它们可以采用的几何形状,但这些空白区域不得包含任何蓝色块。

最好的方法是什么?

到目前为止我做了什么:

我的原始图像实际上是这样的。我确定了所有点,根据一定的距离阈值对它们进行分组,并在它们周围应用了一个凸包。我不确定如何进一步进行。任何帮助将不胜感激。谢谢!

【问题讨论】:

类似dl.acm.org/doi/10.1145/323233.323255 ? 是的,类似的,但我的近似结果在我的情况下是可以的。 我解释一下,但你写了类似的东西,“对于黑色斑点的几何形状没有没有限制,只要黑色斑点blobs do not contain a blue blob" 如果你想找到最大的不包含任何蓝色的黑色 blob,那么只需取整个黑色区域。整个黑色背景是一个非常奇怪的形状,但它肯定没有蓝色。如果没有限制,则允许将黑色的东西视为所有一种形状。我认为您确实对允许使用的几何形状有限制,但您不知道如何表达这些限制。 如果你正在寻找凸形,这个问题被称为“凸头骨”,目前已知最好的解决方案是 O(n^7),其中 n 是输入多边形中的顶点数.我认为您最好使用 fmw42 答案中的循环假设。 @VS:您对 Samuel 问题的回答并没有真正回答它,因为现在我可以问,“整个黑色区域 减去左上角像素 怎么样? "等等,等等。您需要描述一个允许区域的类别,以便给定任意区域的程序可以确定该区域是否被允许。一个典型的例子可能是“只允许凸多边形”(除非这不是你想要的,因为你的例子包含非凸多边形)。另外,我不清楚您所说的“有界”是什么意思。 【参考方案1】:

这是 Python/OpenCV 中使用距离变换找到 X 之间的最大欧几里得距离的一种方法。

输入:

import cv2
import numpy as np
import skimage.exposure

# read image
img = cv2.imread('xxx.png')

# convert to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# threshold to binary and invert so background is white and xxx are black
thresh = cv2.threshold(gray, 128, 255, cv2.THRESH_BINARY)[1]
thresh = 255 - thresh

# add black border around threshold image to avoid corner being largest distance
thresh2 = cv2.copyMakeBorder(thresh, 1,1,1,1, cv2.BORDER_CONSTANT, (0))
h, w = thresh2.shape

# create zeros mask 2 pixels larger in each dimension
mask = np.zeros([h + 2, w + 2], np.uint8)

# apply distance transform
distimg = thresh2.copy()
distimg = cv2.distanceTransform(distimg, cv2.DIST_L2, 5)

# remove excess border
distimg = distimg[1:h-1, 1:w-1]

# get max value and location in distance image
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(distimg)

# scale distance image for viewing
distimg = skimage.exposure.rescale_intensity(distimg, in_range='image', out_range=(0,255))
distimg = distimg.astype(np.uint8)

# draw circle on input
result = img.copy()
centx = max_loc[0]
centy = max_loc[1]
radius = int(max_val)
cv2.circle(result, (centx, centy), radius, (0,0,255), 1)
print('center x,y:', max_loc,'center radius:', max_val)

# save image
cv2.imwrite('xxx_distance.png',distimg)
cv2.imwrite('xxx_radius.png',result)

# show the images
cv2.imshow("thresh", thresh)
cv2.imshow("thresh2", thresh2)
cv2.imshow("distance", distimg)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

距离变换图像:

到Xs距离最大的区域:

文字信息:

中心 x,y:(179, 352) 半径:92.5286865234375

【讨论】:

它们看起来有点像 Voronoi 图,我想这不是巧合吗? 正确。从文档中,“该函数提供了一种非常快速的方法来计算二进制图像的 Voronoi 图”。见docs.opencv.org/4.1.1/d7/d1b/…。但在距离图像中,您必须对局部最大值进行阈值处理才能获得 Voronoi 图像边缘

以上是关于如何在此类图像中找到最大的空白空间?的主要内容,如果未能解决你的问题,请参考以下文章

如何在opencv中找到图像的最大和最小亮度值?

寻找局部最大值灰度图像opencv

如何让 QTableWidget 的列占据最大空间?

如何找到联系人图像支持的最大图像大小?

如何在 Swift 中找到 Double 和 Float 的最大值

如何使用python OpenCV在单通道图像中找到与特定值匹配的最大连通分量?