Python图像处理:从电子显微镜中测量层宽度

3

我有一张电子显微镜图像,展示了生物系统中密集和稀疏层,如下所示。

VDTap.png

这里涉及的层位于图像中间,从标签“re”附近开始,逐渐向左上方变细。我想要做到以下两点:
1)统计黑暗/密集和明亮/稀疏层的总数
2)测量每层的宽度,给定右下角的黑色比例尺为1微米长
我一直在尝试用Python完成这个任务。如果我预先裁剪图像,只包含几个层的部分,例如这里显示的3个黑暗和3个明亮的层:

test.png

我可以使用以下代码计算层数:

import numpy as np
import matplotlib.pyplot as plt
from scipy import ndimage
from PIL import Image

tap = Image.open("VDtap.png").convert('L')
tap_a = np.array(tap)

tap_g = ndimage.gaussian_filter(tap_a, 1)
tap_norm = (tap_g - tap_g.min())/(float(tap_g.max()) - tap_g.min())
tap_norm[tap_norm < 0.5] = 0
tap_norm[tap_norm >= 0.5] = 1

result = 255 - (tap_norm * 255).astype(np.uint8)

tap_labeled, count = ndimage.label(result)

plt.imshow(tap_labeled)
plt.show()

然而,我不确定如何加入比例尺并测量我已经计算过的这些层的宽度。更糟糕的是,当分析整个图像以包括比例尺时,我甚至无法将这些层与图像中正在发生的其他事情区分开来。我非常感谢任何解决这个问题的见解。提前致谢。
编辑1:
到目前为止,我在这个问题上取得了一些进展。如果我事先裁剪图像,只包含一点点的层,我已经能够使用以下代码获取每个层的厚度。
import numpy as np
import matplotlib.pyplot as plt
from scipy import ndimage
from PIL import Image
from skimage.measure import regionprops

tap = Image.open("VDtap.png").convert('L')
tap_a = np.array(tap)

tap_g = ndimage.gaussian_filter(tap_a, 1)
tap_norm = (tap_g - tap_g.min())/(float(tap_g.max()) - tap_g.min())
tap_norm[tap_norm < 0.5] = 0
tap_norm[tap_norm >= 0.5] = 1

result = 255 - (tap_norm * 255).astype(np.uint8)

tap_labeled, count = ndimage.label(result)

props = regionprops(tap_labeled)
ds = np.array([])

for i in xrange(len(props)):
    if i==0:
        ds = np.append(ds, props[i].bbox[1] - 0)
    else:
        ds = np.append(ds, props[i].bbox[1] - props[i-1].bbox[3])

    ds = np.append(ds, props[i].bbox[3] - props[i].bbox[1])

基本上,我发现了Python模块skimage,它可以取一个标记的图像数组并返回每个已标记对象的边界框的四个坐标。1 和 [3] 位置给出了边界框的 x 坐标,因此它们的差异确定了每个层在 x 方向上的范围。此外,for 循环的第一部分(if-else 条件语句)用于获取在每个黑暗/密集层之前的轻/稀层,因为只有黑暗层被 ndimage.label 标记。

不幸的是,这仍然不理想。首先,我希望不必预先裁剪图像,因为我打算对许多这样的图像重复此过程。我考虑到也许可以使用某种滤波器来突出层的(粗略的)周期性,但我不确定是否存在这样的滤波器?其次,上面的代码实际上只给出了每个层的相对宽度 - 我还没有找到一种方法来结合比例尺以获得实际宽度。

1个回答

0

我不想打扰你,但我认为你的问题比你最初想象的要难。由于您发布的内容中有很多部分需要深入注意,因此我无法发布可工作的代码片段。我曾在几个生物/医学实验室工作过,这项工作通常是人工标记特定图像点,并使用计算机计算距离。话虽如此,人们可能应该尝试自动化=D。

对于您来说,这个问题是一个简单但繁琐的工作,需要用尺子做几百次测量。这对计算机来说很完美,对吗?好吧,是和不是。计算机不知道如何识别图片中的任何带状物,必须被告知确切地寻找什么,而这将是棘手的。

识别比例尺

您了解所有图像中的比例尺吗?它们总是具有相同数量的垂直和水平图像吗?它们总是纯黑色的吗?总是只有一根条形码吗(那字母r的实线呢)?我的建议是尝试小波变换。想象一下函数的二维类比情况。

(可能有助于绘制此函数) f(x)=     如果| x | > 1,那么为0,     如果| x | <1 && | x |> 0.5,则为1     如果| x | <0.5,则为-1
然后,当我们的小波f(x,y)在图像上卷积时,输出图像仅在找到黑色刻度尺时才具有高值。还可以调整我设置为1的长度以适应小波,这也将帮助您找到比例尺。

查找脊线

首先解决上述问题,因为它似乎更容易,并为此设置了一个框架。对于这个问题,我会构建另一个小波,但只是作为预处理步骤。对于这个小波,我会再次尝试2d 0-sum框函数,但这次尝试将三个(或更多)相邻的框匹配在一起。除了框的高度和宽度参数之外,我们还需要间距和倾斜角度参数。您可能不必非常接近实际值,只要足够接近,使其余部分变黑即可。

测量脊线

有很多方法可以做到这一点,但为了简单起见,让我们使用之前的步骤。取出你的三个盒子小波响应,并将其居中于中央脊线,报告一个“宽度”值,该值是其捕获的这三个脊线的平均宽度。考虑到这些宽度变化缓慢,这样做可能已经足够接近了!

祝你好运!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接