对于这个问题,这里有一个简单而幼稚的解决方案.它使用UnquoteQuote中提到的2D卷积.
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()
该算法可以找到所有可能的解决方案.如果你只需要一个,你可以优化它,使它得到一个随机的(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 is the solution
与卷积相比,这种方法要快得多(但这取决于解的数量):
6.65 s ± 21.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
1.31 ms ± 31.2 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)