opencv例子里没有提供cvsnakeimage的使用方法,在此整理一个例子,可以形象的看看snake算法的结果,大致做法是:
首先设定域值分割,把基本的轮廓找出来,见图中蓝色轮廓线,再将轮廓点传入cvSnakeImage函数,计算出绿色的snake轮廓线。
其中参数alpha代表点相互靠拢的权值(0-1.0),beta表示弯曲能量(越小越容易弯曲)(0-1.0),gamma表示整体能量(0-1.0)。其中参数我自己也不确定具体的范围,最好自己更改不同的范围试试.
//
TrainingTools.cpp : 定义控制台应用程序的入口点。
//
#include " stdafx.h "
#include < iostream >
#include < string .h >
#include < cxcore.h >
#include < cv.h >
#include < highgui.h >
#include < fstream >
IplImage * image = 0 ; // 原始图像
IplImage * image2 = 0 ; // 原始图像copy
using namespace std;
int Thresholdness = 141 ;
int ialpha = 20 ;
int ibeta = 20 ;
int igamma = 20 ;
void onChange( int pos)
{
if (image2) cvReleaseImage( & image2);
if (image) cvReleaseImage( & image);
image2 = cvLoadImage( " grey.bmp " , 1 ); // 显示图片
image = cvLoadImage( " grey.bmp " , 0 );
cvThreshold(image,image,Thresholdness, 255 ,CV_THRESH_BINARY); // 分割域值
CvMemStorage * storage = cvCreateMemStorage( 0 );
CvSeq * contours = 0 ;
cvFindContours( image, 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( 0 , 0 , 255 ), 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 = 1000 ;
criteria.epsilon = 0.1 ;
cvSnakeImage( image, point,length, & alpha, & beta, & gamma,CV_VALUE,size,criteria, 0 );
// 显示曲线
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( " Thd " , " win1 " , & Thresholdness, 255 , onChange);
cvCreateTrackbar( " alpha " , " win1 " , & ialpha, 100 , onChange);
cvCreateTrackbar( " beta " , " win1 " , & ibeta, 100 , onChange);
cvCreateTrackbar( " gamma " , " win1 " , & igamma, 100 , onChange);
cvResizeWindow( " win1 " , 300 , 500 );
onChange( 0 );
for (;;)
{
if (cvWaitKey( 40 ) == 27 ) break ;
cvShowImage( " win1 " ,image2);
}
return 0 ;
}
//
#include " stdafx.h "
#include < iostream >
#include < string .h >
#include < cxcore.h >
#include < cv.h >
#include < highgui.h >
#include < fstream >
IplImage * image = 0 ; // 原始图像
IplImage * image2 = 0 ; // 原始图像copy
using namespace std;
int Thresholdness = 141 ;
int ialpha = 20 ;
int ibeta = 20 ;
int igamma = 20 ;
void onChange( int pos)
{
if (image2) cvReleaseImage( & image2);
if (image) cvReleaseImage( & image);
image2 = cvLoadImage( " grey.bmp " , 1 ); // 显示图片
image = cvLoadImage( " grey.bmp " , 0 );
cvThreshold(image,image,Thresholdness, 255 ,CV_THRESH_BINARY); // 分割域值
CvMemStorage * storage = cvCreateMemStorage( 0 );
CvSeq * contours = 0 ;
cvFindContours( image, 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( 0 , 0 , 255 ), 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 = 1000 ;
criteria.epsilon = 0.1 ;
cvSnakeImage( image, point,length, & alpha, & beta, & gamma,CV_VALUE,size,criteria, 0 );
// 显示曲线
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( " Thd " , " win1 " , & Thresholdness, 255 , onChange);
cvCreateTrackbar( " alpha " , " win1 " , & ialpha, 100 , onChange);
cvCreateTrackbar( " beta " , " win1 " , & ibeta, 100 , onChange);
cvCreateTrackbar( " gamma " , " win1 " , & igamma, 100 , onChange);
cvResizeWindow( " win1 " , 300 , 500 );
onChange( 0 );
for (;;)
{
if (cvWaitKey( 40 ) == 27 ) break ;
cvShowImage( " win1 " ,image2);
}
return 0 ;
}