OpenCv Learning Articles - Image Median Filtering Algorithm

1. Algorithm principle

Simply put: cross an image with a 3*3 template, and replace the value of pixel 5 with the median of pixel 1 to pixel 9. This filter is more suitable for salt and pepper noise. Because the value of salt and pepper is nothing more than 0 or 255.

2. A few points of knowledge you need to know

1. Hill sorting method:

Since we want to find the median of 9 numbers, we need to sort 9 pixels. Of course, the simple insertion sort method can also be sorted. Here is a Hill sort method. http://www.iqiyi.com/v_19rrhzyejc.html  This is the video I watched when I was learning Hill sorting. https://www.cnblogs.com/chengxiao/p/6104371.html This post is also good

The Hill sorting method is simply to choose a step size from the first number to start the interval step size selection and directly sort first. When the step size is not 1, you will not get an array in order, but you will get a more ordered array. The array of is not in order until the stride is 1.

uchar Median(uchar n1, uchar n2, uchar n3, uchar n4, uchar n5,uchar n6, uchar n7, uchar n8, uchar n9)
{
 uchar arr[9];
 arr[0] = n1;
 arr[1] = n2 ;
 arr[2] = n3;
 arr[3] = n4;
 arr[4] = n5;
 arr[5] = n6;
 arr[6] = n7;
 arr[7] = n8;
 arr[8] = n9;
 for (int gap = 9 / 2; gap > 0; gap /= 2)//Hill sort, determine how many subsequences
  for (int i = gap; i < 9; ++i)
   for (int j = i - gap; j >= 0 && arr[j] > arr[j + gap]; j -= gap)
    swap(arr[j], arr[j + gap]);
 return arr[4];//returning value 
}

If the for loop can't turn out, don't be lazy and use a pen to turn around like me.

After walking around, this sort is almost out.

2. Salt and pepper noise function

//Image salt and pepper 
void salt(Mat &image, int num) 
{      
 if (!image.data) return;//Prevent incoming empty images 
 int i, j;
 srand(time(NULL));
 for (int x = 0 ; x < num; ++x)
 {
  i = rand() % image.rows;
  j = rand() % image.cols;
  image.at(i, j)[0] = 255;
  image.at(i, j)[1] = 255;
  image.at(i, j)[2] = 255;
 }
} This function is to randomly generate a value of 255 in the row and column as a variable of a mat class image and how many salt and pepper points are needed

3. Program source code

#include
#include
#include
#include  
#include 
using namespace cv;
using namespace std;
//Find the median of nine numbers 
uchar Median(uchar n1, uchar n2, uchar n3, uchar n4, uchar n5,uchar n6, uchar n7 , uchar n8, uchar n9)
{
 uchar arr[9];
 arr[0] = n1;
 arr[1] = n2;
 arr[2] = n3;
 arr[3] = n4;
 arr[4] = n5;
 arr [5] = n6;
 arr[6] = n7;
 arr[7] = n8;
 arr[8] = n9;
 for (int gap = 9 / 2; gap > 0; gap /= 2)//Hill sort , determine how many subsequences
  for (int i = gap; i < 9; ++i)
   for (int j = i - gap; j >= 0 && arr[j] > arr[j + gap]; j -= gap)
    swap(arr[j], arr[j + gap]);
 return arr[4];//return the median 
}

//Image salt and pepper 
void salt(Mat &image, int num) 
{      
 if (!image.data) return;//Prevent incoming empty images 
 int i, j;
 srand(time(NULL));
 for (int x = 0 ; x < num; ++x)
 {
  i = rand() % image.rows;
  j = rand() % image.cols;
  image.at(i, j)[0] = 255;
  image.at(i, j)[1] = 255;
  image.at(i, j)[2] = 255;
 }
}

//中值滤波函数 
void MedianFlitering(const Mat &src, Mat &dst)
{
 if (!src.data)
  return;
 Mat _dst(src.size(), src.type());
 for (int i = 0; i
  for (int j = 0; j < src.cols; ++j)
  {
   if ((i - 1) > 0 && (i + 1) < src.rows && (j - 1) > 0 && (j + 1) < src.cols)
   {
    _dst.at(i, j)[0] = Median(src.at(i, j)[0], src.at(i + 1, j + 1)[0],
     src.at(i + 1, j)[0], src.at(i, j + 1)[0], src.at(i + 1, j - 1)[0],
     src.at(i - 1, j + 1)[0], src.at(i - 1, j)[0], src.at(i, j - 1)[0],
     src.at(i - 1, j - 1)[0]);
    _dst.at(i, j)[1] = Median(src.at(i, j)[1], src.at(i + 1, j + 1)[1],
     src.at(i + 1, j)[1], src.at(i, j + 1)[1], src.at(i + 1, j - 1)[1],
     src.at(i - 1, j + 1)[1], src.at(i - 1, j)[1], src.at(i, j - 1)[1],
     src.at(i - 1, j - 1)[1]);
    _dst.at(i, j)[2] = Median(src.at(i, j)[2], src.at(i + 1, j + 1)[2],
     src.at(i + 1, j)[2], src.at(i, j + 1)[2], src.at(i + 1, j - 1)[2],
     src.at(i - 1, j + 1)[2], src.at(i - 1, j)[2], src.at(i, j - 1)[2],
     src.at(i - 1, j - 1)[2]);
   }
   else
    _dst.at(i, j) = src.at(i, j);
  }
 _dst.copyTo(dst);//拷贝 
}


void main()

{
 Mat image = imread("fzh.jpg");

 Mat Salt_Image;
 image.copyTo(Salt_Image);
 salt(Salt_Image, 3000);

 Mat image3, image4;
 MedianFlitering(Salt_Image, image3);
 medianBlur(Salt_Image, image4, 3);
 imshow("Original image", image);
 imshow("After custom median filtering", image3);
 imshow("openCV Built-in median filter", image4);
 waitKey(); 
}

4. Realization effect diagram


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325756096&siteId=291194637