估计 3D 显微图像中的各向异性#

在本教程中,我们将计算 3D 图像的结构张量。有关 3D 图像处理的总体介绍,请参阅 探索 3D 图像(细胞)。我们此处使用的数据是从通过共聚焦荧光显微镜获得的肾脏组织图像中采样的(在 kidney-tissue-fluorescence.tif 下的 [1] 中有更多详细信息)。

import matplotlib.pyplot as plt
import numpy as np
import plotly.express as px
import plotly.io

from skimage import data, feature

加载图像#

此生物医学图像可通过 scikit-image 的数据注册表获得。

我们的 3D 多通道图像的形状和大小究竟是什么?

print(f'number of dimensions: {data.ndim}')
print(f'shape: {data.shape}')
print(f'dtype: {data.dtype}')
number of dimensions: 4
shape: (16, 512, 512, 3)
dtype: uint16

为了本教程的目的,我们将仅考虑第二个颜色通道,这使我们得到一个 3D 单通道图像。值的范围是多少?

n_plane, n_row, n_col, n_chan = data.shape
v_min, v_max = data[:, :, :, 1].min(), data[:, :, :, 1].max()
print(f'range: ({v_min}, {v_max})')
range: (68, 4095)

让我们可视化我们的 3D 图像的中间切片。

fig1 = px.imshow(
    data[n_plane // 2, :, :, 1],
    zmin=v_min,
    zmax=v_max,
    labels={'x': 'col', 'y': 'row', 'color': 'intensity'},
)

plotly.io.show(fig1)

让我们选择一个显示相对 X-Y 各向同性的特定区域。相比之下,沿 Z 方向的梯度差异很大(而且就此而言,很弱)。

sample = data[5:13, 380:410, 370:400, 1]
step = 3
cols = sample.shape[0] // step + 1
_, axes = plt.subplots(nrows=1, ncols=cols, figsize=(16, 8))

for it, (ax, image) in enumerate(zip(axes.flatten(), sample[::step])):
    ax.imshow(image, cmap='gray', vmin=v_min, vmax=v_max)
    ax.set_title(f'Plane = {5 + it * step}')
    ax.set_xticks([])
    ax.set_yticks([])
Plane = 5, Plane = 8, Plane = 11

要以 3D 方式查看示例数据,请运行以下代码

import plotly.graph_objects as go

(n_Z, n_Y, n_X) = sample.shape
Z, Y, X = np.mgrid[:n_Z, :n_Y, :n_X]

fig = go.Figure(
    data=go.Volume(
        x=X.flatten(),
        y=Y.flatten(),
        z=Z.flatten(),
        value=sample.flatten(),
        opacity=0.5,
        slices_z=dict(show=True, locations=[4])
    )
)
fig.show()

计算结构张量#

让我们可视化示例数据的底部切片,并确定强变化的典型大小。我们将使用此大小作为窗口函数的“宽度”。

fig2 = px.imshow(
    sample[0, :, :],
    zmin=v_min,
    zmax=v_max,
    labels={'x': 'col', 'y': 'row', 'color': 'intensity'},
    title='Interactive view of bottom slice of sample data.',
)

plotly.io.show(fig2)

在最亮区域(即,在第 22 行和第 17 列附近),我们可以看到跨列(分别为行)2 或 3 个(分别为 1 或 2 个)像素的变化(因此,是强梯度)。因此,我们可以为窗口函数选择,例如,sigma = 1.5。或者,我们可以按每个轴传递 sigma,例如,sigma = (1, 2, 3)。请注意,大小 1 在第一个(Z,平面)轴上听起来是合理的,因为后者的大小为 8 (13 - 5)。在 X-Z 或 Y-Z 平面中查看切片可以证实这是合理的。

然后,我们可以计算结构张量的特征值。

(3, 8, 30, 30)

最大特征值在哪里?

coords = np.unravel_index(eigen.argmax(), eigen.shape)
assert coords[0] == 0  # by definition
coords
(np.int64(0), np.int64(1), np.int64(22), np.int64(16))

注意

读者可以检查此结果(坐标 (plane, row, column) = coords[1:])在 sigma 变化时有多么稳健。

让我们查看在找到最大特征值的 X-Y 平面中特征值的空间分布(即,Z = coords[1])。

fig3 = px.imshow(
    eigen[:, coords[1], :, :],
    facet_col=0,
    labels={'x': 'col', 'y': 'row', 'facet_col': 'rank'},
    title=f'Eigenvalues for plane Z = {coords[1]}.',
)

plotly.io.show(fig3)

我们正在查看局部属性。让我们考虑上述 X-Y 平面中最大特征值周围的一个很小的邻域。

eigen[0, coords[1], coords[2] - 2 : coords[2] + 1, coords[3] - 2 : coords[3] + 1]
array([[0.05530323, 0.05929082, 0.06043806],
       [0.05922725, 0.06268274, 0.06354238],
       [0.06190861, 0.06685075, 0.06840962]])

如果我们检查此邻域中第二大的特征值,我们可以看到它们与最大的特征值具有相同的数量级。

eigen[1, coords[1], coords[2] - 2 : coords[2] + 1, coords[3] - 2 : coords[3] + 1]
array([[0.03577746, 0.03577334, 0.03447714],
       [0.03819524, 0.04172036, 0.04323701],
       [0.03139592, 0.03587025, 0.03913327]])

相比之下,第三大的特征值小一个数量级。

eigen[2, coords[1], coords[2] - 2 : coords[2] + 1, coords[3] - 2 : coords[3] + 1]
array([[0.00337661, 0.00306529, 0.00276288],
       [0.0041869 , 0.00397519, 0.00375595],
       [0.00479742, 0.00462116, 0.00442455]])

让我们可视化在找到最大特征值的 X-Y 平面中的示例数据切片。

fig4 = px.imshow(
    sample[coords[1], :, :],
    zmin=v_min,
    zmax=v_max,
    labels={'x': 'col', 'y': 'row', 'color': 'intensity'},
    title=f'Interactive view of plane Z = {coords[1]}.',
)

plotly.io.show(fig4)

让我们可视化在找到最大特征值的 X-Z(左)和 Y-Z(右)平面中的示例数据切片。Z 轴是下面子图中的垂直轴。我们可以看到沿 Z 轴的预期相对不变性(对应于肾脏组织中的纵向结构),尤其是在 Y-Z 平面中(纵向=1)。

subplots = np.dstack((sample[:, coords[2], :], sample[:, :, coords[3]]))
fig5 = px.imshow(
    subplots, zmin=v_min, zmax=v_max, facet_col=2, labels={'facet_col': 'longitudinal'}
)

plotly.io.show(fig5)

总而言之,体素 (plane, row, column) = coords[1:] 周围的区域在 3D 中是各向异性的:第三大特征值与最大和第二大特征值之间存在一个数量级。我们可以在图 平面 Z = 1特征值 中一目了然地看到这一点。

有问题的邻域在一个平面中“有些各向同性”(在此处,它将相对接近 X-Y 平面):第二大特征值和最大特征值之间存在小于 2 的因子。此描述与我们在图像中看到的内容兼容,即,在某个方向上(在此处,它将相对接近行轴)的梯度更强,而垂直于它的梯度更弱。

在3D结构张量的椭球表示中 [2],我们会得到薄饼状的情况。

脚本总运行时间: (0 分钟 5.435 秒)

图库由 Sphinx-Gallery 生成