我不知道有什么功能可以完全满足您的要求。如果您没有提供要卷积的点掩码,而是提供了点列表。 [(7, 7), (100, 100)] 那么它可能就像获取适当的图像补丁一样简单(比如与您提供的内核大小相同),将图像补丁和内核卷积,然后插入回原始图像。
这是一个编码示例,希望它足够接近您可以轻松修改:
[编辑:我注意到我在填充和补丁算术中遇到了几个错误。以前,你不能与边界上的一个点(比如 (0, 0))进行卷积,我将填充加倍,修复了一些算术,现在一切都很好。]
import cv2
import numpy as np
from scipy import ndimage
from matplotlib import pyplot as plt
def image_convolve_mask(image, list_points, kernel):
# list_points ex. [(7, 7), (100, 100)]
# assuming kernels of dims 2n+1 x 2n+1
rows, cols = image.shape
k_rows, k_cols = kernel.shape
r_pad = int(k_rows/2)
c_pad = int(k_cols/2)
# zero-pad the image in case desired point is close to border
padded_image = np.zeros((rows + 2*k_rows, cols + 2*k_cols))
# set the original image in the center
padded_image[k_rows: rows + k_rows, k_cols: cols + k_cols] = image
# should you prefer to use np.pad:
# padded_image = np.pad(image, (k_rows, k_cols), 'constant', constant_values=(0, 0))
for p in list_points:
# extract pertinent patch from image
# arbitrarily choosing the patch as same size as the kernel; change as needed
patch = padded_image[p[0] + k_rows - r_pad: p[0] + 2*k_rows - r_pad, p[1] + k_cols - c_pad: p[1] + 2*k_cols - c_pad]
# here use whatever function for convolution; I prefer cv2filter2D()
# commented out is another option
# conv = ndimage.convolve(patch, kernel, mode='constant', cval=0.0)
conv = cv2.filter2D(patch, -1, kernel)
# set the convolved patch back in to the image
padded_image[p[0] + k_rows - r_pad: p[0] + 2*k_rows - r_pad, p[1] + k_cols - c_pad: p[1] + 2*k_cols - c_pad] = conv
return padded_image[k_rows: rows + k_rows, k_cols: cols + k_cols]
现在在图片上试用一下:
penguins = cv2.imread('penguins.png', 0)
kernel = np.ones((5,5),np.float32)/25
# kernel = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]], np.float32)
conv_image = image_convolve_mask(penguins, [(7, 7), (36, 192), (48, 207)], kernel)
plt.imshow(conv_image, cmap = 'gray', interpolation = 'bicubic')
plt.xticks([]), plt.yticks([])
plt.show()
我应用了一个 5x5 的平滑器,在像素 (7, 7) 周围看不到任何变化,但我选择了另外两个点作为最左边的两个企鹅喙的尖端。所以你可以看到平滑的补丁。
这是一个 lena512 图像,有 21 个卷积点(时间:0.006177 秒)。
[编辑 2:使用掩码生成行列表的示例,用于输入函数的集合元组。]
mask = np.eye(512)
k = np.ones((25, 25), np.float32)/625
list_mask = zip(np.where(mask==1)[0], np.where(mask==1)[1])
tic = time.time()
conv_image = image_convolve_mask(lena, list_mask, k)
print 'time: ', time.time()-tic # 0.08136 sec