1

I am currently working on translating Matlab version active contour to OpenCV. It seems that OpenCV has its own version of active contour but deprecated then. I am curious about how different between this version with Matlab version. So I did a comparison experiment. Given a MRI brain image and an initial boundary , I applied both Matlab and OpenCV version active contour to segment the white matter in brain.

For both Matlab and OpenCV, I choose gradient(edge) method of active contour. I then labeled the results on the image. The red curve is initial boundary while the green curve is final boundary.

The Matlab code is:

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

It seems that Matlab does a really good job when choosing the appropriate parameters. The "ContractionBias" parameter (refer it here) is really useful for controlling the curve to shrink or expand.

However, the OpenCV version active contour seems doesn't work at all. I use slider bar to change the parameters alpha, beta and gamma but cannot get a descend result. It seems that the curve doesn't expand no matter how I set the parameters. I use OpenCV 2.4.13.3 and active contour can be found in legacy folder as snakes.cpp. Chek OpenCV github or more specifically snakes.cpp. The OpenCV test code is:

#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

Is there anything I did wrong or this version of active contour in OpenCV is completely useless? I checked the snake.cpp, the source code for OpenCV version active contour, it seems that it is implemented based on the theory in paper. Because of file protection, I cannot access the Matlab version active contour. Therefore, I cannot compare them directly. Since eventually, I will use OpenCV to implement stuffs, any suggestion for improving or changing my OpenCV code will be appreciated.

I attached the original image and mask in case someone wants to repeat the test.

Thanks!

Brain Image Mask

SimaGuanxing
  • 673
  • 2
  • 10
  • 29
  • Maybe this can help? From the images looks like you have a similar problem of this post: [Active Contour Models in OpenCV 3.0](https://stackoverflow.com/questions/32894542/active-contour-models-in-opencv-3-0). It's C++, but you could still take some hints from the comment section. – EsotericVoid Aug 14 '17 at 22:30
  • @Bit Thank you! It seems that OpenCV version snake only works for binary image, which I think is very weird. – SimaGuanxing Aug 15 '17 at 03:56

0 Answers0