英文:
Find an empty space in a binary image that can fit a shape
问题
我有这张图片
我需要找到一个能容纳这个形状的空白区域
以便最终结果类似于这样
英文:
I have this image
<br>
<br>
I need to find an empty area that can fit this shape
<br>
<br>
so that the end result is something like this
<br>
答案1
得分: 2
以下是对该代码部分的翻译:
这是一个简单但天真的解决此问题的方法。正如UnquoteQuote所提到的,它使用了2D卷积。
import random
import numpy as np
import scipy.signal as sig
import matplotlib.pyplot as plt
import cv2
# 载入图像
image = (cv2.imread('image.jpg').mean(axis=2) > 127).astype(np.float32)
shape = (cv2.imread('shape.jpg').mean(axis=2) > 127).astype(np.float32)
# 执行2D卷积
conv = sig.convolve2d(image, shape, mode='valid')
solutions = np.where(conv == 0)
# 绘制一些解决方案
plt.figure(figsize=(16, 4))
for i in range(4):
r = random.randint(0, solutions[0].shape[0] - 1)
x, y = solutions[0][r], solutions[1][r]
solution_plot = np.zeros((*image.shape, 3))
solution_plot[:, :, 0] = image
solution_plot[x:x + shape.shape[0], y:y + shape.shape[1], 1] = shape
plt.subplot(1, 4, i + 1)
plt.imshow(solution_plot)
plt.show()
此算法找到了所有可能的解决方案。如果您只需要一个解决方案,可以优化它,以获取随机的(x, y)
点,并执行形状和裁剪图像区域[x:x+shape_width, y:y+shape_height]
的点积,以检查是否有空间,直到找到正确的点。
可以像这样执行:
while True:
x = random.randint(0, image.shape[0] - shape.shape[0])
y = random.randint(0, image.shape[1] - shape.shape[1])
if np.sum(shape*image[x:x + shape.shape[0], y:y + shape.shape[1]]) == 0:
break
# x, y 是解决方案
与卷积相比,这个方法要快得多(但这取决于解决方案的数量):
- 卷积:
6.65 秒 ± 21.4 毫秒每次循环(7次运行的平均值 ± 标准偏差,每次循环1次)
- 随机搜索:
1.31 毫秒 ± 31.2 微秒每次循环(7次运行的平均值 ± 标准偏差,每次循环1000次)
英文:
Here is a simple yet naive solution to this problem. It uses 2D convolution as mentioned by UnquoteQuote.
import random
import numpy as np
import scipy.signal as sig
import matplotlib.pyplot as plt
import cv2
# load images
image = (cv2.imread('image.jpg').mean(axis=2) > 127).astype(np.float32)
shape = (cv2.imread('shape.jpg').mean(axis=2) > 127).astype(np.float32)
# perform 2D convolution
conv = sig.convolve2d(image, shape, mode='valid')
solutions = np.where(conv == 0)
# draw some solutions
plt.figure(figsize=(16, 4))
for i in range(4):
r = random.randint(0, solutions[0].shape[0] - 1)
x, y = solutions[0][r], solutions[1][r]
solution_plot = np.zeros((*image.shape, 3))
solution_plot[:, :, 0] = image
solution_plot[x:x + shape.shape[0], y:y + shape.shape[1], 1] = shape
plt.subplot(1, 4, i + 1)
plt.imshow(solution_plot)
plt.show()
This algorithm finds all possible solutions. If you only need one, you can optimize it so that it gets a random (x, y)
point and perform dot product of the shape and a cropped image area [x:x+shape_width, y:y+shape_height]
to check if there is a space until you find the right point.
This can be done for example like this:
while True:
x = random.randint(0, image.shape[0] - shape.shape[0])
y = random.randint(0, image.shape[1] - shape.shape[1])
if np.sum(shape*image[x:x + shape.shape[0], y:y + shape.shape[1]]) == 0:
break
# x, y is the solution
Compared to convolution this one is much faster (but it depends on the number of the solutions):
-
convolution:
6.65 s ± 21.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
-
random search:
1.31 ms ± 31.2 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论