繁体   English   中英

如何在Python中使用VIPS执行逻辑操作和逻辑索引?

[英]How to perform logical operation and logical indexing using VIPS in Python?

我有以下使用Python和OpenCV的代码。 简要地说,我有一堆在不同焦深下拍摄的图像。 代码在所有焦深(z)中挑选出在高斯响应的拉普拉斯算子最大的每个(x,y)位置上的像素,从而创建一个焦点堆叠图像。 函数get_fmap创建一个2d数组,其中每个像素将包含具有最大对数响应的焦平面数。 在以下代码中,被注释掉的行是我当前的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

log_responsefmap在问题代码中初始化为3D数组,而问题文本指出输出fmap是2D数组。 因此,我假设将log_responsefmap初始化为形状与每个图像相同的2D数组。 因此,修改将是-

log_response = np.zeros_like(img[:,:,0], dtype='single')
fmap = np.zeros_like(img[:,:,0], dtype='uint8')

现在,回到问题的主题,您正在对每个图像进行一对一的2D过滤,并获得所有堆叠图像上已过滤输出的最大索引。 如果您不了解cv2.filter2D的文档, cv2.filter2D它也可以用于多维数组,从而为我们提供多维数组作为输出。 然后,获取所有图像的最大索引就像.argmax(2)一样简单。 因此,实施必须非常高效,并且将简单地-

fmap = cv2.filter2D(img,-1,log_kernel).argmax(2)

在查阅了Python VIPS手册并经过反复试验后,我想出了自己的答案。 我有问题的numpy和OpenCV实现可以这样转换为VIPS:

import pyvips

img = []
for ii in range(num_z_levels):
    img.append(pyvips.Image.new_from_file("testimg_z" + str(ii) + ".tif")

def get_fmap(img)
    log_kernel = get_log_kernel(11,2)  # get_log_kernel is my own function, which generates a 2-d numpy array.
    log_kernel = [list(row) for row in log_kernel]  # pyvips.Image.new_from_array takes 1-d list array.
    log_kernel = pyvips.Image.new_from_array(log_kernel)  # Turn the kernel into Vips array so it can be used by Vips.
    log_response = img[0].conv(log_kernel)

    for ii in range(len(img)):
        img_filtered = img[ii+1].conv(log_kernel)
        log_response = (img_filtered > log_response).ifthenelse(img_filtered, log_response)
        fmap = (img_filtered > log_response).ifthenelse(ii+1, 0)

逻辑索引是通过ifthenelse方法实现的:

result_img = (test_condition).ifthenelse(value_if_true, value_if_false)

语法相当灵活。 测试条件可以是两个相同大小的图像之间的比较,也可以是一个图像和一个值之间的比较,例如img1 > img2img > 5 同样,value_if_true可以是单个值或Vips图像。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM