【发布时间】:2020-05-29 04:18:57
【问题描述】:
我有随机放置矩形的二进制图像,我想获取这些矩形的位置和大小。 如果可能的话,我希望精确地重新创建图像所需的矩形数量最少。
左边是我的原图,右边是我申请scipys.find_objects()后得到的图像
(就像建议 this question 一样)。
import scipy
# image = scipy.ndimage.zoom(image, 9, order=0)
labels, n = scipy.ndimage.measurements.label(image, np.ones((3, 3)))
bboxes = scipy.ndimage.measurements.find_objects(labels)
img_new = np.zeros_like(image)
for bb in bboxes:
img_new[bb[0], bb[1]] = 1
如果矩形相距很远,这很好用,但如果它们重叠并构建更复杂的结构,这个算法只会给我最大的边界框(对图像进行上采样没有区别)。我觉得应该已经存在一个 scipy 或 opencv 方法可以做到这一点。
我很高兴知道是否有人知道如何解决这个问题,或者更了解现有的解决方案。
因此,我想要图像中的矩形列表(即左下角:右上角)。条件是,当我重绘那些填充的矩形时,我想获得与以前完全相同的图像。如果可能,矩形的数量应该最少。
这是生成示例图像的代码(以及更复杂的示例 original 与 scipy)
import numpy as np
def random_rectangle_image(grid_size, n_obstacles, rectangle_limits):
n_dim = 2
rect_pos = np.random.randint(low=0, high=grid_size-rectangle_limits[0]+1,
size=(n_obstacles, n_dim))
rect_size = np.random.randint(low=rectangle_limits[0],
high=rectangle_limits[1]+1,
size=(n_obstacles, n_dim))
# Crop rectangle size if it goes over the boundaries of the world
diff = rect_pos + rect_size
ex = np.where(diff > grid_size, True, False)
rect_size[ex] -= (diff - grid_size)[ex].astype(int)
img = np.zeros((grid_size,)*n_dim, dtype=bool)
for i in range(n_obstacles):
p_i = np.array(rect_pos[i])
ps_i = p_i + np.array(rect_size[i])
img[tuple(map(slice, p_i, ps_i))] = True
return img
img = random_rectangle_image(grid_size=64, n_obstacles=30,
rectangle_limits=[4, 10])
【问题讨论】:
-
“编写这个代码应该不会太难。”ᶜᶦᵗᵃᵗᶦᵒⁿ ⁿᵉᵉᵈᵉᵈ 右侧图中有多少个矩形,在中心左侧的重叠集中? 至少 2 -- 但也可以是 3 或 4,具体取决于您的计数方式。
-
在多次 cmets 的措辞之后好的:我希望有一个现有的算法来解决这个问题,并想问一下。如果没有,我会很乐意自己做。听起来不应该是这样的:肯定有人愚蠢(而且聪明)为我做这项工作......
-
所以基本上你要求的是找到图像中每个直线多边形的最小矩形分区。我认为这是一个众所周知的问题,如果你用谷歌搜索,你会发现很多算法。但我不认为有一个简单的解决方案。
-
您可以尝试使用 opencv blob 检测方法并针对此特定图像调整其参数。还可以考虑在应用斑点检测器之前对图像进行预处理,例如腐蚀和膨胀操作,以便更容易检测矩形。
-
我突然想到你可能想多了。一个简单的算法也可以工作:定位一个矩形的左上角,扫描它的边界,从图像中删除。重复。它将导致绘制更多矩形(用于重叠矩形),但它应该是万无一失的。
标签: python numpy image-processing scipy rectangles