3

我面临一个我无法解决的众所周知的问题。我有根的图片(http://cl.ly/image/2W3C0a3X0a3Y)。从这张照片中,我想知道最长根的长度(第一个问题),大根和小根的百分比(例如作为第二个问题的方向的直径)。重要的是我可以区分细根和大根,因为这或多或少是研究的目的(其中一部分在不同物种之间进行比较)。最后一件事,我想沿着测量的最长根画一条线,以检查一切是否正确测量。

对于最长根的长度,我尝试使用 regionprops(),这不是最优的,因为如果我做对了,它假定椭圆作为基本形状。然而,我真正需要支持的事情实际上是:

如何获得最长根的长度(起点应该是最长根离开直径最大的主根的地方)?是否可以区分细根和大根,我可以得到它们的一部分吗?(硬币,图片中的圆形物体是参考)我可以在图片中绘制长度和直径等属性吗?

我发现了如何绘制椭圆和东西的质心,但我只是不明白如何使用建议的值来做到这一点。

我希望这不是双重帖子,并且这个问题在其他地方不存在这样的问题,如果是,我很抱歉。

我要感谢这个论坛上的人们,你们做得很好,每个有问题的人都可以很幸运有你们在这里。

谢谢你的帮助,菲利普

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% 编辑

我遵循了建议的解决方案,到目前为止的代码如下:

clc
clear all
close all

img=imread('root_test.jpg');

labTransformation = makecform('srgb2lab');
labI = applycform(img,labTransformation);

%seperate l,a,b
l = labI(:,:,1);
a = labI(:,:,2);
b = labI(:,:,3);

level = graythresh(l);
bw = im2bw(l);
bw = ~bw;
bw = bwareaopen(bw, 200);
se = strel('disk', 5);
bw2=imdilate(bw, se);
bw2 = imfill(bw2, 'holes');
bw3 =bwmorph(bw2, 'thin', 5);
bw3=double(bw3);
I4 = bwmorph(bw3, 'skel', 200);
%se = strel('disk', 10);%this step is for better visibility of the line
%bw4=imdilate(I4, se);
D = bwdist(I4);

这导致我的骨架图片 - 这是一个很大的进步,谢谢你!在我必须计算距离的地方,我有点过分了。我如何解释 MatLab 它必须计算从所有小根到主根的距离(如何定义?)?为此,我必须先处理直径,对吗?

您能否给出一个或另一个提示更多如何完成距离/长度问题?

感谢您提供的大力帮助!

菲利普

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% EDIT2

好的,我设法分离了单个根部分。这不是您的编辑建议的内容,但至少是一些内容。我也有所有根的总长度 - 还不错。但即使有(我假设)超级简单的逐步解释,我也从未见过这样的树。我停在我必须选择一个不可见点的地方——其余的对我来说太先进了。我不想浪费更多的时间,我非常感谢你已经给我的帮助。但我想我太愚蠢了,无法做到这一点:) 谢谢!继续这样下去,真的很有帮助。

菲利普

4

1 回答 1

7

对于一个预先开始的点,我认为该图像不需要 3439x2439 的分辨率,它似乎没有为问题添加任何重要的东西,所以我只是使用了调整大小的 800x567 版本(尽管应该(几乎)将此答案应用于较大版本没有问题)。另外,您提到regionprops但我没有看到有关您如何获得二进制图像的任何描述,所以让我们从头开始。

我在 LAB 颜色空间中考虑了您的图像,然后通过 Otsu 对 L 通道进行了二值化,考虑到前景为黑色,对此结果应用了膨胀(同样可以通过应用侵蚀来完成),最后删除了小组件。与更直接的亮度公式相比,L 通道可以更好地表示图像,从而更容易分割。膨胀(或腐蚀)是为了加入次要特征,因为有相当多的分支似乎无关紧要。这产生了以下图像:

在此处输入图像描述

在这一点上,我们可以尝试将距离变换与灰色调锚定骨架结合使用(参见 Soille 关于形态学的书,和/或 Ranwez 和 Soille 的“Order Independent Homotopic Thinning for Binary and Gray Tone Anchored Skeletons”)。但是,由于后者不容易获得,我会在这里考虑一些更简单的东西。如果我们在上图中执行孔填充,然后进行细化和修剪,我们会得到许多根之间连接的粗略草图。下图显示了由原始图像组成的这一步的结果(为了更好的可视化而放大):

在此处输入图像描述

正如预期的那样,由于孔填充,变薄的图像采用“捷径”。但是,如果不执行这样的步骤,那么我们最终会在这个图像中出现循环——这是我想在这里避免的。尽管如此,它似乎为实际根的大小提供了一个不错的近似值。

现在我们需要计算分支(或根)的大小。首先要确定主根在哪里。这可以通过在膨胀之前使用上面的二进制图像并考虑距离变换来完成,但这不会在这里完成——我的兴趣只是展示了计算这些长度的可行性。假设你知道你的主根在哪里,我们需要找到从给定根到它的路径,然后这条路径的大小就是这个根的大小。观察到,如果我们从细化图像中消除分支点,我们会得到一组很好的连接组件:

在此处输入图像描述

假设每个端点是一个根的末端,那么一个根的大小就是到主根的最短路径,并且该路径由刚刚显示的图像中的一组连通分量组成。现在您可以找到最大的、第二大的以及所有其他可以通过此过程计算的。

编辑:

为了使最后一步清楚,首先让我们标记所有找到的分支(在新选项卡中打开图像以获得更好的可视化):

在此处输入图像描述

现在,每个分支的“数字”长度只是组件中的像素数量。您可以稍后通过考虑添加到图像中的对象将此值转换为“真实世界”长度。请注意,此时根本不需要依赖图像处理算法,我们可以从这个表示构造一棵树并在那里工作。树的构建方式如下: 1) 在骨架中找到属于主根的分支点(这是上图中标签 15、16 和 17 之间的“不可见点”);2)创建从该点到连接到它的每个分支的边;3)根据直到另一个分支开始所需的像素数量为边缘分配权重;4)重复新的起始分支。例如,在初始点,到达分支 15、16 和 17 的开头需要 0 个像素。然后,要从分支 15 的开头到达其结尾,它需要分支 15 的大小(像素数)。此时我们在这条路径上没有其他东西可以访问,所以我们创建了一个叶子节点。对所有其他分支重复相同的过程。例如,这是该标记的完整树(以下树的双重表示更节省空间):

在此处输入图像描述

现在你找到了最大的加权路径——它对应于最大根的大小——等等。

于 2013-01-29T05:15:03.380 回答