Rev 3 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
3 | PointedEar | 1 | /*------------------------------------------------------------------------------------------*\ |
2 | This file contains material supporting chapter 7 of the cookbook: |
||
3 | Computer Vision Programming using the OpenCV Library. |
||
4 | by Robert Laganiere, Packt Publishing, 2011. |
||
5 | |||
6 | This program is free software; permission is hereby granted to use, copy, modify, |
||
7 | and distribute this source code, or portions thereof, for any purpose, without fee, |
||
8 | subject to the restriction that the copyright notice may not be removed |
||
9 | or altered from any source or altered source distribution. |
||
10 | The software is released on an as-is basis and without any warranties of any kind. |
||
11 | In particular, the software is not guaranteed to be fault-tolerant or free from failure. |
||
12 | The author disclaims all warranties with regard to this software, any use, |
||
13 | and any consequent failure, is purely the responsibility of the user. |
||
14 | |||
15 | Copyright (C) 2010-2011 Robert Laganiere, www.laganiere.name |
||
16 | \*------------------------------------------------------------------------------------------*/ |
||
17 | |||
18 | #include <iostream> |
||
19 | #include <vector> |
||
20 | #include <opencv2/core/core.hpp> |
||
21 | #include <opencv2/imgproc/imgproc.hpp> |
||
22 | #include <opencv2/highgui/highgui.hpp> |
||
23 | |||
24 | int main() |
||
25 | { |
||
26 | // Read input binary image |
||
27 | cv::Mat image= cv::imread("../binaryGroup.bmp",0); |
||
28 | if (!image.data) |
||
29 | return 0; |
||
30 | |||
31 | cv::namedWindow("Binary Image"); |
||
32 | cv::imshow("Binary Image",image); |
||
33 | |||
34 | // Get the contours of the connected components |
||
5 | PointedEar | 35 | std::vector<std::vector<cv::Point> > contours; |
3 | PointedEar | 36 | cv::findContours(image, |
37 | contours, // a vector of contours |
||
38 | CV_RETR_EXTERNAL, // retrieve the external contours |
||
39 | CV_CHAIN_APPROX_NONE); // retrieve all pixels of each contours |
||
40 | |||
41 | // Print contours' length |
||
42 | std::cout << "Contours: " << contours.size() << std::endl; |
||
5 | PointedEar | 43 | std::vector<std::vector<cv::Point> >::const_iterator itContours= contours.begin(); |
3 | PointedEar | 44 | for ( ; itContours!=contours.end(); ++itContours) { |
45 | |||
46 | std::cout << "Size: " << itContours->size() << std::endl; |
||
47 | } |
||
48 | |||
49 | // draw black contours on white image |
||
50 | cv::Mat result(image.size(),CV_8U,cv::Scalar(255)); |
||
51 | cv::drawContours(result,contours, |
||
52 | -1, // draw all contours |
||
53 | cv::Scalar(0), // in black |
||
54 | 2); // with a thickness of 2 |
||
55 | |||
56 | cv::namedWindow("Contours"); |
||
57 | cv::imshow("Contours",result); |
||
58 | |||
59 | // Eliminate too short or too long contours |
||
60 | int cmin= 100; // minimum contour length |
||
61 | int cmax= 1000; // maximum contour length |
||
5 | PointedEar | 62 | std::vector<std::vector<cv::Point> >::const_iterator itc= contours.begin(); |
3 | PointedEar | 63 | while (itc!=contours.end()) { |
64 | |||
65 | if (itc->size() < cmin || itc->size() > cmax) |
||
66 | itc= contours.erase(itc); |
||
67 | else |
||
68 | ++itc; |
||
69 | } |
||
70 | |||
71 | // draw contours on the original image |
||
72 | cv::Mat original= cv::imread("../group.jpg"); |
||
73 | cv::drawContours(original,contours, |
||
74 | -1, // draw all contours |
||
75 | cv::Scalar(255,255,255), // in white |
||
76 | 2); // with a thickness of 2 |
||
77 | |||
78 | cv::namedWindow("Contours on Animals"); |
||
79 | cv::imshow("Contours on Animals",original); |
||
80 | |||
81 | // Let's now draw black contours on white image |
||
82 | result.setTo(cv::Scalar(255)); |
||
83 | cv::drawContours(result,contours, |
||
84 | -1, // draw all contours |
||
85 | cv::Scalar(0), // in black |
||
86 | 1); // with a thickness of 1 |
||
87 | image= cv::imread("../binaryGroup.bmp",0); |
||
88 | |||
89 | // testing the bounding box |
||
90 | cv::Rect r0= cv::boundingRect(cv::Mat(contours[0])); |
||
91 | cv::rectangle(result,r0,cv::Scalar(0),2); |
||
92 | |||
93 | // testing the enclosing circle |
||
94 | float radius; |
||
95 | cv::Point2f center; |
||
96 | cv::minEnclosingCircle(cv::Mat(contours[1]),center,radius); |
||
97 | cv::circle(result,cv::Point(center),static_cast<int>(radius),cv::Scalar(0),2); |
||
98 | |||
99 | // cv::RotatedRect rrect= cv::fitEllipse(cv::Mat(contours[1])); |
||
100 | // cv::ellipse(result,rrect,cv::Scalar(0),2); |
||
101 | |||
102 | // testing the approximate polygon |
||
103 | std::vector<cv::Point> poly; |
||
104 | cv::approxPolyDP(cv::Mat(contours[2]),poly,5,true); |
||
105 | |||
106 | std::cout << "Polygon size: " << poly.size() << std::endl; |
||
107 | |||
108 | // Iterate over each segment and draw it |
||
109 | std::vector<cv::Point>::const_iterator itp= poly.begin(); |
||
110 | while (itp!=(poly.end()-1)) { |
||
111 | cv::line(result,*itp,*(itp+1),cv::Scalar(0),2); |
||
112 | ++itp; |
||
113 | } |
||
114 | // last point linked to first point |
||
115 | cv::line(result,*(poly.begin()),*(poly.end()-1),cv::Scalar(20),2); |
||
116 | |||
117 | // testing the convex hull |
||
118 | std::vector<cv::Point> hull; |
||
119 | cv::convexHull(cv::Mat(contours[3]),hull); |
||
120 | |||
121 | // Iterate over each segment and draw it |
||
122 | std::vector<cv::Point>::const_iterator it= hull.begin(); |
||
123 | while (it!=(hull.end()-1)) { |
||
124 | cv::line(result,*it,*(it+1),cv::Scalar(0),2); |
||
125 | ++it; |
||
126 | } |
||
127 | // last point linked to first point |
||
128 | cv::line(result,*(hull.begin()),*(hull.end()-1),cv::Scalar(20),2); |
||
129 | |||
130 | // testing the moments |
||
131 | |||
132 | // iterate over all contours |
||
133 | itc= contours.begin(); |
||
134 | while (itc!=contours.end()) { |
||
135 | |||
136 | // compute all moments |
||
137 | cv::Moments mom= cv::moments(cv::Mat(*itc++)); |
||
138 | |||
139 | // draw mass center |
||
140 | cv::circle(result, |
||
141 | // position of mass center converted to integer |
||
142 | cv::Point(mom.m10/mom.m00,mom.m01/mom.m00), |
||
143 | 2,cv::Scalar(0),2); // draw black dot |
||
144 | } |
||
145 | |||
146 | cv::namedWindow("Some Shape descriptors"); |
||
147 | cv::imshow("Some Shape descriptors",result); |
||
148 | |||
149 | // New call to findContours but with CV_RETR_LIST flag |
||
150 | image= cv::imread("../binaryGroup.bmp",0); |
||
151 | |||
152 | // Get the contours of the connected components |
||
153 | cv::findContours(image, |
||
154 | contours, // a vector of contours |
||
155 | CV_RETR_LIST, // retrieve the external and internal contours |
||
156 | CV_CHAIN_APPROX_NONE); // retrieve all pixels of each contours |
||
157 | |||
158 | // draw black contours on white image |
||
159 | result.setTo(cv::Scalar(255)); |
||
160 | cv::drawContours(result,contours, |
||
161 | -1, // draw all contours |
||
162 | cv::Scalar(0), // in black |
||
163 | 2); // with a thickness of 2 |
||
164 | cv::namedWindow("All Contours"); |
||
165 | cv::imshow("All Contours",result); |
||
166 | |||
167 | cv::waitKey(); |
||
168 | return 0; |
||
5 | PointedEar | 169 | } |