与使用Matlab版本

时间:2017-08-14 22:17:40

标签: c++ matlab opencv image-processing

我目前正致力于将Matlab版本的活动轮廓转换为OpenCV。似乎OpenCV有自己版本的活动轮廓,但是当时不推荐使用。我很好奇这个版本与Matlab版本有多么不同。所以我做了一个比较实验。给定MRI脑图像和初始边界,我应用Matlab和OpenCV版本活动轮廓来分割脑中的白质。

对于Matlab和OpenCV,我选择活动轮廓的渐变(边缘)方法。然后我在图像上标记了结果。红色曲线是初始边界,而绿色曲线是最终边界。

Matlab代码是:

clear
clc
I = imread('brain.png');
IMaskS = imread('shrinkMask.png');

figure(1)
imshow(I)
hold on
visboundaries( IMaskS, 'color', 'r'); 
bwSnake = activecontour(I,  IMaskS, 250, 'edge','ContractionBias',-0.45,'SmoothFactor',0.7);
finalBoundary = bwboundaries(bwSnake);
visboundaries(finalBoundary, 'color', 'g');

enter image description here

在选择合适的参数时,Matlab似乎做得非常好。 " ContractionBias"参数(参考here)对于控制曲线缩小或扩展非常有用。

然而,OpenCV版本的活动轮廓似乎根本不起作用。我使用滑块来更改参数alpha,beta和gamma,但无法获得下降结果。无论我如何设置参数,似乎曲线都不会扩展。我使用OpenCV 2.4.13.3,活动轮廓可以在遗留文件夹中找到snakes.cpp。 Chek OpenCV github或更具体地snakes.cpp。 OpenCV测试代码是:

#include <iostream>
#include "opencv2/core.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/legacy/legacy.hpp"


using namespace std;
using namespace cv;

IplImage *image = 0; 
IplImage *image2 = 0; 
IplImage *imageMask = 0;
using namespace std;

int ialpha = 10;
int ibeta = 40;
int igamma = 50;


void onChange(int pos)
{

    if (image2) cvReleaseImage(&image2);
    if (image) cvReleaseImage(&image);
    if (imageMask) cvReleaseImage(&imageMask);

    image2 = cvLoadImage("brain.png", 1); 
    image = cvLoadImage("brain.png", 0);
    imageMask = cvLoadImage("shrinkMask.png", 0);



    CvMemStorage* storage = cvCreateMemStorage(0);
    CvSeq* contours = 0;

    cvFindContours(imageMask, storage, &contours, sizeof(CvContour),
        CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);


    if (!contours) return;
    int length = contours->total;
    if (length<10) return;
    CvPoint* point = new CvPoint[length]; 

    CvSeqReader reader;
    CvPoint pt = cvPoint(0, 0);;
    CvSeq *contour2 = contours;

    cvStartReadSeq(contour2, &reader);
    for (int i = 0; i < length; i++)
    {
        CV_READ_SEQ_ELEM(pt, reader);
        point[i] = pt;
    }
    cvReleaseMemStorage(&storage);


    for (int i = 0; i<length; i++)
    {
        int j = (i + 1) % length;
        cvLine(image2, point[i], point[j], CV_RGB(255, 0, 0), 1, 8, 0);
    }

    float alpha = ialpha / 100.0f;
    float beta = ibeta / 100.0f;
    float gamma = igamma / 100.0f;

    CvSize size;
    size.width = 3;
    size.height = 3;
    CvTermCriteria criteria;
    criteria.type = CV_TERMCRIT_ITER;
    criteria.max_iter = 500;
    criteria.epsilon = 0.1;
    cvSnakeImage(image, point, length, &alpha, &beta, &gamma, CV_VALUE, size, criteria, 1);


    for (int i = 0; i<length; i++)
    {
        int j = (i + 1) % length;
        cvLine(image2, point[i], point[j], CV_RGB(0, 255, 0), 1, 8, 0);
    }
    delete[]point;

}

int main(int argc, char* argv[])
{


    cvNamedWindow("win1", 0);
    cvCreateTrackbar("alpha", "win1", &ialpha, 100, onChange);
    cvCreateTrackbar("beta", "win1", &ibeta, 100, onChange);
    cvCreateTrackbar("gamma", "win1", &igamma, 100, onChange);
    //cvResizeWindow("win1", 696, 520);
    cvResizeWindow("win1", 256, 256);
    onChange(0);

    for (;;)
    {
        if (cvWaitKey(40) == 27) break;
        cvShowImage("win1", image2);
    }

    return 0;
}

enter image description here

我做错了什么或者OpenCV中这个版本的活动轮廓完全没用?我检查了snake.cpp,OpenCV版本活动轮廓的源代码,它似乎是基于论文理论实现的。由于文件保护,我无法访问Matlab版本的活动轮廓。因此,我无法直接比较它们。从最终开始,我将使用OpenCV来实现内容,任何改进或更改我的OpenCV代码的建议都将受到赞赏。

我附上了原始图片和面具,以防有人想重复测试。

谢谢!

Brain Image Mask

0 个答案:

没有答案