首页 文章

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

提问于
浏览
2

我实际上正在进行头侧轮廓检测 . 当照片拍摄在白墙前时,我决定在用阈值处理的图片上运行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 :
Input Image - threshold

Output Snake :

  • 蓝色:手动设定点数

  • 绿色:输出蛇

OutputSnake

任何帮助或想法将非常感激 . 谢谢 !

4 回答

  • 0

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

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

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

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

    enter image description here

    left

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

    enter image description here

  • 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

    自从我研究了活动轮廓的OpenCV实现以来已经有一段时间了,但是如果我正确地回想起它,那就是使用贪婪算法进行能量最小化(Williams等人) . 此外,对外力有若干改进,通常是改善蛇收敛的边缘信息,例如,梯度矢量流场蛇(GVF) . GVF外力被建模为液体扩散过程,以允许snaxels(蛇形元素)在更高曲率和向内凹陷的区域中朝向图像边缘流动 . 当主动轮廓时,我会建议粗到精的方法,即通常是高级过程(人或其他分割过程)将作为最初的snaxel位置的种子,然后,蛇形变形过程将作为描绘ROI边界的一种很好的方式 . 在医学图像分析等应用中,这种方法是可以接受的,甚至是可取的 . 另一个好的蛇算法是水平集的亲戚将是没有边缘模型的Chan-Vese活动轮廓,绝对值得一试,并且在Matlab中有几个漂浮在互联网上的例子 .

  • 7

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

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

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

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

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

相关问题