微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

对 XArray 中图像堆栈中的每个图像应用函数

如何解决对 XArray 中图像堆栈中的每个图像应用函数

我有一堆图片,比如说

import dask.array as da
import xarray as xr
import numpy as np

img_stack =  xr.DataArray(
    da.from_array(np.random.random((5,100,100))),dims=('t','x','y'),coords={'t':range(5),'x':range(100),'y':range(100)}
)

一个函数

def filter(patch,N=3):
    print(patch.shape)
    return signal.convolve2d(
           patch,(1 / (N * N)) * np.ones((N,N)),boundary="symm",mode="same")

我想对堆栈中的每个图像应用此函数(沿 t 维度)。

我认为最好的方法是使用 apply_ufunc 并且当 dask 未启用时我可以这样做:

xr.apply_ufunc(
    filter,img_stack.load(),input_core_dims=[['y','x']],output_core_dims=[['y',vectorize=True)

这很好用,我得到了想要的结果。过滤器接收一个 (100,100) 数组。

但如果我允许 dask

xr.apply_ufunc(
    filter,img_stack,vectorize=True,dask='allowed')

我得到了一个 ValueError: convolve2d inputs must both be 2D arrays

注意:在这种情况下,我没有 load() 数据集。如果您已经通过执行前一个代码块加载了数据集,则最好通过运行第一个代码块来重新初始化 img_stack 变量。

发送到 filter 函数的数组的形状为 (5,100),而不是前一种情况中的 (100,100),因此我遇到了错误(因为该方法需要一个 {{ 1}} 数组)。不知道为什么会发生这种情况,或者我可以做些什么来对堆栈中的 5 个图像中的每一个应用 m X n 函数

我想知道这样做的最佳方法是什么,以及我是否正确应用了 filter

解决方法

问题在于您指定了 dask="allowed",它告诉 xarray 您的函数可以本机处理 dask 数组 - 在您的情况下它不能。

documentation states

dask ({"forbidden","allowed","parallelized"},默认: "forbidden") – 如何处理应用到表单中包含惰性数据的对象 dask 数组:

‘forbidden’(默认):如果遇到 dask 数组,则引发错误。

‘allowed’:将 dask 数组直接传递给 func。首选此选项,如果 func 本身支持 dask 数组。

‘parallelized’:如果有任何输入,则自动并行化 func 是使用 dask.array.apply_gufunc 的 dask 数组。多路输出 支持论据。仅当 func 没有时才使用此选项 原生支持 dask 数组(例如将它们转换为 numpy 数组)。

所以你需要设置 dask="parallelized",如果你这样做,你的例子会起作用。

请注意,使用 vectorize=True 效果很好,但它不是最高效的解决方案 - 特别是当您的数据集变大时。 如果您关心性能问题,请考虑使用 numab.guvectorize 将您的函数应用于 3d 数组的每个 1d 元素,例如 lengthy xarray example

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。