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