135 lines
3.6 KiB
C++
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
|