1 /******************************************************************************** 2 * 3 * 4 * This program is demonstration for ellipse fitting. Program finds 5 * contours and approximate it by ellipses. 6 * 7 * Trackbar specify threshold parametr. 8 * 9 * White lines is contours. Red lines is fitting ellipses. 10 * 11 * 12 * Autor: Denis Burenkov. 13 * 14 * 15 * 16 ********************************************************************************/ 17 #include "opencv2/imgproc/imgproc.hpp" 18 #include "opencv2/imgcodecs.hpp" 19 #include "opencv2/highgui/highgui.hpp" 20 #include <iostream> 21 using namespace cv; 22 using namespace std; 23 24 // static void help() 25 // { 26 // cout << 27 // "\nThis program is demonstration for ellipse fitting. The program finds\n" 28 // "contours and approximate it by ellipses.\n" 29 // "Call:\n" 30 // "./fitellipse [image_name -- Default ../data/stuff.jpg]\n" << endl; 31 // } 32 33 int sliderPos = 70; 34 35 Mat image; 36 37 void processImage(int, void*); 38 39 int main( int argc, char** argv ) 40 { 41 const char* filename = argc == 2 ? argv[1] : (char*)"../data/stuff.jpg"; 42 image = imread(filename, 0); 43 if( image.empty() ) 44 { 45 cout << "Couldn't open image " << filename << "\nUsage: fitellipse <image_name>\n"; 46 return 0; 47 } 48 49 imshow("source", image); 50 namedWindow("result", 1); 51 52 // Create toolbars. HighGUI use. 53 createTrackbar( "threshold", "result", &sliderPos, 255, processImage ); 54 processImage(0, 0); 55 56 // Wait for a key stroke; the same function arranges events processing 57 waitKey(); 58 return 0; 59 } 60 61 // Define trackbar callback functon. This function find contours, 62 // draw it and approximate it by ellipses. 63 void processImage(int /*h*/, void*) 64 { 65 vector<vector<Point> > contours; 66 Mat bimage = image >= sliderPos; 67 68 findContours(bimage, contours, RETR_LIST, CHAIN_APPROX_NONE); 69 70 Mat cimage = Mat::zeros(bimage.size(), CV_8UC3); 71 72 for(size_t i = 0; i < contours.size(); i++) 73 { 74 size_t count = contours[i].size(); 75 if( count < 6 ) 76 continue; 77 78 Mat pointsf; 79 Mat(contours[i]).convertTo(pointsf, CV_32F); 80 RotatedRect box = fitEllipse(pointsf); 81 82 if( MAX(box.size.width, box.size.height) > MIN(box.size.width, box.size.height)*30 ) 83 continue; 84 drawContours(cimage, contours, (int)i, Scalar::all(255), 1, 8); 85 86 ellipse(cimage, box, Scalar(0,0,255), 1, LINE_AA); 87 ellipse(cimage, box.center, box.size*0.5f, box.angle, 0, 360, Scalar(0,255,255), 1, LINE_AA); 88 Point2f vtx[4]; 89 box.points(vtx); 90 for( int j = 0; j < 4; j++ ) 91 line(cimage, vtx[j], vtx[(j+1)%4], Scalar(0,255,0), 1, LINE_AA); 92 } 93 94 imshow("result", cimage); 95 } 96