• API
• FAQ
• Tools
• Archive
SHARE
TWEET

# Untitled

a guest Aug 3rd, 2017 263 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. #include "opencv2/imgproc.hpp"
2. #include "opencv2/imgcodecs.hpp"
3. #include "opencv2/highgui.hpp"
4. #include <iostream>
5.
6. using namespace cv;
7. using namespace std;
8. double angle(cv::Point pt1, cv::Point pt2, cv::Point pt0) {
9.     double dx1 = pt1.x - pt0.x;
10.     double dy1 = pt1.y - pt0.y;
11.     double dx2 = pt2.x - pt0.x;
12.     double dy2 = pt2.y - pt0.y;
13.     return (dx1*dx2 + dy1*dy2) / sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
14. }
15.
16. void find_squares(Mat& image, vector<vector<Point> >& squares)
17. {
18.     // blur will enhance edge detection
19.     Mat blurred(image);
20.     Mat dst;
21.     medianBlur(image, dst, 9);
22.
23.     Mat gray0(dst.size(), CV_8U), gray;
24.     vector<vector<Point> > contours;
25.
26.     // find squares in every color plane of the image
27.     for (int c = 0; c < 3; c++)
28.     {
29.         int ch[] = { c, 0 };
30.         mixChannels(&dst, 1, &gray0, 1, ch, 1);
31.
32.         // try several threshold levels
33.         const int threshold_level = 2;
34.         for (int l = 0; l < threshold_level; l++)
35.         {
36.             // Use Canny instead of zero threshold level!
38.             if (l == 0)
39.             {
40.                 Canny(gray0, gray, 10, 20, 3); //
41.
42.                                                // Dilate helps to remove potential holes between edge segments
43.                 dilate(gray, gray, Mat(), Point(-1, -1));
44.             }
45.             else
46.             {
47.                 gray = gray0 >= (l + 1) * 255 / threshold_level;
48.             }
49.
50.             // Find contours and store them in a list
51.             findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
52.
53.             // Test contours
54.             vector<Point> approx;
55.             for (size_t i = 0; i < contours.size(); i++)
56.             {
57.                 // approximate contour with accuracy proportional
58.                 // to the contour perimeter
59.                 approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);
60.
61.                 // Note: absolute value of an area is used because
62.                 // area may be positive or negative - in accordance with the
63.                 // contour orientation
64.                 if (approx.size() == 4 &&
65.                     fabs(contourArea(Mat(approx))) > 1000 &&
66.                     isContourConvex(Mat(approx)))
67.                 {
68.                     double maxCosine = 0;
69.
70.                     for (int j = 2; j < 5; j++)
71.                     {
72.                         double cosine = fabs(angle(approx[j % 4], approx[j - 2], approx[j - 1]));
73.                         maxCosine = MAX(maxCosine, cosine);
74.                     }
75.
76.                     if (maxCosine < 0.3)
77.                         squares.push_back(approx);
78.                 }
79.             }
80.         }
81.     }
82. }
83.
84.
85. cv::Mat debugSquares(std::vector<std::vector<cv::Point> > squares, cv::Mat image)
86. {
87.     for (int i = 0; i< squares.size(); i++) {
88.         // draw contour
89.         cv::drawContours(image, squares, i, cv::Scalar(255, 0, 0), 1, 8, std::vector<cv::Vec4i>(), 0, cv::Point());
90.
91.         // draw bounding rect
92.         cv::Rect rect = boundingRect(cv::Mat(squares[i]));
93.         cv::rectangle(image, rect.tl(), rect.br(), cv::Scalar(0, 255, 0), 2, 8, 0);
94.
95.         // draw rotated rect
96.         cv::RotatedRect minRect = minAreaRect(cv::Mat(squares[i]));
97.         cv::Point2f rect_points[4];
98.         minRect.points(rect_points);
99.         for (int j = 0; j < 4; j++) {
100.             cv::line(image, rect_points[j], rect_points[(j + 1) % 4], cv::Scalar(0, 0, 255), 1, 8); // blue
101.         }
102.     }
103.
104.     return image;
105. }
106.
107. int main(int, char**)
108. {
109.     int largest_area = 0;
110.     int largest_contour_index = 0;
111.     cv::Rect bounding_rect;
114.
115.     //2-convert image from gray scale to black and white using adaptive thresholding
116.     Mat blackAndWhiteMat;
118.
119.
120.     Mat dst(src.rows, src.cols, CV_8UC1, Scalar::all(0));
121.     vector<Vec4i> hierarchy;
122.
123.     vector<vector<cv::Point>> contours; // Vector for storing contour
124.     find_squares(src, contours);
125.
126.
127.     for (int i = 0; i< contours.size(); i++) // iterate through each contour.
128.     {
129.         double a = contourArea(contours[i], false);  //  Find the area of contour
130.         if (a>largest_area) {
131.             largest_area = a;
132.             largest_contour_index = i;                //Store the index of largest contour
133.             bounding_rect = boundingRect(contours[i]); // Find the bounding rectangle for biggest contour
134.         }
135.
136.     }
137.
138.     Scalar color(255, 255, 255);
139.     drawContours(dst, contours, largest_contour_index, color, CV_FILLED, 8, hierarchy); // Draw the largest contour using previously stored index.
140.     rectangle(src, bounding_rect, Scalar(0, 255, 0), 1, 8, 0);
141.
142.
143.
144.     Mat quad(src.size(), CV_8UC1); // should be improved
145.     Mat results(src.size(), CV_8UC3);
146.
147.     vector<Point2f> corners;
153.
154.
155.     for (size_t i = 0; i< contours.size(); i++)
156.     {
157.         RotatedRect minRect = minAreaRect(Mat(contours[i]));
158.
159.         // rotated rectangle
160.         Point2f rect_points[4];
161.         minRect.points(rect_points);
162.
163.         if (Rect(minRect.boundingRect()).width > src.cols / 2) // should be improved
164.             for (int j = 0; j < 4; j++)
165.             {
167.                 Point2f nearest_pt = rect_points[0];
168.                 float dist = norm(pt - nearest_pt);
169.                 for (int k = 1; k < 4; k++)
170.                 {
171.                     if (norm(pt - rect_points[k]) < dist)
172.                     {
173.                         dist = norm(pt - rect_points[k]);
174.                         nearest_pt = rect_points[k];
175.                     }
176.                 }
177.                 corners.push_back(nearest_pt);
178.             }
179.     }
180.
181.     Mat transmtx = getPerspectiveTransform(corners, quad_pts);
182.     warpPerspective(src, results, transmtx, src.size()); // Create a Mat To Show results
183.
184.     imshow("results", results);
185.
186.     cv::Mat result; // segmentation result (4 possible values)
187.     cv::Mat bgModel, fgModel; // the models (internally used)
188.
189.                               // GrabCut segmentation
190.     cv::grabCut(src,    // input image
191.         result,   // segmentation result
192.         bounding_rect,// rectangle containing foreground
193.         bgModel, fgModel, // models
194.         1,        // number of iterations
195.         cv::GC_INIT_WITH_RECT); // use rectangle
196.                                 // Get the pixels marked as likely foreground
197.     cv::compare(result, cv::GC_PR_FGD, result, cv::CMP_EQ);
198.     // Generate output image
199.     cv::Mat foreground(src.size(), CV_8UC3, cv::Scalar(255, 255, 255));
200.     src.copyTo(foreground, result); // bg pixels not copied
201.
202.                                     // draw rectangle on original image
203.     cv::rectangle(src, bounding_rect, cv::Scalar(255, 255, 255), 1);
204.     resize(src, src, Size(), 0.5, 0.5);
205.
206.     cv::namedWindow("Image");
207.     cv::imshow("Image", src);
208.
209.     // display result
210.     cv::namedWindow("Segmented Image");
211.     resize(foreground, foreground, Size(), 0.5, 0.5);
212.     cv::imshow("Segmented Image", foreground);
213.
214.
215.     waitKey();
216.
217.
218.     return 0;
219. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy.

Top