Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <vector>
- #include <algorithm>
- #include <iostream>
- #include <fstream>
- #include <string>
- #include <opencv2/opencv.hpp>
- using namespace cv;
- using namespace std;
- Scalar getMSSIM(const Mat& i1, const Mat& i2)
- {
- const double C1 = 6.5025, C2 = 58.5225;
- int d = CV_32F;
- Mat I1, I2;
- i1.convertTo(I1, d);
- i2.convertTo(I2, d);
- Mat I2_2 = I2.mul(I2);
- Mat I1_2 = I1.mul(I1);
- Mat I1_I2 = I1.mul(I2);
- Mat mu1, mu2;
- GaussianBlur(I1, mu1, Size(11, 11), 1.5);
- GaussianBlur(I2, mu2, Size(11, 11), 1.5);
- Mat mu1_2 = mu1.mul(mu1);
- Mat mu2_2 = mu2.mul(mu2);
- Mat mu1_mu2 = mu1.mul(mu2);
- Mat sigma1_2, sigma2_2, sigma12;
- GaussianBlur(I1_2, sigma1_2, Size(11, 11), 1.5);
- sigma1_2 -= mu1_2;
- GaussianBlur(I2_2, sigma2_2, Size(11, 11), 1.5);
- sigma2_2 -= mu2_2;
- GaussianBlur(I1_I2, sigma12, Size(11, 11), 1.5);
- sigma12 -= mu1_mu2;
- Mat t1, t2, t3;
- t1 = 2 * mu1_mu2 + C1;
- t2 = 2 * sigma12 + C2;
- t3 = t1.mul(t2);
- t1 = mu1_2 + mu2_2 + C1;
- t2 = sigma1_2 + sigma2_2 + C2;
- t1 = t1.mul(t2);
- Mat ssim_map;
- divide(t3, t1, ssim_map);
- Scalar mssim = mean(ssim_map);
- return mssim;
- }
- double calcMatch(const Mat& lhs, const Mat& rhs) {
- int count = 0;
- for (int i = 0; i < lhs.rows; ++i) {
- for (int j = 0; j < lhs.cols; ++j) {
- if (lhs.at<uchar>(i, j) != rhs.at<uchar>(i, j)) {
- ++count;
- }
- }
- }
- return 1.0 - count * 1.0 / (lhs.size().area());
- }
- const size_t img_width = 2100;
- const size_t img_height = 2970;
- int main() {
- //извлечение координат разметки из текстового файла
- vector<string> files;
- vector<vector<Point>> coords;
- ifstream in("coords.csv");
- string str;
- while (getline(in, str)) {
- size_t len = str.find_first_of(';');
- files.push_back(str.substr(0, len));
- vector<int> coords_x, coords_y;
- size_t x_end = str.find_first_of(';', len + 1);
- string str_x = str.substr(len + 1, x_end - len - 1);
- string str_y = str.substr(x_end + 1);
- vector<Point> pts;
- size_t st_x = 0, st_y = 0;
- for (int i = 0; i < 4; ++i) {
- size_t end_x = str_x.find(',', st_x);
- size_t end_y = str_y.find(',', st_y);
- int x = stoi(str_x.substr(st_x, end_x - st_x));
- int y = stoi(str_y.substr(st_y, end_y - st_y));
- st_x = end_x + 1;
- st_y = end_y + 1;
- pts.push_back({ x, y });
- }
- coords.push_back(pts);
- }
- //считывание изображений
- size_t k = files.size();
- vector<Mat> source_data(k);
- for (int i = 0; i < k; ++i) {
- source_data[i] = imread(files[i]);
- }
- //визуализация разметки
- vector<Mat> markup(k);
- for (int i = 0; i < k; ++i) {
- source_data[i].copyTo(markup[i]);
- Point pt = coords[i].back();
- for (int j = 0; j < coords[i].size(); ++j) {
- line(markup[i], pt, coords[i][j], { 0, 165, 255 }, 8, LINE_8);
- pt = coords[i][j];
- }
- imwrite("markup" + to_string(i) + ".jpg", markup[i]);
- }
- //совмещение документов
- vector<Point> frame = { {0, 0}, {img_width, 0}, {img_width, img_height}, {0, img_height} };
- vector<Mat> projections(k);
- for (int i = 0; i < k; ++i) {
- Mat perspective = findHomography(coords[i], frame, RANSAC);
- warpPerspective(source_data[i], projections[i], perspective, Size{ img_width,img_height });
- imwrite("projection" + to_string(i) + ".jpg", projections[i]);
- }
- //бинаризация документов
- vector<Mat> binarization(k);
- for (int i = 0; i < k; ++i) {
- Mat temp;
- cvtColor(projections[i], temp, COLOR_BGR2GRAY);
- adaptiveThreshold(temp, binarization[i], 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 111, 15);
- imwrite("binarization" + to_string(i) + ".jpg", binarization[i]);
- }
- //оценка качества
- vector<Mat> difference(k);
- for (int i = 1; i < k; ++i) {
- bitwise_xor(binarization[0], binarization[i], difference[i]);
- imwrite("difference" + to_string(i) + ".jpg", difference[i]);
- cout << files[i] << ":" << endl;
- cout << "Match with etalon = " << calcMatch(binarization[0], binarization[i]) << endl;
- cout << "Structure similarity = " << getMSSIM(binarization[0], binarization[i])[0] << endl;
- cout << endl;
- }
- }
- /*
- *
- ### Задание
- 1. Нарисовать эталонную "разметку" (четырехугольник изображения страницы) для отсканированного изображения и фотографий (не менее 5 любых).
- 2. Изготовить эталонную бинаризацию для скана.
- 3. Запрограммировать совмещение изображений при помощи гомографии с использованием эталонной геометрической разметки.
- 4. Используя эталонную геометрическую разметку реализовать численную оценку качества бинаризации (из лабораторной 4) для совмещенных изображений (для отдельных изображений и для набора).
- 5. Реализовать представление результатов выполнения лабораторной (иллюстрации, таблицы, графики и т.д.) и вставить в отчет.
- 6. Произвести уточнение параметров бинаризации (улучшение качества для набора изображений) и продемонстрировать результаты после уточнения.
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement