Advertisement
Georgiy031

Untitled

May 3rd, 2021
584
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.86 KB | None | 0 0
  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. int main() {
  80.     //извлечение координат разметки из текстового файла
  81.     vector<string> files;
  82.     vector<vector<Point>> coords;
  83.  
  84.     ifstream in("coords.csv");
  85.     string str;
  86.     while (getline(in, str)) {
  87.         size_t len = str.find_first_of(';');
  88.         files.push_back(str.substr(0, len));
  89.        
  90.         vector<int> coords_x, coords_y;
  91.         size_t x_end = str.find_first_of(';', len + 1);
  92.         string str_x = str.substr(len + 1, x_end - len - 1);
  93.         string str_y = str.substr(x_end + 1);
  94.  
  95.         vector<Point> pts;
  96.         size_t st_x = 0, st_y = 0;
  97.         for (int i = 0; i < 4; ++i) {
  98.             size_t end_x = str_x.find(',', st_x);
  99.             size_t end_y = str_y.find(',', st_y);
  100.             int x = stoi(str_x.substr(st_x, end_x - st_x));
  101.             int y = stoi(str_y.substr(st_y, end_y - st_y));
  102.             st_x = end_x + 1;
  103.             st_y = end_y + 1;
  104.             pts.push_back({ x, y });
  105.         }
  106.         coords.push_back(pts);
  107.     }
  108.  
  109.     //считывание изображений
  110.     size_t k = files.size();
  111.    
  112.     vector<Mat> source_data(k);
  113.     for (int i = 0; i < k; ++i) {
  114.         source_data[i] = imread(files[i]);
  115.     }
  116.  
  117.     //визуализация разметки
  118.     vector<Mat> markup(k);
  119.     for (int i = 0; i < k; ++i) {
  120.         source_data[i].copyTo(markup[i]);
  121.         Point pt = coords[i].back();
  122.         for (int j = 0; j < coords[i].size(); ++j) {
  123.             line(markup[i], pt, coords[i][j], { 0, 165, 255 }, 8, LINE_8);
  124.             pt = coords[i][j];
  125.         }
  126.         imwrite("markup" + to_string(i) + ".jpg", markup[i]);
  127.     }
  128.  
  129.     //совмещение документов
  130.     vector<Point> frame = { {0, 0}, {img_width, 0}, {img_width, img_height}, {0, img_height} };
  131.     vector<Mat> projections(k);
  132.  
  133.     for (int i = 0; i < k; ++i) {
  134.         Mat perspective = findHomography(coords[i], frame, RANSAC);
  135.         warpPerspective(source_data[i], projections[i], perspective, Size{ img_width,img_height });
  136.         imwrite("projection" + to_string(i) + ".jpg", projections[i]);
  137.     }
  138.  
  139.     //бинаризация документов
  140.     vector<Mat> binarization(k);
  141.     for (int i = 0; i < k; ++i) {
  142.         Mat temp;
  143.         cvtColor(projections[i], temp, COLOR_BGR2GRAY);
  144.         adaptiveThreshold(temp, binarization[i], 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 111, 15);
  145.         imwrite("binarization" + to_string(i) + ".jpg", binarization[i]);
  146.     }
  147.  
  148.     //оценка качества
  149.     vector<Mat> difference(k);
  150.     for (int i = 1; i < k; ++i) {
  151.         bitwise_xor(binarization[0], binarization[i], difference[i]);
  152.         imwrite("difference" + to_string(i) + ".jpg", difference[i]);
  153.        
  154.         cout << files[i] << ":" << endl;
  155.         cout << "Match with etalon = " << calcMatch(binarization[0], binarization[i]) << endl;
  156.         cout << "Structure similarity = " << getMSSIM(binarization[0], binarization[i])[0] << endl;
  157.         cout << endl;
  158.     }
  159. }
  160.  
  161. /*
  162. *
  163. ### Задание
  164. 1. Нарисовать эталонную "разметку" (четырехугольник изображения страницы) для отсканированного изображения и фотографий (не менее 5 любых).
  165. 2. Изготовить эталонную бинаризацию для скана.
  166. 3. Запрограммировать совмещение изображений при помощи гомографии с использованием эталонной геометрической разметки.
  167. 4. Используя эталонную геометрическую разметку реализовать численную оценку качества бинаризации (из лабораторной 4) для совмещенных изображений (для отдельных изображений и для набора).
  168. 5. Реализовать представление результатов выполнения лабораторной (иллюстрации, таблицы, графики и т.д.) и вставить в отчет.
  169. 6. Произвести уточнение параметров бинаризации (улучшение качества для набора изображений) и продемонстрировать результаты после уточнения.
  170. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement