Rev 3 |
View as "text/plain" |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
1
/*------------------------------------------------------------------------------------------*\
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 <iostream>
#include <vector>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
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<std::vector<cv::Point> > 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<std::vector<cv::Point> >::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<std::vector<cv::Point> >::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<int>(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<cv::Point> 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<cv::Point>::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<cv::Point> hull;
cv::convexHull(cv::Mat(contours[3]),hull);
// Iterate over each segment and draw it
std::vector<cv::Point>::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;
}