OpenCV 3.0中的活动轮廓模型

时间:2015-10-01 18:34:39

标签: c++ matlab opencv contour

我试图在C ++中使用Opencv 3.0实现Active Contour Models算法。 这个算法基于我为MatLab编写的脚本,并没有按预期工作。 这两个图像显示了两种算法运行的结果。

MatLab脚本:

和OpenCV:

在他们两个中我对所有ACM参数使用相同的值,因此它们应该返回相同的东西,即白色圆形轮廓。 我怀疑这个问题是我的图像能量函数,因为opencv和matlab中的梯度运算是不一样的。图像能量的matlab脚本是:

ProgramGroups

在C ++中我的功能如下:

Program

有谁知道可能出错了什么?

1 个答案:

答案 0 :(得分:2)

正如David Doria所说,经过一些修正之后,这是函数get_eext的最终版本。这个版本对我来说很好。

Mat config_eext(float wl, float we, float wt, Mat image)
{
Mat eline, gradx, grady, img_gray, eedge;

//bitdepth defined as CV_32F
image.convertTo(img_gray, bitdepth);

//Convolution Kernels
Mat m1, m2, m3, m4, m5;
m1 = (Mat_<float>(1, 2) << 1, -1);
m2 = (Mat_<float>(2, 1) << 1, -1);
m3 = (Mat_<float>(1, 3) << 1, -2, 1);
m4 = (Mat_<float>(3, 1) << 1, -2, 1);
m5 = (Mat_<float>(2, 2) << 1, -1, -1, 1);

img_gray.copyTo(eline);

//Kernels de gradiente
Mat kernelx = (Mat_<float>(1, 3) << -1, 0, 1);
Mat kernely = (Mat_<float>(3, 1) << -1, 0, 1);

//Gradiente em x e em y
filter2D(img_gray, gradx, -1, kernelx);
filter2D(img_gray, grady, -1, kernely);

//Edge Energy como definido por Kass
eedge = -1 * (gradx.mul(gradx) + grady.mul(grady));

//Termination Energy Convolution
Mat cx, cy, cxx, cyy, cxy, eterm(img_gray.rows, img_gray.cols, bitdepth), cxm1, den, cxcx, cxcxm1, cxcxcy, cxcycxy, cycycxx;
filter2D(img_gray, cx, bitdepth, m1);
filter2D(img_gray, cy, bitdepth, m2);
filter2D(img_gray, cxx, bitdepth, m3);
filter2D(img_gray, cyy, bitdepth, m4);
filter2D(img_gray, cxy, bitdepth, m5);

//element wise operations to find Eterm
cxcx = cx.mul(cx);
cxcx.convertTo(cxcxm1, -1, 1, 1);
den = cxcxm1 + cy.mul(cy);
cv::pow(den, 1.5, den);
cxcxcy = cxcx.mul(cy);
cxcycxy = cx.mul(cy);
cxcycxy = cxcycxy.mul(cxy);
cycycxx = cy.mul(cy);
cycycxx = cycycxx.mul(cxx);
eterm = (cxcxcy - 2 * cxcycxy + cycycxx);
cv::divide(eterm, den, eterm, -1);

//Image energy
Mat eext;
eext = wl*eline + we*eedge + wt*eterm;
return eext;
}

希望它有所帮助!