opencv/samples/c/fitellipse.cpp

135 lines
3.6 KiB
C++

/********************************************************************************
*
*
* This program is demonstration for ellipse fitting. Program finds
* contours and approximate it by ellipses.
*
* Trackbar specify threshold parametr.
*
* White lines is contours. Red lines is fitting ellipses.
*
*
* Autor: Denis Burenkov.
*
*
*
********************************************************************************/
#ifdef _CH_
#pragma package <opencv>
#endif
#define CV_NO_BACKWARD_COMPATIBILITY
#ifndef _EiC
#include "cv.h"
#include "highgui.h"
#endif
int slider_pos = 70;
// Load the source image. HighGUI use.
IplImage *image02 = 0, *image03 = 0, *image04 = 0;
void process_image(int h);
int main( int argc, char** argv )
{
const char* filename = argc == 2 ? argv[1] : (char*)"stuff.jpg";
// load image and force it to be grayscale
if( (image03 = cvLoadImage(filename, 0)) == 0 )
return -1;
// Create the destination images
image02 = cvCloneImage( image03 );
image04 = cvCloneImage( image03 );
// Create windows.
cvNamedWindow("Source", 1);
cvNamedWindow("Result", 1);
// Show the image.
cvShowImage("Source", image03);
// Create toolbars. HighGUI use.
cvCreateTrackbar( "Threshold", "Result", &slider_pos, 255, process_image );
process_image(0);
// Wait for a key stroke; the same function arranges events processing
cvWaitKey(0);
cvReleaseImage(&image02);
cvReleaseImage(&image03);
cvDestroyWindow("Source");
cvDestroyWindow("Result");
return 0;
}
// Define trackbar callback functon. This function find contours,
// draw it and approximate it by ellipses.
void process_image(int h)
{
CvMemStorage* storage;
CvSeq* contour;
// Create dynamic structure and sequence.
storage = cvCreateMemStorage(0);
contour = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint) , storage);
// Threshold the source image. This needful for cvFindContours().
cvThreshold( image03, image02, slider_pos, 255, CV_THRESH_BINARY );
// Find all contours.
cvFindContours( image02, storage, &contour, sizeof(CvContour),
CV_RETR_LIST, CV_CHAIN_APPROX_NONE, cvPoint(0,0));
// Clear images. IPL use.
cvZero(image02);
cvZero(image04);
// This cycle draw all contours and approximate it by ellipses.
for(;contour;contour = contour->h_next)
{
int count = contour->total; // This is number point in contour
CvPoint center;
CvSize size;
CvBox2D box;
// Number point must be more than or equal to 6 (for cvFitEllipse_32f).
if( count < 6 )
continue;
CvMat* points_f = cvCreateMat( 1, count, CV_32FC2 );
CvMat points_i = cvMat( 1, count, CV_32SC2, points_f->data.ptr );
cvCvtSeqToArray( contour, points_f->data.ptr, CV_WHOLE_SEQ );
cvConvert( &points_i, points_f );
// Fits ellipse to current contour.
box = cvFitEllipse2( points_f );
// Draw current contour.
cvDrawContours(image04,contour,CV_RGB(255,255,255),CV_RGB(255,255,255),0,1,8,cvPoint(0,0));
// Convert ellipse data from float to integer representation.
center = cvPointFrom32f(box.center);
size.width = cvRound(box.size.width*0.5);
size.height = cvRound(box.size.height*0.5);
// Draw ellipse.
cvEllipse(image04, center, size,
-box.angle, 0, 360,
CV_RGB(0,0,255), 1, CV_AA, 0);
cvReleaseMat(&points_f);
}
// Show image. HighGUI use.
cvShowImage( "Result", image04 );
}
#ifdef _EiC
main(1,"fitellipse.c");
#endif