我有以下使用Python和OpenCV的代码。简而言之,我有一堆在不同震源深度拍摄的图像。这些代码在所有焦深(z)中具有最大高斯拉普拉斯响应拉普拉斯位置的每个(x,y)位置挑选出像素,从而创建焦点叠加图像。函数get_fmap
创建一个2d阵列,其中每个像素将包含具有最大日志响应的焦平面的编号。在以下代码中,注释掉的行是我当前的VIPS实现。它们在函数定义中看起来不兼容,因为它只是部分解决方案。如何在Python中使用VIPS执行逻辑操作和逻辑索引?
# from gi.repository import Vips
def get_log_kernel(siz, std):
x = y = np.linspace(-siz, siz, 2*siz+1)
x, y = np.meshgrid(x, y)
arg = -(x**2 + y**2)/(2*std**2)
h = np.exp(arg)
h[h < sys.float_info.epsilon * h.max()] = 0
h = h/h.sum() if h.sum() != 0 else h
h1 = h*(x**2 + y**2 - 2*std**2)/(std**4)
return h1 - h1.mean()
def get_fmap(img): # img is a 3-d numpy array.
log_response = np.zeros_like(img[:, :, 0], dtype='single')
fmap = np.zeros_like(img[:, :, 0], dtype='uint8')
log_kernel = get_log_kernel(11, 2)
# kernel = get_log_kernel(11, 2)
# kernel = [list(row) for row in kernel]
# kernel = Vips.Image.new_from_array(kernel)
# img = Vips.new_from_file("testimg.tif")
for ii in range(img.shape[2]):
# img_filtered = img.conv(kernel)
img_filtered = cv2.filter2D(img[:, :, ii].astype('single'), -1, log_kernel)
index = img_filtered > log_response
log_response[index] = img_filtered[index]
fmap[index] = ii
return fmap
然后fmap
将被用来挑选出来自不同焦平面的像素来创建一个焦点堆栈图像
这是一个非常大的图像上完成的,而且我觉得VIPS可能做得更好比OpenCV就此。但是,官方文档仅提供有关Python绑定的信息。根据我在互联网上可以找到的信息,我只能够进行图像卷积工作(在我的情况下,它比OpenCV快一个数量级)。我想知道如何在VIPS中实现这一点,尤其是这些行?
log_response = np.zeros_like(img[:, :, 0], dtype = 'single')
index = img_filtered > log_response
log_response[index] = im_filtered[index]
fmap[index] = ii
我是vips维护者。你的代码看起来不错。你看到vips'logmat'函数了吗?它可能适合你。它创建一个日志掩码http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/libvips-create.html#vips-logmat从Python使用(例如)'Vips .Image.logmat(2,0.1)'。它会生成近似整数掩码和可分离掩码,这可以提供有用的加速。如果你愿意,你可以使用字符串'“float”'而不是'Vips.Precision.FLOAT'。 – user894763
(第2部分)你需要'索引'图像吗?我认为你可以将其重写为'fmap =(img_filtered> log_response).ifthenelse(ii + 1,0)',我可能错过了一些东西。如果你有任何可以共享的基准,我会很好奇速度和内存使用与opencv相比。 – user894763
尝试:'x = Vips.Image.logmat(2,0.1); x.matrixprint()'查看vips制作的日志文件。添加'precision =“float”'获得一个浮点版本。 – user894763