Mar*_*sin 2 c++ algorithm opencv
我实际上正在进行头侧轮廓检测.当照片拍摄在白墙前时,我决定在用阈值处理的图片上运行蛇(活动轮廓模型算法).
问题是蛇不适合鼻子,嘴巴和嘴巴下方(正如你在下面的图片中看到的那样).
//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);
Run Code Online (Sandbox Code Playgroud)
我试图更改alpha/beta/gamma参数或迭代次数,但我没有找到比下面的输出显示更好的结果.我无法理解为什么鼻子被割伤,嘴巴不适合嘴巴.我猜测曲率有足够的点,但仍有一些线由几个(> 2)点组成.
输入图片:

输出蛇:
蓝色:手工设置的点数
绿色:输出蛇

任何帮助或想法将非常感激.谢谢 !
典型的蛇形或活动轮廓算法在3种成本函数之间进行权衡:边缘强度/距离(数据项),间距和平滑度(先前项).您可能会立即注意到与"鼻子问题"有关 - 鼻子有高曲率.你的蛇也有进入凹陷区域的麻烦,因为与凸起的船体相比,它肯定会增加其曲率.
解决方案:
A.由于你的蛇的性能并不比一个凸壳更好,作为补救措施之一,我将使用更简单的凸壳算法,然后在其倒置残差上重新运行.它将得到一个正确的鼻子,然后凹陷将变成残差中的凸起.或者你可以使用openCV的凸性缺陷函数而不是使用convexHull.
B.另一种修复方法可以是减少蛇形曲率参数,使其能够在鼻子周围急剧弯曲.由于你几乎没有噪音,你可以实际清理一下,我发现没有强制执行某些限制的问题,而不是做出"更软"的权衡.也许头部轮廓先前模型也可以在这里帮助.
下面我尝试使用各种距离变换和距离参数的权重来编写我自己的蛇算法.结论 - 参数比距离度量更重要并且确实有一定的效果(左图使用的参数小于右图,因此更多地削减了鼻子).轮廓(红色)的距离用灰色表示,蛇是绿色.
C.由于你的背景几乎是纯色,所以要花点时间来清理一些残留的噪音(使用形态操作或连接组件),然后只需找到干净轮廓的对象().我在下面实现了最后一个解决方案:第一个图像删除了噪声,第二个图像只是openCV的轮廓函数.

小智 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作为最后一个参数.
我希望它可以帮到你.祝好运!