Image processing - (source) median filtering () function programming

 

https://blog.csdn.net/tengfei461807914/article/details/83626123

Median filter is a nonlinear filter, excellent results when dealing with impulse noise and salt and pepper noise, can effectively protect the edge information with an image.

Roadmap median filtering is very simple, the values ​​of the pixels in the convolution kernel is taken as a pixel value which can be covered by anchor.

If according to traverse all the pixels, and then take the sorted pixel values ​​in the convolution kernel, then the time will be a high degree of complexity, the need for improved median filter.

Improved median filter is actually very good thought, nothing more than a slide in the value of the question to take window, during each slide to the right in the window is equal to adding a new add-pixel window, while subtracting one pixel window , consider maintaining the pixel information can change in this window.

This algorithm is used inside huang, the idea is that people put forward, the algorithm idea is as follows:

In the method for calculating the value, do not use the sort, but the use of pixel histogram, the pixel value is a hash of the record. The threshold is first set threshold, the threshold is the center position of the window, i.e. ksize × ksize / 2 + 1, kisze for the window size.

During each calculation value, from small to large cumulative pixel value histogram, if the value is greater than or equal, then the corresponding value is the median value of the pixel.

例如ksize=3的窗口如下:
⎡⎣⎢122235154⎤⎦⎥(3) \left[\begin{matrix}1 & 2 & 1 \\2 & 3 & 5 \\2 & 5 & 4\end{matrix}\right] \tag{3}




1
2
2


2
3
5


1
5
4





(3)

Calculating a pixel value of the histogram as the window, threshold =. 3 ×. 3/2 + 1. 5 =
1: 2 (1 denotes a pixel value has 2)
2: 3
3: 1
4: 1
5: 2

Because 2 + 3≥5, so the value 2

During each sliding window, if the window in the first column, then the histogram is calculated directly. Otherwise, move to the right, leaving the left side minus the pixel window, add into the window on the right side of the pixels in the histogram.

In addition, you can also let the window to move in accordance with the snake, it will also avoid the problem in the first column of each window requires recalculation.

  1 void AddSultPapperNoise(const Mat &src, Mat &dst,int num)//添加椒盐噪声
  2 {
  3     dst = src.clone();
  4     uchar *pd=dst.data;
  5     int row, col, cha;
  6     srand((unsigned)time(NULL));
  7     while (num--)
  8     {
  9         row = rand() % dst.rows;
 10         col = rand() % dst.cols;
 11         cha = rand() % dst.channels();
 12         pd[(row*dst.cols + col)*dst.channels() + cha] = 0;
 13     }
 14 }
 15 
 16 
 17 int GetMediValue(const int histogram[], int thresh)//计算中值
 18 {
 19     int sum = 0;
 20     for (int i = 0; i < (1 << 16); i++)
 21     {
 22         sum += histogram[i];
 23         if (sum >= thresh)
 24             return i;
 25     }
 26     return (1 << 16);
 27 }
 28 
 29 void MyFastMediFilter(const Mat &src, Mat &dst, int ksize)
 30 {
 31     CV_Assert(ksize % 2 == 1);
 32 
 33     Mat tmp;
 34     int len = ksize / 2;
 35     tmp.create(Size(src.cols + len, src.rows + len), src.type());//添加边框
 36     dst.create(Size(src.cols, src.rows), src.type());
 37 
 38 
 39     int channel = src.channels();
 40     uchar *ps = src.data;
 41     uchar *pt = tmp.data;
 42     for (int row = 0; row < tmp.rows; row++)//添加边框的过程
 43     {
 44         for (int col = 0; col < tmp.cols; col++)
 45         {
 46             for (int c = 0; c < channel; c++)
 47             {
 48                 if (row >= len && row < tmp.rows - len && col >= len && col < tmp.cols - len)
 49                     pt[(tmp.cols * row + col) * channel + c] = ps[(src.cols * (row - len) + col - len) * channel + c];
 50                 else
 51                     pt[(tmp.cols * row + col) * channel + c] = 0;
 52             }
 53         }
 54     }
 55     int Hist[(1 << 16)] = { 0 };
 56     uchar *pd = dst.data;
 57     ushort Val = 0 ;
 58      Pt = tmp.data;
 59      for ( int C = 0 ; C <Channel; C ++) // each channel separately calculated 
60      {
 61 is          for ( int Row = len; Row <tmp.rows - len ; Row ++ )
 62 is          {
 63 is              for ( int COL = len; COL <tmp.cols - len; COL ++ )
 64              {
 65                  
66                  IF (COL == len)
 67                  {
 68                     memset(Hist, 0, sizeof(Hist));
 69                     for (int x = -len; x <= len; x++)
 70                     {
 71                         for (int y = -len; y <= len; y++)
 72                         {
 73                             val = pt[((row + x) * tmp.cols + col + y) * channel + c];
 74                             Hist[val]++;
 75                         }
 76                     }
 77                 }
 78                 else
 79                 {
 80                     int L = col - len - 1;
 81                     int R = col + len;
 82                     for (int y = -len; y <= len; y++)
 83                     {
 84                         int leftInd = ((row + y) * tmp.cols + L) * channel + c;
 85                         int rightInd = ((row + y) * tmp.cols + R) * channel + c;
 86                         Hist[pt[leftInd]]--;
 87                         Hist[pt[rightInd]]++;
 88                     }
 89                 }
 90                  val = getmedivalu A (Hist, A * ksiz ksiz A / 2 + 1 );
91                  Pd [(dst.cols * (row - man) + col - man) * channel + c] = val;
92                  
93              }
 94          }
 95      }
 96  }
 97 

 

Guess you like

Origin www.cnblogs.com/fpzs/p/11183476.html