Snake算法 - opencv活动轮廓 - 工作不太好

时间:2013-07-09 01:06:11

标签: c++ algorithm opencv

我实际上正在进行头侧轮廓检测。当照片拍摄在白墙前时,我决定对使用阈值处理的照片运行snake(活动轮廓模型算法)。

问题是蛇不适合鼻子,嘴巴和口腔下方(如下图所示)。

//load file from disk and apply threshold
IplImage* img = cvLoadImage (file.c_str (), 0);
cvThreshold(img, img, 170, 255, CV_THRESH_BINARY);

float alpha = 0.1; // Weight of continuity energy
float beta = 0.5; // Weight of curvature energy
float gamma = 0.4; // Weight of image energy

CvSize size; // Size of neighborhood of every point used to search the minimumm have to be odd
size.width = 5;
size.height = 5;

CvTermCriteria criteria;
criteria.type = CV_TERMCRIT_ITER;  // terminate processing after X iteration
criteria.max_iter = 10000; 
criteria.epsilon = 0.1;

// snake is an array of cpt=40 points, read from a file, set by hand
cvSnakeImage(img, snake, cpt, &alpha, &beta, &gamma, CV_VALUE, size, criteria, 0);

我尝试更改alpha / beta / gamma参数或迭代次数,但我没有找到比下面的输出更好的结果。我无法理解为什么鼻子被割伤,嘴巴不适合嘴巴。我猜测曲率有足够的分数,但仍有一些线条由几个(> 2)点组成。

输入图片 Input Image - threshold

输出Snake:

  • 蓝色:手工设定的点数

  • 绿色:输出蛇

OutputSnake

非常感谢任何帮助或想法。 谢谢!

4 个答案:

答案 0 :(得分:7)

典型的蛇形或活动轮廓算法在3种成本函数之间进行权衡:边缘强度/距离(数据项),间距和平滑度(先前项)。您可能会立即注意到与“鼻子问题”有关 - 鼻子有高曲率。你的蛇也有进入凹陷区域的麻烦,因为与凸起的船体相比,这肯定会增加它的曲率。

解:
答:由于你的蛇的性能并不比一个凸包更好,作为补救措施之一,我将采用更简单的凸壳算法,然后在其倒置残差上重新运行。它将得到一个正确的鼻子,然后凹陷将变成残差中的凸起。或者您可以使用openCV的凸性缺陷函数,而不是使用convexHull

B中。另一个修复方法可以是减少蛇形曲率参数,使其能够在鼻子周围急剧弯曲。由于你几乎没有噪音,你可以实际清理一下,我发现没有强制执行某些限制的问题,而不是做出“更软”的权衡。也许头部轮廓先前模型也可以在这里帮助。

下面我尝试使用各种距离变换和距离参数的权重来编写自己的蛇算法。结论 - 参数比距离度量更重要并且确实有一定的效果(左图使用的参数小于右图,因此更多地削减了鼻子)。轮廓(红色)的距离用灰色显示,蛇是绿色。

enter image description here left

℃。由于你的背景几乎是纯色,所以要花一点时间来清理一些残留的噪音(使用形态操作或连接的组件),只需要清洁轮廓的findContrours()。我在下面实现了最后一个解决方案:第一个图像删除了噪声,第二个图像只是openCV的轮廓函数。 enter image description here enter image description here

答案 1 :(得分:5)

如果你想自己实施,我推荐论文“你一直想要关于蛇的一切(但不敢问)”,作者:Jim Ivins和John Porrill。

关于OpenCV的实现,我不太了解,但我建议你:

  • 减少beta,使曲率更强

  • 检查图像能量。也许函数(方案)的最后一个参数是错误的。有两个可能的值:_CV_SNAKE_IMAGE和_CV_SNAKE_GRAD。你把它设置为0,如果我没错,我认为0意味着_CV_SNAKE_IMAGE。因此,该函数将假设输入图像是能量图像。同样,我不确定OpenCV如何实现此功能,但我认为当您使用_CV_SNAKE_IMAGE时,该函数假定输入图像是渐变模块图像。在你的情况下,它可以使蛇避免黑色区域(解释为低梯度模块)并寻找明亮区域。因此,尝试使用_CV_SNAKE_GRAD作为最后一个参数。

我希望它可以帮到你。祝你好运!

答案 2 :(得分:0)

自从我研究了活动轮廓的OpenCV实现以来已经有一段时间了,但是如果我没记错的话,它是使用贪婪算法来实现能量最小化(Williams等人)。此外,外力有一些改进,通常是边缘信息的改进,例如,改进了蛇的收敛性。梯度矢量流场蛇(GVF)。 GVF外力被建模为液体扩散过程,以允许菱形(蛇元素)在较高曲率和向内凹的区域中流向图像边缘。当进行主动轮廓绘制时,我建议采用从粗到细的方法,即通常将高级过程(人或其他分割过程)用作初始snaxel位置的种子,然后进行蛇形变形过程作为划定ROI边界的一种好方法。在诸如医学图像分析的应用中,这种方法是可以接受的,甚至是可取的。与水平集类似的另一种良好的蛇算法是Chan-Vese主动轮廓,没有边缘模型,绝对值得一试,在Matlab网上有很多例子。

答案 3 :(得分:-2)

活跃的轮廓只是糟糕的时期。看起来最大流量最小切割可以轻松解决这种图像分割问题。

我知道这是在前一段时间被问到的,但我总体上对活动轮廓感到愤怒。这个页面是谷歌的热门歌曲之一,我想很多人会阅读这篇文章,希望有人可以通过pdes做一些有用的轮廓演变。

事实是,活动轮廓需要大量的人为干预,然后它只有在你有不自然的边缘强度或非常高的对比度时才有效。

如果您的博士或博士后有兴趣 - 我求求您找到别的东西。我保证一个令人震惊的结果。虽然有一些看似很好的轮廓模型,但源代码永远不可用 - 例如,在一个级别集中的通用gvf。

所有(二进制)分段问题都可以分解为有向图 - 您未来的雇主和审查员会感谢我。我劝你不要在活动轮廓上浪费时间。