Advertisement
Guest User

Untitled

a guest
Dec 16th, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.52 KB | None | 0 0
  1. #include <iostream>
  2. #include <opencv2/opencv.hpp>
  3. #include <opencv2/highgui/highgui.hpp>
  4.  
  5. void convertToGrayScale(cv::Mat & in, cv::Mat & out) {
  6.     for (int i = 0; i < in.rows; i++) {
  7.         for (int j = 0; j < in.cols; j++) {
  8.             cv::Vec3b pixel = in.at<cv::Vec3b>(i, j);
  9.             uchar gsColor = (uchar)(0.0722 * pixel.val[0] + 0.7152 * pixel.val[1] + 0.2126 * pixel.val[2]);
  10.             out.at<uchar>(i, j) = gsColor;
  11.         }
  12.     }
  13. }
  14.  
  15. void getBinaryModel(cv::Mat & in, int * out) {
  16.     uchar threshold = 0;
  17.     int histogram[256] = {0};
  18.     int sum = 0;
  19.     double omega1 = 0, omega2, mu1, mu2, sigma = 0, max = 0;
  20.     int pixelNum = in.rows * in.cols;
  21.     for (int i = 0; i < in.rows; i++) {
  22.         for (int j = 0; j < in.cols; j++) {
  23.             ++histogram[in.at<uchar>(i, j)];
  24.             sum += in.at<uchar>(i, j);
  25.         }
  26.     }
  27.     for (int i = 0; i < 256; ++i) {
  28.         omega1 += histogram[i];
  29.         if (omega1 == 0)
  30.             continue;
  31.         omega2 = pixelNum - omega1;
  32.         if (omega2 == 0)
  33.             break;
  34.         sigma += i * histogram[i];
  35.         mu1 = sigma / omega1;
  36.         mu2 = (sum - sigma) / omega2;
  37.         double_t between = omega1 * omega2 * (mu1 - mu2) * (mu1 - mu2);
  38.         if (between > max) {
  39.             max = between;
  40.             threshold = (uchar)i;
  41.         }
  42.     }
  43.  
  44.     for (int i = 0; i < in.rows; i++) {
  45.         for (int j = 0; j < in.cols; j++) {
  46.             if (in.at<uchar>(i, j) < threshold) {
  47.                 out[i * in.cols + j] = 1;
  48.             } else {
  49.                 out[i * in.cols + j] = 0;
  50.             }
  51.         }
  52.     }
  53. }
  54.  
  55. int getLeft(int * model, int width, int i, int j) {
  56.     if (j == 0) {
  57.         return 0;
  58.     }
  59.     return model[i * width + j - 1];
  60. }
  61.  
  62. int getUp(int * model, int width, int i, int j) {
  63.     if (i == 0) {
  64.         return 0;
  65.     }
  66.     return model[(i - 1) * width + j];
  67. }
  68.  
  69. unsigned long countAreas(int * model, int width, int height) {
  70.     int curComp = 0;
  71.     int compNum = 0;
  72.     int leftComp, upComp;
  73.     std::map<int, int> comps;
  74.     for (int i = 0; i < height; i++) {
  75.         for (int j = 0; j < width; j++) {
  76.             int pos = i * width + j;
  77.             if (model[pos] == 1) {
  78.                 leftComp = getLeft(model, width, i, j);
  79.                 upComp = getUp(model, width, i, j);
  80.                 if (leftComp == 0 && upComp == 0) {
  81.                     ++curComp;
  82.                     ++compNum;
  83.                     comps[curComp] = curComp;
  84.                     model[pos] = curComp;
  85.                 } else {
  86.                     if (leftComp == 0) {
  87.                         model[pos] = comps[upComp];
  88.                     } else if (upComp == 0 || comps[leftComp] == comps[upComp]) {
  89.                         model[pos] = comps[leftComp];
  90.                     }
  91.                     else {
  92.                         if (leftComp < upComp) {
  93.                             model[pos] = comps[leftComp];
  94.                             if (comps[upComp] != comps[leftComp]) {
  95.                                 comps[upComp] = comps[leftComp];
  96.                             }
  97.                         } else {
  98.                             model[pos] = comps[upComp];
  99.                             if (comps[leftComp] != comps[upComp]) {
  100.                                 comps[leftComp] = comps[upComp];
  101.                             }
  102.                         }
  103.                     }
  104.                 }
  105.             }
  106.         }
  107.     }
  108.     std::set<int> difComps;
  109.     for (int i = 0; i < height; i++) {
  110.         for (int j = 0; j < width; j++) {
  111.             int pos = i * width + j;
  112.             if (model[pos] != 0) {
  113.                 model[pos] = comps[model[pos]];
  114.                 difComps.insert(model[pos]);
  115.             }
  116.         }
  117.     }
  118.  
  119.     return difComps.size();
  120. }
  121.  
  122. void dilation(int * modelSrc, int * modelDst, int width, int height, uchar * matrix, int size) {
  123.     for (int i = 0; i < height; i++) {
  124.         for (int j = 0; j < width; j++) {
  125.             int pos = i * width + j;
  126.             if (modelSrc[pos] == 1) {
  127.                 for (int k = 0; k < size; k++) {
  128.                     for (int m = 0; m < size; m++) {
  129.                         if (matrix[k * size + m] == 1) {
  130.                             int x = j - size / 2 + m;
  131.                             int y = i - size / 2 + k;
  132.                             if (x >= 0 && x < width && y >= 0 && y < height)
  133.                                 modelDst[y * width + x] = matrix[k * size + m];
  134.                         }
  135.                     }
  136.                 }
  137.             }
  138.         }
  139.     }
  140. }
  141.  
  142. int main() {
  143.     cv::Mat image;
  144.     image = cv::imread("img/img2.jpg", cv::IMREAD_COLOR);
  145.     if(!image.data )
  146.     {
  147.         std::cerr <<  "Could not open or find the image" << std::endl ;
  148.         return -1;
  149.     }
  150.     cv::Mat grayScaleImage(image.size(), CV_8U);
  151.     convertToGrayScale(image, grayScaleImage);
  152.     int model[image.rows * image.cols];
  153.     int tmp[image.rows * image.cols];
  154.     getBinaryModel(grayScaleImage, model);
  155.  
  156.     /*for (int i = 0; i < image.rows * image.cols; i++)
  157.     {
  158.         std::cerr <<  model[i] << " ";
  159.         if (i % image.rows == 0)
  160.             std::cerr << std::endl;
  161.     }*/
  162.  
  163.  
  164.     uchar matrix[9][9] = {
  165.             0,0,0,1,1,1,0,0,0,
  166.             0,0,1,1,1,1,1,0,0,
  167.             0,1,1,1,1,1,1,1,0,
  168.             1,1,1,1,1,1,1,1,1,
  169.             1,1,1,1,1,1,1,1,1,
  170.             1,1,1,1,1,1,1,1,1,
  171.             0,1,1,1,1,1,1,1,0,
  172.             0,0,1,1,1,1,1,0,0,
  173.             0,0,0,1,1,1,0,0,0,
  174.     };
  175.  
  176.     dilation(model, tmp, image.cols, image.rows, &matrix[0][0], 9);
  177.  
  178.     cv::Mat modelImage(image.size(), CV_8U);
  179.     for (int i = 0; i < modelImage.rows; i++) {
  180.         for (int j = 0; j < modelImage.cols; j++) {
  181.             if (model[i * modelImage.cols + j] == 1) {
  182.                 modelImage.at<uchar>(i, j) = 255;
  183.             } else {
  184.                 modelImage.at<uchar>(i, j) = 0;
  185.             }
  186.         }
  187.     }
  188.  
  189.     cv::Mat afterIm(image.size(), CV_8U);
  190.     for (int i = 0; i < afterIm.rows; i++) {
  191.         for (int j = 0; j < afterIm.cols; j++) {
  192.             if (tmp[i * afterIm.cols + j] == 1) {
  193.                 afterIm.at<uchar>(i, j) = 255;
  194.             } else {
  195.                 afterIm.at<uchar>(i, j) = 0;
  196.             }
  197.         }
  198.     }
  199.  
  200.     std::cerr << countAreas(tmp, image.cols, image.rows);
  201.  
  202.     /*namedWindow("before", cv::WINDOW_AUTOSIZE);
  203.     imshow("before", modelImage);*/
  204.  
  205.     namedWindow("after", cv::WINDOW_AUTOSIZE);
  206.     imshow("after", afterIm);
  207.  
  208.     cv::waitKey(0);
  209.  
  210.     return 0;
  211. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement