Advertisement
Guest User

Median/Bilateral Filter

a guest
May 21st, 2018
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.66 KB | None | 0 0
  1. #define H 0
  2. #define S 1
  3. #define V 2
  4.  
  5. std::vector<Vec3b> sortByChannel(std::vector<Vec3b> kernel, int size, int channel) {
  6.     int minIndex;
  7.     for (int i = 0; i < size - 1; i++) {
  8.         minIndex = i;
  9.         for (int j = i + 1; j < size; j++) {
  10.             if (kernel[j][channel] < kernel[minIndex][channel])
  11.                 minIndex = j;
  12.         }
  13.         //Swap
  14.         Vec3b aux = kernel[i];
  15.         kernel[i] = kernel[minIndex];
  16.         kernel[minIndex] = aux;
  17.     }
  18.     return kernel;
  19. }
  20.  
  21. std::vector<Vec3b> sortByChannelAndChannelEqualSV(std::vector<Vec3b> kernel, int size, int eqCh, int eqCh2, int channel) {
  22.     int minIndex = UINT_MAX;
  23.     for (int i = 0; i < size - 1; i++) {
  24.         minIndex = i;
  25.         for (int j = i + 1; j < size; j++) {
  26.             if (kernel[j][eqCh] == kernel[i][eqCh] && kernel[j][eqCh2] == kernel[i][eqCh2]) {
  27.                 if (kernel[j][channel] < kernel[minIndex][channel])
  28.                     minIndex = j;
  29.             }
  30.             else
  31.                 break;
  32.         }
  33.         //Swap
  34.         Vec3b aux = kernel[i];
  35.         kernel[i] = kernel[minIndex];
  36.         kernel[minIndex] = aux;
  37.     }
  38.     return kernel;
  39. }
  40.  
  41. std::vector<Vec3b> sortByChannelAndChannelEqualMaxToLow(std::vector<Vec3b> kernel, int size, int eqCh, int channel) {
  42.     int maxIndex = -1;
  43.     for (int i = 0; i < size - 1; i++) {
  44.         maxIndex = i;
  45.         for (int j = i + 1; j < size; j++) {
  46.             if (kernel[j][eqCh] == kernel[i][eqCh]) {
  47.                 if (kernel[j][channel] > kernel[maxIndex][channel])
  48.                     maxIndex = j;
  49.             }
  50.             else
  51.                 break;
  52.         }
  53.         //Swap
  54.         Vec3b aux = kernel[i];
  55.         kernel[i] = kernel[maxIndex];
  56.         kernel[maxIndex] = aux;
  57.     }
  58.     return kernel;
  59. }
  60.  
  61. Mat medianFilterColor(Mat src, int kernelSize, bool print = false) {
  62.     Mat matHSV;
  63.     cvtColor(src, matHSV, CV_BGR2HSV);
  64.     Mat dst = matHSV.clone();
  65.     int range = kernelSize / 2,
  66.         size = kernelSize * kernelSize,
  67.         height = src.rows - range,
  68.         width = src.cols - range;
  69.     std::vector<Vec3b> kernel;
  70.     kernel.resize(size);
  71.     for (int i = range; i < height; i++) {
  72.         for (int j = range; j < width; j++) {
  73.             int count = 0;
  74.             for (int x = 0; x < kernelSize; x++) {
  75.                 for (int y = 0; y < kernelSize; y++) {
  76.                     int matX = i + x - range,
  77.                         matY = j + y - range;
  78.                     kernel[count++] = matHSV.at<Vec3b>(matX, matY);
  79.                 }
  80.             }
  81.             kernel = sortByChannel(kernel, count, V);
  82.             //kernel = sortByChannelAndChannelEqualMaxToLow(kernel, size, V, S);
  83.             //kernel = sortByChannelAndChannelEqualSV(kernel, size, V, S, H);
  84.             dst.at<Vec3b>(i, j) = kernel[count / 2];
  85.         }
  86.     }
  87.     //
  88.     Mat matRGB;
  89.     cvtColor(dst, matRGB, CV_HSV2BGR);
  90.     //
  91.     if (print) {
  92.         imshow("Original image", src);
  93.         imshow("Median filter", matRGB);
  94.         waitKey();
  95.     }
  96.     //
  97.     return matRGB;
  98. }
  99.  
  100. void testMedianFilterColor() {
  101.     char fname[MAX_PATH];
  102.     if (openFileDlg(fname)) {
  103.         Mat src = imread(fname, CV_LOAD_IMAGE_COLOR);
  104.         medianFilterColor(src, 7, true);
  105.     }  
  106. }
  107.  
  108. //Bilaterial filter
  109.  
  110. float distanceBF(int x, int y, int i, int j) {
  111.     return float(sqrt(pow(x - i, 2) + pow(y - j, 2)));
  112. }
  113.  
  114. float gaussianBF(float x, double sigma) {
  115.     return exp(-(pow(x, 2))/(2 * pow(sigma, 2))) / (2 * CV_PI * pow(sigma, 2));
  116. }
  117.  
  118. #define BF_SIZE 5
  119. #define BF_SIGMA_R (12.0f)
  120. #define BF_SIGMA_S (16.0f)
  121.  
  122. Mat bilateralFilter(Mat src, int size, float sigmaR, float sigmaS, bool print = false) {
  123.     int height = src.rows, width = src.cols;
  124.     Mat matLAB;
  125.     cvtColor(src, matLAB, CV_BGR2Lab);
  126.     Mat bfImage = Mat::zeros(height, width, CV_64FC3);
  127.     for (int i = 0; i < height; i++) {
  128.         for (int j = 0; j < width; j++) {
  129.             bfImage.at<Vec3d>(i, j) = matLAB.at<Vec3b>(i, j);
  130.         }
  131.     }
  132.     //
  133.     int range = size / 2;
  134.     for (int i = range; i < height - range; i++) {
  135.         for (int j = range; j < width - range; j++) {
  136.             double wP[3] = { 0.0 }, sumTotal[3] = { 0.0 };
  137.             for (int x = 0; x < range; x++) {
  138.                 for (int y = 0; y < range; y++) {
  139.                     int matX = i + x - range,
  140.                         matY = j + y - range;
  141.                     double gS = gaussianBF(distanceBF(i, j, matX, matY), sigmaS);
  142.                     for (int c = 0; c < 3; c++) {
  143.                         float diff = matLAB.at<Vec3b>(matX, matY)[c] - matLAB.at<Vec3b>(i, j)[c];
  144.                         double gR = gaussianBF(diff, sigmaR);
  145.                         double w = gS * gR;
  146.                         sumTotal[c] += matLAB.at<Vec3b>(matX, matY)[c] * w;
  147.                         wP[c] += w;
  148.                     }
  149.                 }
  150.             }
  151.             //
  152.             for (int c = 0; c < 3; c++) {
  153.                 sumTotal[c] /= wP[c];
  154.                 bfImage.at<Vec3d>(i, j)[c] = sumTotal[c];
  155.             }
  156.             //
  157.         }
  158.     }
  159.     //
  160.     Mat dstLAB;
  161.     normalize(bfImage, dstLAB, 0, 255, NORM_MINMAX, CV_8UC3);
  162.     //Convert to BGR
  163.     Mat dstBGR;
  164.     cvtColor(dstLAB, dstBGR, CV_Lab2BGR);
  165.     if (print) {
  166.         imshow("Original image", src);
  167.         imshow("Bilateral filter", dstBGR);
  168.         waitKey();
  169.     }
  170.     return dstBGR;
  171. }
  172.  
  173. void testBilaterFilter() {
  174.     char fname[MAX_PATH];
  175.     if (openFileDlg(fname)) {
  176.         Mat src = imread(fname, CV_LOAD_IMAGE_COLOR);
  177.         bilateralFilter(src, BF_SIZE, BF_SIGMA_R, BF_SIGMA_S, true);
  178.     }
  179. }
  180.  
  181. //
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement