Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- lab-04: Using binarization for image analysis
- @file main.cpp
- @author Vlad Tishin
- @version 1.0 30/03/21
- */
- #include <opencv2/opencv.hpp>
- #include <opencv2/highgui.hpp>
- #include <opencv2/imgproc/imgproc.hpp>
- #include <opencv2/quality/qualitymse.hpp>
- #include <opencv2/quality/qualitypsnr.hpp>
- #include <opencv2/quality/qualityssim.hpp>
- #include <iostream>
- using namespace cv;
- using namespace std;
- /**
- * Implementation of a fast Gaussian local binarization algorithm.
- * @param img - image for binarization.
- * @param res - output binarized image.
- * @param d0 - constant.
- * @param k - kernel size
- * @param tr - treshold.
- */
- void bin_gauss(Mat &img, Mat &res, double d0, int k, double tr);
- /**
- * Implementing the Connectivity Component filter.
- * @param img - input image.
- * @param mode - 0: x, 1: y, 2: width, 3: height, 4: area.
- * @param low - lower bound.
- * @param up - upper bound
- * @return filtered image.
- */
- Mat components_filter(const Mat& img, int mode, double low, double up);
- /**
- * Visualizes the deviation between two images. Paints elements in red and green
- colors.
- * If the pixel is only on 1 image - red, only on 2 - green.
- * @param src - ref bin image.
- * @param bin - bin image
- * @return deviation image.
- */
- Mat visualize_diff(const Mat& src, const Mat& bin);
- int main( )
- {
- Mat ref_image = imread("etalon_bin.jpg", IMREAD_GRAYSCALE);
- Mat image = imread("src.jpg");
- Mat gray, bin_gray, median_bin, filtered_median, deviation;
- cvtColor(image, gray, cv::COLOR_BGR2GRAY);
- imwrite("g1.png", gray);
- adaptiveThreshold(gray, bin_gray, 255, ADAPTIVE_THRESH_GAUSSIAN_C,
- THRESH_BINARY, 81, 20);
- imwrite("b1.png", bin_gray);
- medianBlur(bin_gray, median_bin, 3);
- imwrite("f1.png", median_bin);
- filtered_median = components_filter(median_bin, 4, 0, 15000);
- filtered_median = components_filter(filtered_median, 0, 220, 2250);
- filtered_median = components_filter(filtered_median, 1, 135, 2900);
- imwrite("v1.png", filtered_median);
- cout << "-------------------------------------------------" << endl;
- cout << "Binarized image" << endl;
- cout << "SSIM: " << cv::quality::QualitySSIM::compute(ref_image, bin_gray,
- noArray())[0] << endl;
- cout << "PSNR: " << cv::quality::QualityPSNR::compute(ref_image, bin_gray,
- noArray())[0] << endl;
- cout << "MSE: " << cv::quality::QualityMSE::compute(ref_image, bin_gray,
- noArray())[0] << endl << endl;
- cout << "Binarized image with median filter" << endl;
- cout << "SSIM: " << cv::quality::QualitySSIM::compute(ref_image, median_bin,
- noArray())[0] << endl;
- cout << "PSNR: " << cv::quality::QualityPSNR::compute(ref_image, median_bin,
- noArray())[0] << endl;
- cout << "MSE: " << cv::quality::QualityMSE::compute(ref_image, median_bin,
- noArray())[0] << endl << endl;
- cout << "Binarized image with median and component filters" << endl;
- cout << "SSIM: " << cv::quality::QualitySSIM::compute(ref_image,
- filtered_median, noArray())[0] << endl;
- cout << "PSNR: " << cv::quality::QualityPSNR::compute(ref_image,
- filtered_median, noArray())[0] << endl;
- cout << "MSE: " << cv::quality::QualityMSE::compute(ref_image,
- filtered_median, noArray())[0] << endl;
- cout << "-------------------------------------------------"<< endl;
- deviation = visualize_diff(ref_image, filtered_median);
- imwrite("e1.png", deviation);
- bin_gauss(gray, bin_gray, 20, 81, 0.4); // 20 81 0.45
- imwrite("b2.png", bin_gray);
- medianBlur(bin_gray, median_bin, 3);
- imwrite("f2.png", median_bin);
- filtered_median = components_filter(median_bin, 4, 0, 15000);
- filtered_median = components_filter(filtered_median, 0, 220, 2250);
- filtered_median = components_filter(filtered_median, 1, 135, 2900);
- imwrite("v2.png", filtered_median);
- cout << endl << "-------------------------------------------------" << endl;
- cout << "Binarized image";
- cout << "SSIM: " << cv::quality::QualitySSIM::compute(ref_image, bin_gray,
- noArray())[0] << endl;
- cout << "PSNR: " << cv::quality::QualityPSNR::compute(ref_image, bin_gray,
- noArray())[0] << endl;
- cout << "MSE: " << cv::quality::QualityMSE::compute(ref_image, bin_gray,
- noArray())[0] << endl << endl;
- cout << "Binarized image with median filter" << endl;
- cout << "SSIM: " << cv::quality::QualitySSIM::compute(ref_image, median_bin,
- noArray())[0] << endl;
- cout << "PSNR: " << cv::quality::QualityPSNR::compute(ref_image, median_bin,
- noArray())[0] << endl;
- cout << "MSE: " << cv::quality::QualityMSE::compute(ref_image, median_bin,
- noArray())[0] << endl << endl;
- cout << "Binarized image with median and component filters" << endl;
- cout << "SSIM: " << cv::quality::QualitySSIM::compute(ref_image,
- filtered_median, noArray())[0] << endl;
- cout << "PSNR: " << cv::quality::QualityPSNR::compute(ref_image,
- filtered_median, noArray())[0] << endl;
- cout << "MSE: " << cv::quality::QualityMSE::compute(ref_image,
- filtered_median, noArray())[0] << endl;
- cout << "-------------------------------------------------"<< endl;
- deviation = visualize_diff(ref_image, filtered_median);
- imwrite("e2.png", deviation);
- waitKey(0);
- return 0;
- }
- // Implementation of a fast Gaussian local binarization algorithm.
- void bin_gauss(Mat &img, Mat &res, double d0, int k, double tr){
- Mat G, M, D;
- GaussianBlur( img, G, Size(k, k), 0, 0);
- absdiff(G, img, M);
- GaussianBlur( M, D, Size(k, k), 0, 0);
- subtract(G, img, G);
- add(D, d0, D);
- divide(G, D, G);
- #pragma omp parallel for num_threads(4) collapse(2)
- for(int i=0; i<res.rows; i++)
- for (int j=0; j<res.cols; j++)
- res.at<uchar>(i, j) = (G.at<uchar>(i, j) < tr) ? 255 : 0;
- }
- // Implementing the Connectivity Component filter.
- Mat components_filter(const Mat& img, int mode, double low, double up){
- const int connectivity_8 = 8;
- Mat labels, stats, centroids;
- Mat inv_median_bin;
- bitwise_not(img, inv_median_bin);
- connectedComponentsWithStats(inv_median_bin, labels, stats, centroids,
- connectivity_8);
- Mat mask(labels.size(), CV_8UC1, Scalar(0));
- Mat surfSup_low=stats.col(mode)>low;
- Mat surfSup_up=stats.col(mode)<up;
- int tmp_label;
- for (int i = 0; i < inv_median_bin.rows; i++){
- for (int j = 0; j < inv_median_bin.cols ; j++){
- tmp_label = labels.at<int>(i,j);
- if ( (int) surfSup_low.at<char>(tmp_label,0) == 0 || (int)
- surfSup_up.at<char>(tmp_label,0) == 0 )
- mask.at<char>(i,j) = (char) 0;
- else
- mask.at<char>(i,j) = (char) 255;
- }
- }
- Mat r(inv_median_bin.size(), CV_8UC1, Scalar(0));
- inv_median_bin.copyTo(r,mask);
- bitwise_not(r, r);
- return r;
- }
- // Visualizes the deviation between two images. Paints elements in red and green
- colors.
- Mat visualize_diff(const Mat& src, const Mat& bin){
- Mat res;
- bin.copyTo(res);
- cvtColor(res,res ,COLOR_GRAY2BGR);
- for(int i=0; i<src.rows; i++)
- for(int j=0; j<bin.cols; j++) {
- int diff = (int) src.at<uchar>(i, j) - (int) bin.at<uchar>(i, j);
- if (diff == 0)
- continue;
- else if (diff > 0) {
- res.at<Vec3b>(i, j)[0] = 0;
- res.at<Vec3b>(i, j)[1] = 255;
- res.at<Vec3b>(i, j)[2] = 0;
- }
- else if (diff < 0) {
- res.at<Vec3b>(i, j)[0] = 0;
- res.at<Vec3b>(i, j)[1] = 0;
- res.at<Vec3b>(i, j)[2] = 255;
- }
- }
- return res;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement