/*------------------------------------------------------------------------------------------*\ This file contains material supporting chapter 7 of the cookbook: Computer Vision Programming using the OpenCV Library. by Robert Laganiere, Packt Publishing, 2011. This program is free software; permission is hereby granted to use, copy, modify, and distribute this source code, or portions thereof, for any purpose, without fee, subject to the restriction that the copyright notice may not be removed or altered from any source or altered source distribution. The software is released on an as-is basis and without any warranties of any kind. In particular, the software is not guaranteed to be fault-tolerant or free from failure. The author disclaims all warranties with regard to this software, any use, and any consequent failure, is purely the responsibility of the user. Copyright (C) 2010-2011 Robert Laganiere, www.laganiere.name \*------------------------------------------------------------------------------------------*/ #include #include #include #include #include int main() { // Read input binary image cv::Mat image= cv::imread("../binaryGroup.bmp",0); if (!image.data) return 0; cv::namedWindow("Binary Image"); cv::imshow("Binary Image",image); // Get the contours of the connected components std::vector > contours; cv::findContours(image, contours, // a vector of contours CV_RETR_EXTERNAL, // retrieve the external contours CV_CHAIN_APPROX_NONE); // retrieve all pixels of each contours // Print contours' length std::cout << "Contours: " << contours.size() << std::endl; std::vector >::const_iterator itContours= contours.begin(); for ( ; itContours!=contours.end(); ++itContours) { std::cout << "Size: " << itContours->size() << std::endl; } // draw black contours on white image cv::Mat result(image.size(),CV_8U,cv::Scalar(255)); cv::drawContours(result,contours, -1, // draw all contours cv::Scalar(0), // in black 2); // with a thickness of 2 cv::namedWindow("Contours"); cv::imshow("Contours",result); // Eliminate too short or too long contours int cmin= 100; // minimum contour length int cmax= 1000; // maximum contour length std::vector >::const_iterator itc= contours.begin(); while (itc!=contours.end()) { if (itc->size() < cmin || itc->size() > cmax) itc= contours.erase(itc); else ++itc; } // draw contours on the original image cv::Mat original= cv::imread("../group.jpg"); cv::drawContours(original,contours, -1, // draw all contours cv::Scalar(255,255,255), // in white 2); // with a thickness of 2 cv::namedWindow("Contours on Animals"); cv::imshow("Contours on Animals",original); // Let's now draw black contours on white image result.setTo(cv::Scalar(255)); cv::drawContours(result,contours, -1, // draw all contours cv::Scalar(0), // in black 1); // with a thickness of 1 image= cv::imread("../binaryGroup.bmp",0); // testing the bounding box cv::Rect r0= cv::boundingRect(cv::Mat(contours[0])); cv::rectangle(result,r0,cv::Scalar(0),2); // testing the enclosing circle float radius; cv::Point2f center; cv::minEnclosingCircle(cv::Mat(contours[1]),center,radius); cv::circle(result,cv::Point(center),static_cast(radius),cv::Scalar(0),2); // cv::RotatedRect rrect= cv::fitEllipse(cv::Mat(contours[1])); // cv::ellipse(result,rrect,cv::Scalar(0),2); // testing the approximate polygon std::vector poly; cv::approxPolyDP(cv::Mat(contours[2]),poly,5,true); std::cout << "Polygon size: " << poly.size() << std::endl; // Iterate over each segment and draw it std::vector::const_iterator itp= poly.begin(); while (itp!=(poly.end()-1)) { cv::line(result,*itp,*(itp+1),cv::Scalar(0),2); ++itp; } // last point linked to first point cv::line(result,*(poly.begin()),*(poly.end()-1),cv::Scalar(20),2); // testing the convex hull std::vector hull; cv::convexHull(cv::Mat(contours[3]),hull); // Iterate over each segment and draw it std::vector::const_iterator it= hull.begin(); while (it!=(hull.end()-1)) { cv::line(result,*it,*(it+1),cv::Scalar(0),2); ++it; } // last point linked to first point cv::line(result,*(hull.begin()),*(hull.end()-1),cv::Scalar(20),2); // testing the moments // iterate over all contours itc= contours.begin(); while (itc!=contours.end()) { // compute all moments cv::Moments mom= cv::moments(cv::Mat(*itc++)); // draw mass center cv::circle(result, // position of mass center converted to integer cv::Point(mom.m10/mom.m00,mom.m01/mom.m00), 2,cv::Scalar(0),2); // draw black dot } cv::namedWindow("Some Shape descriptors"); cv::imshow("Some Shape descriptors",result); // New call to findContours but with CV_RETR_LIST flag image= cv::imread("../binaryGroup.bmp",0); // Get the contours of the connected components cv::findContours(image, contours, // a vector of contours CV_RETR_LIST, // retrieve the external and internal contours CV_CHAIN_APPROX_NONE); // retrieve all pixels of each contours // draw black contours on white image result.setTo(cv::Scalar(255)); cv::drawContours(result,contours, -1, // draw all contours cv::Scalar(0), // in black 2); // with a thickness of 2 cv::namedWindow("All Contours"); cv::imshow("All Contours",result); cv::waitKey(); return 0; }