繁体   English   中英

由Xarray中的一系列坐标定义的多边形3D蒙版

[英]3D mask from polygon defined by series of coordinates in Xarray

背景:

我正在使用Xarray分析医学影像和区域定义的轮廓。 我的xarray是像素值的3D数组,其坐标由患者坐标系(x,y,z)定义,单位为mm。

我有一系列坐标(以x,y,z表示),它们定义了复杂多边形的顶点。 它是一个元组列表,其中每个列表定义了z平面中的所有顶点。 例如

[[(x1, y1, z1),..(xN, yN, z1)], [(x1, y1, z2),..(xM, yM, z2)], ...]

我做了一个数字,但我的医院已禁止访问我尝试过的每个图像共享网站。 抱歉。

帮助请求:

我想为这些多边形坐标定义的区域创建一个遮罩。 我很难弄清楚该怎么做。 指导将不胜感激!

这是一些玩具代码说明:

pixel_data = np.ones((5,5,5))
x_coords = np.arange(2.4, 7.4, 1)
y_coords = np.arange(-3.6, 1.4, 1)
z_coords = np.arange(202.7, 207.7, 1)[::-1]
coords = {'x': x_coords, 'y': y_coords, 'z': z_coords}

example = xr.DataArray(pixel_data, dims=('y','x','z'), coords=coords)

数组:

<xarray.DataArray (y: 5, x: 5, z: 5)>
    array([[[1., 1., 1., 1., 1.],
            [1., 1., 1., 1., 1.],
            [1., 1., 1., 1., 1.],
            [1., 1., 1., 1., 1.],
            [1., 1., 1., 1., 1.]],
                  ...

Coordinates:
* x        (x) float64 2.4 3.4 4.4 5.4 6.4
* y        (y) float64 -3.6 -2.6 -1.6 -0.6 0.4
* z        (z) float64 206.7 205.7 204.7 203.7 202.7

contours = [[(2.4, -3.6, 203.7),(3.4, 0.4, 203.7),(6.4, -1.6, 203.7)],
            [(2.4, -2.6, 204.7),(4.4, 0.4, 204.7),(6.4, -3.6, 204.7)]]

每个元组中的x,y和z坐标将始终与我的数据数组中的x,y,z坐标完全匹配。

好吧,我想我明白了。 不知道这是否是最好的方法。 欢迎提出建议。

需要构造一个由顶点坐标定义的多边形,必须将其转换为x,y维度中的索引坐标。 构造完多边形后,分配遮罩值相对简单。 见下文:

from PIL import Image, ImageDraw
import xarray as xr
import numpy as np

pixel_data = np.ones((5,5,5))
x_coords = np.arange(2.4, 7.4, 1)
y_coords = np.arange(-3.6, 1.4, 1)
z_coords = np.arange(202.7, 207.7, 1)[::-1]
coords = {'x': x_coords, 'y': y_coords, 'z': z_coords}

example = xr.DataArray(pixel_data, dims=('y','x','z'), coords=coords)

contours = [[(2.4, -3.6, 203.7),(3.4, 0.4, 203.7),(6.4, -1.6, 203.7)],
            [(2.4, -2.6, 204.7),(4.4, 0.4, 204.7),(6.4, -3.6, 204.7)]]

def create_mask(array, contour_list):
    'Takes in an Array we want to mask, and a contour'
    'coordinate nested list.'
    mask_array = xr.zeros_like(array)
    slice_dict = {}
    mask_dict = {}

    for i, coord in enumerate(contour_list):
        'Each list inside contour_list is a list of (x,y,z)'
        'coordinates defining the contour on each slice. For each'
        'sequence, the z coord is constant. This for-loop builds'
        'a numpy array for each series of (x,y) coordinates and'
        'stores them in a dict where the corresponding key is the'
        'z-coordinate.'
        x_start = float(example.x[0].values)
        y_start = float(example.y[0].values)
        spacing = float(example.x[0].values) - float(example.x[1].values)
        resized = np.resize(coord, (int(np.size(coord) / 3), 3))
        rtstruct_pixelArray = (resized[:,:2] - [x_start, y_start]) / spacing
        rtstruct_pixelArray = np.rint(rtstruct_pixelArray)
        slice_dict[coord[0][2]] = rtstruct_pixelArray


    for z_slc in slice_dict.keys():
        'For each z-slice, we need to draw a polygon defined by'
        'the points we pulled above. We can do this with ImageDraw.'
        polygon = slice_dict[z_slc].flatten().tolist()
        img = Image.new('L', (example.shape[0], example.shape[1]), 0)
        ImageDraw.Draw(img).polygon(polygon, outline=255, fill=255)
        mask = np.array(img)
        mask_dict[z_slc] = mask

    for z_slc in mask_dict.keys():
        'We can reassign values in mask_array with indexing.'
        'We rely on sel to give us the slice we need. This works'
        'because xarray does not copy the data with sel.'
        mask_slice = mask_array.sel(z=z_slc, method='nearest')
        mask_slice[:,:] = mask_dict[z_slc]

    return mask_array

mask = create_mask(example, contours)

这是一个最低限度的工作示例!

暂无
暂无

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

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