# Untitled

May 6th, 2021
776
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. #include <vector>
2. #include <algorithm>
3. #include <iostream>
4. #include <fstream>
5. #include <string>
6.
7. #include <opencv2/opencv.hpp>
8.
9. using namespace cv;
10. using namespace std;
11.
12.
13. Scalar getMSSIM(const Mat& i1, const Mat& i2)
14. {
15.     const double C1 = 6.5025, C2 = 58.5225;
16.     int d = CV_32F;
17.
18.     Mat I1, I2;
19.     i1.convertTo(I1, d);
20.     i2.convertTo(I2, d);
21.
22.     Mat I2_2 = I2.mul(I2);
23.     Mat I1_2 = I1.mul(I1);
24.     Mat I1_I2 = I1.mul(I2);
25.
26.
27.     Mat mu1, mu2;
28.     GaussianBlur(I1, mu1, Size(11, 11), 1.5);
29.     GaussianBlur(I2, mu2, Size(11, 11), 1.5);
30.
31.     Mat mu1_2 = mu1.mul(mu1);
32.     Mat mu2_2 = mu2.mul(mu2);
33.     Mat mu1_mu2 = mu1.mul(mu2);
34.
35.     Mat sigma1_2, sigma2_2, sigma12;
36.
37.     GaussianBlur(I1_2, sigma1_2, Size(11, 11), 1.5);
38.     sigma1_2 -= mu1_2;
39.
40.     GaussianBlur(I2_2, sigma2_2, Size(11, 11), 1.5);
41.     sigma2_2 -= mu2_2;
42.
43.     GaussianBlur(I1_I2, sigma12, Size(11, 11), 1.5);
44.     sigma12 -= mu1_mu2;
45.
46.     Mat t1, t2, t3;
47.
48.     t1 = 2 * mu1_mu2 + C1;
49.     t2 = 2 * sigma12 + C2;
50.     t3 = t1.mul(t2);
51.
52.     t1 = mu1_2 + mu2_2 + C1;
53.     t2 = sigma1_2 + sigma2_2 + C2;
54.     t1 = t1.mul(t2);
55.
56.     Mat ssim_map;
57.     divide(t3, t1, ssim_map);
58.
59.     Scalar mssim = mean(ssim_map);
60.     return mssim;
61. }
62.
63.
64. double calcMatch(const Mat& lhs, const Mat& rhs) {
65.     int count = 0;
66.     for (int i = 0; i < lhs.rows; ++i) {
67.         for (int j = 0; j < lhs.cols; ++j) {
68.             if (lhs.at<uchar>(i, j) != rhs.at<uchar>(i, j)) {
69.                 ++count;
70.             }
71.         }
72.     }
73.     return 1.0 - count * 1.0 / (lhs.size().area());
74. }
75.
76. const size_t img_width = 2100;
77. const size_t img_height = 2970;
78.
79.
80. int main() {
81.     vector<string> files = { "P_20210309_064128_vHDR_Auto.jpg",
82.                              "P_20210410_170858_vHDR_On.jpg" ,
83.                              "P_20210410_170941_vHDR_On.jpg" ,
84.                              "P_20210410_171129_vHDR_On.jpg" ,
85.                              "P_20210410_171136_vHDR_On.jpg" ,
86.                              "P_20210410_171334_vHDR_On.jpg"
87.     };
88.
89.     int k = files.size();
90.
91.     //считывание изображений
92.     vector<Mat> src(k);
93.     for (int i = 0; i < k; ++i) {
95.     }
96.
97.     //подготовка изображений
98.     vector<Mat> prepared(k);
99.     for (int i = 0; i < k; ++i) {
100.         Mat gr, bl, di, bin;
101.         cvtColor(src[i], gr, COLOR_BGR2GRAY);
102.         GaussianBlur(gr, bl, { 3, 3 }, 0);
103.         dilate(bl, di, getStructuringElement(cv::MORPH_RECT, cv::Point(9, 9)));
105.         medianBlur(bin, prepared[i], 3);
106.     }
107.
108.     //выделение границ и линий
109.     for (int i = 0; i < k; ++i) {
110.         Mat edges;
111.         Canny(prepared[i], edges, 0, 300);
112.
113.         vector<Vec4i> lines;
114.         HoughLinesP(edges, lines, 1, CV_PI / 180, 1, 1, 20);
115.         for (auto& l : lines) {
116.             line(edges, Point(l[0], l[1]), Point(l[2], l[3]), cv::Scalar(255, 0, 0), 3, 8);
117.         }
118.         edges.copyTo(prepared[i]);
119.     }
120.
121.     //определение контуров документа
122.     vector<Mat> result(k);
123.     vector<vector<Point>> points(k);
124.
125.     for (int i = 0; i < k; ++i) {
126.         medianBlur(prepared[i], prepared[i], 9);
127.         bitwise_not(prepared[i], prepared[i]);
128.
129.         vector<vector<Point>> contours;
130.         vector<Vec4i> hierarchy;
131.
132.         findContours(prepared[i], contours, hierarchy, RETR_LIST, CHAIN_APPROX_SIMPLE);
133.         sort(contours.begin(), contours.end(), [](vector<Point>& lhs, vector<Point>& rhs) {
134.             return fabs(contourArea(Mat(lhs))) < fabs(contourArea(Mat(rhs)));
135.         });
136.         vector<Point> mainContour = contours.back();
137.         double perimetr = arcLength(mainContour, true);
138.
139.         Mat approx;
140.         approxPolyDP(mainContour, approx, 0.02 * perimetr, true);
141.
142.         src[i].copyTo(result[i]);
143.         points[i] = approx;
144.         Point pt = points[i].back();
145.         for (int j = 0; j < points[i].size(); ++j) {
146.             line(result[i], pt, points[i][j], { 108, 73, 255 }, 8, LINE_8);
147.             pt = points[i][j];
148.         }
149.         imwrite("result" + to_string(i) + ".jpg", result[i]);
150.     }
151.
152.     //совмещение документов
153.     vector<Point> frame = { {0, 0}, {0, img_height}, {img_width, img_height}, {img_width, 0} };
154.     vector<Mat> projections(k);
155.
156.     for (int i = 0; i < k; ++i) {
157.         Mat perspective = findHomography(points[i], frame, RANSAC);
158.         warpPerspective(src[i], projections[i], perspective, Size{ img_width,img_height });
159.         imwrite("projection" + to_string(i) + ".jpg", projections[i]);
160.     }
161.
162.     //бинаризация документов
163.     vector<Mat> binarization(k);
164.     for (int i = 0; i < k; ++i) {
165.         Mat temp;
166.         cvtColor(projections[i], temp, COLOR_BGR2GRAY);
168.         imwrite("binarization" + to_string(i) + ".jpg", binarization[i]);
169.     }
170.
171.     //оценка качества
172.     Mat etalon_input = imread("etalon.jpg"), gray, etalon;
173.     cvtColor(etalon_input, gray, COLOR_BGR2GRAY);
175.
176.     vector<Mat> difference(k);
177.     for (int i = 0; i < k; ++i) {
178.         bitwise_xor(etalon, binarization[i], difference[i]);
179.         imwrite("difference" + to_string(i) + ".jpg", difference[i]);
180.
181.         cout << files[i] << ":" << endl;
182.         cout << "Match with etalon = " << calcMatch(etalon, binarization[i]) << endl;
183.         cout << "Structure similarity = " << getMSSIM(etalon, binarization[i])[0] << endl;
184.         cout << endl;
185.     }
186.     waitKey(0);
187. }
188.
189. /*
190. *
191. ### Задание
192. 1. Реализовать выделение "границ и уголков" на фотографиях документа.
193. 2. Реализовать детектирование наиболее правдоподобного четырехугольника изображения страницы документа на фото.
194. 3. Используя эталонную геометрическую разметку из лабораторной 5 реализовать численную оценку качества выделения отдельных примитивов и финального результата для отдельных изображений и для набора.
195. 4. Реализовать представление результатов выполнения лабораторной (иллюстрации, таблицы, графики и т.д.) и вставить в отчет.
196. */
RAW Paste Data