本周文件交换精选

我们最好的用户提交

追踪图像中二进制区域的边界

布雷特本周的选择是Freeman链码, 经过Nicolas Douillet.

内容

一个新文件提示一个思维实验

我以前从未这样做过,但我决定写一下刚刚去的文件今天(正如我写这个)!我很高兴看到尼古拉斯提交的这个形象:

说实话,我从来没听说过"弗里曼链码"但我听说过很多在图像处理中,追踪二值区域的边界通常很方便——拥有选项总是一件好事。我不太熟悉尼古拉斯的工作;他的65个文件交换贡献已经下载了数千次,并获得了几个五星级的评分。那里有很多好东西,甚至一个功能我有点不怕跑。(阅读“概述”,您将理解。)

Freeman链码

就像我通常做的那样,我开始使用维基百科(我喜欢并经常支持维基百科,尽管我孩子的老师不允许他们使用这些资源),我做了一点金宝app阅读Freeman Chain Code。它基本上是二进制图像的边界跟踪压缩算法。

尼古拉斯的实现

尼古拉斯的弗里曼算法的实现没有任何MathWorks的工具箱依赖关系;它在核心matlab中运行。所以,如果你有图像处理工具箱(IPT),你需要跟踪一个单独的没有孔的二进制区域,这个函数工作得很漂亮:

% ('gear.jpg'是Nicolas与他的条目共享的文件。)我= imread (“gear.jpg”);I = imbinarize(我);[Code, row_idx0, col_idx0] = Freeman_chain_code(I, false);%注意:第二个输入参数是一个“详细”标志,触发可视化产出的百分比。(我抑制了这里的可视化,因为输出如上所示。)

图像处理工具箱

所以这是它变得更加有趣的地方。当然,有一个相同的方式生成相同的信息 - 所以我以为我会快速比较:

使用图像处理工具箱功能:

[b,l] = bwboundaries(i,8);contour2 = false(大小(l));为了i = 1:numel(B) thisB = B{ii};第1 = sub2ind(大小(L), thisB (: 1), thisB (:, 2));Contour2(第1)= 1;结尾imshow (Contour2)标题(“使用bwboundaries”

的界限相同的。(事实上,很容易验证,至少在本例中,它们,事实上,一模一样。)

定时如何比较?

我建议时间当你想要精确计算一个函数运行所需的时间时:

fcn = @()reman_chain_code(i,false);t_freeman = timitit(fcn);

定义一个函数来捕获IPT功能:

函数io = calcboundaries(i)[b,l] = bwboundaries(i,8);io = false(大小(l));为了i = 1:numel(B) thisB = B{ii};第1 = sub2ind(大小(L), thisB (: 1), thisB (:, 2));Io(第1)= 1;结尾结尾

...我们同样有:

fcn = @() calcBoundaries(I);t_IPT时间= (fcn);
> >流('Freeman: %0.5f sec;\nIPT: %0.5f sec\n',t_freeman,t_ipt)freeman:0.00024秒;IPT:0.00090秒

他们都很快。令人惊讶的是,对于该特定图像,弗里曼边界检测甚至比工具箱功能更快。(它没有近期验证bwboundaries是。)

那么更复杂的图像呢?

现在让我们把情况稍微复杂化一点。假设我们有一个二值图像包含感兴趣地区:

我= imread (“coins.png”);我= Imfill(imbinarize(i),“黑洞”);Freeman_chain_code(我,真的);

有趣的是......弗里曼链代码只返回一个轮廓 - 对于检测到的第一个区域(在Matlab Sense中)。

此外,即使您有一个单独的区域 - 但该区域有一个或多个孔(即,如果是欧拉数1),尼古拉斯的功能只会捕捉到那个地区的轮廓!

我= false (300);I(150, 150) = true;I = bwdist(我);I = I > 15 & I < 50;
[~, ~, ~, Contour] = Freeman_chain_code_modified(I, false);
Contour2 = calcBoundaries(我);次要情节(2,2,1:2);imshow (I)标题(“原始”副图(等高线)标题(等高线)'弗里曼')子图(2,2,4)imshow(contour2)标题(“bwbounaries”

我采取了修改尼古拉斯的代码来容纳多个地区的自由。(在这样做时,我在IPT中使用了一些功能!)在修改版本中,我在循环中缠绕了整个进程,并在处理后将每个ROI的像素设置为0。我还添加了“轮廓”的输出参数,因为我发现它通常是边界跟踪工作流程的最有用方面。)到底:

[Code, a, b, Contour] = Freeman_chain_code_modified(I, true);

但是即使代码现在容纳多个roi,它仍然不能工作,因为我需要它在包含漏洞的roi上。而且,修改后的Freeman代码现在是好几次了慢点bwboundaries方法。

有几点建议

谢谢,尼古拉斯,为这份提交,以及你的许多其他人!您的代码很好地实现,非常有用 - 尤其适用于那些无法访问图像处理工具箱的人,并且谁具有简单的ROI处理。一世喜欢看一个引用你的工作中引用的弗里曼的算法,我希望看到'帮助'的评论充实有点搞清楚了,以帮助你的文件用户。最后,如果您将包含在输出列表中的“轮廓”包含“轮廓”,则会有用。(虽然这对任何人来说都很容易修改。)尽管如此,真正的扎实工作:思想挑衅,非常感谢!

一如既往,我欢迎你的想法和意见




MATLAB®R2020b发布

|
  • 打印
  • 发送电子邮件

评论

请点击留下评论在这里登录到你的MathWorks帐户或创建一个新的。