实施脊线检测
我正在尝试编写一个脊检测算法,并且我发现的所有来源似乎都将边缘检测与脊检测混为一谈。 现在,我已经实现了 Canny 边缘检测算法,但这不是我想要的:例如,给定图像中的一条线,它将有效地将其转换为双线边缘(因为它将记录 该行的两侧) - 我只想让它读取一行。
关于山脊检测的 wikipedia 文章 有很多数学知识,但是这种没有帮助我作为一名程序员(并不是说我不喜欢数学,而是这不是我的领域,而且我不明白如何将他们的微分方程转化为代码)。 是否有实际实施此功能的良好来源? 或者,就此而言,是否有一个好的开源实现?
编辑:这是一个简单的例子。 我们从简单的一行开始:
http://img24.imageshack.us/img24/ 8112/linez.th.png
并运行Canny算法得到:
http://img12.imageshack.us/img12/1317/canny.th.png
(你可以看到这里更厚 - 如果你点击图片,你会发现它确实是两个相邻的行,中间有一个空格)
另外,我正在用 C++ 编写,但这并不重要。 但我想编写算法,而不仅仅是编写SomePackage::findRidges()
并完成它。
I'm trying to write a ridge detection algorithm, and all of the sources I've found seem to conflate edge detection with ridge detection. Right now, I've implemented the Canny edge detection algorithm, but it's not what I want: for example, given a single line in the image, it will effectively translate it to a double line of edges (since it will record both sides of the line) - I just want it to read the one line.
The wikipedia article about ridge detection has a bunch of math, but this kind of this doesn't help me as a programmer (not that I'm averse to math, but it's not my field, and I don't understand how to translate their differential equations into code). Is there a good source for actually implementing this? Or, for that matter, is there a good open source implementation?
Edit: here's the simple example. We start with a simple line:
http://img24.imageshack.us/img24/8112/linez.th.png
and run the Canny Algorithm to get:
http://img12.imageshack.us/img12/1317/canny.th.png
(you can see that it's thicker here - if you click on the image, you'll see that it really is two adjacent lines with a blank in between)
Also, I'm writing in C++, but that shouldn't really matter. But I want to code the algorithm, not just write SomePackage::findRidges()
and be done with it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
也许您需要考虑清理已有的线路,而不是像 Canny 那样的边缘检测。 感觉你应该能够使用图像形态学做一些事情,特别是我正在考虑骨架化和最终侵蚀点类型操作。 正确使用这些应该从您的图像中删除任何非“线条”的特征 - 我相信它们是在英特尔的 OpenCV 库中实现的。
您可以从使用 Canny 过滤器生成的双线中恢复单线,使用一次扩张操作,然后进行 3 次侵蚀(我在 ImageJ 中尝试过) - 这也应该删除任何边缘。
Maybe you need to think in terms of cleaning up the line you already have, rather than a Canny-like edge detection. It feels like you should be able to do something with image morphology, in particular I'm thinking of the skeletonize and ultimate eroded points type operations. Used appropriately these should remove from your image any features which are not 'lines' - I believe they're implemented in Intel's OpenCV library.
You can recover a single line from your double line generated using the Canny filter using one dilate operation followed by 3 erodes (I tried it out in ImageJ) - this should also remove any edges.
我本来建议像 Ian 所说的那样清理你的线条,但如果你不想这样做,你也可以考虑做一些霍夫变换的变体。
http://en.wikipedia.org/wiki/Hough_transform
您应该能够获得这条线的实际方程,因此您可以根据需要将其设置为细或粗。 唯一棘手的部分是弄清楚线的终点在哪里。
这是我几年前用 MATLAB 编写的霍夫变换代码。 我不确定它的效果如何,但它应该给你一个总体的想法。 它将找到图像中的所有线条(不是线段)
I was going to suggest cleaning up your lines like Ian said, but if you don't want to do that, you might also look into doing some variant of a hough transform.
http://en.wikipedia.org/wiki/Hough_transform
You should be able to get the actual equation for the line from this, so you can make it as thin or as thick as you like. The only tricky part is figuring out where the line ends.
Here's the code I wrote for a hough transform a few years ago, written in MATLAB. I'm not sure how well it works anymore, but it should give you a general idea. It will find all the lines (not segments) in an image
如果有人仍然对此感兴趣,这里是脊/谷算法的实现: C++ 源代码。 查找名为
get_ridges_or_valleys()
的函数。 此实现是 Linderhed (2009) 提出的算法的 3D 版本。 有关脊/谷算法,请参阅论文第 8 页。If anyone is still interested in this, here is an implementation of the ridges/valleys algorithm: C++ source code. Look for a function called
get_ridges_or_valleys()
. This implementation is a 3D version of the algorithm proposed by Linderhed (2009). See page 8 of the paper for the ridges/valleys algorithm.