opencv学习小结(7) – 使用中值滤波来平滑图像

中值滤波:我们可以讲中值滤波应用到图像处理中。依然,我们在图像中去3*3的矩阵,里面有9个像素点,我们将9个像素进行排序,最后将这个矩阵的中心点赋值为这九个像素的中值。

预处理图像

例程如下:

//求九个人形的中值
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)//希尔排序
    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];//返回中值
}
//中值滤波函数
void MedianFlitering(const Mat &src, Mat &dst) 
{
  if (!src.data)return;
  Mat _dst(src.size(), src.type());
  for (int i = 0; i < src.rows; ++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<Vec3b>(i, j)[0] = Median(src.at<Vec3b>(i, j)[0], src.at<Vec3b>(i + 1, j + 1)[0],
          src.at<Vec3b>(i + 1, j)[0], src.at<Vec3b>(i, j + 1)[0], src.at<Vec3b>(i + 1, j - 1)[0],
          src.at<Vec3b>(i - 1, j + 1)[0], src.at<Vec3b>(i - 1, j)[0], src.at<Vec3b>(i, j - 1)[0],
          src.at<Vec3b>(i - 1, j - 1)[0]);
        _dst.at<Vec3b>(i, j)[1] = Median(src.at<Vec3b>(i, j)[1], src.at<Vec3b>(i + 1, j + 1)[1],
          src.at<Vec3b>(i + 1, j)[1], src.at<Vec3b>(i, j + 1)[1], src.at<Vec3b>(i + 1, j - 1)[1],
          src.at<Vec3b>(i - 1, j + 1)[1], src.at<Vec3b>(i - 1, j)[1], src.at<Vec3b>(i, j - 1)[1],
          src.at<Vec3b>(i - 1, j - 1)[1]);
        _dst.at<Vec3b>(i, j)[2] = Median(src.at<Vec3b>(i, j)[2], src.at<Vec3b>(i + 1, j + 1)[2],
          src.at<Vec3b>(i + 1, j)[2], src.at<Vec3b>(i, j + 1)[2], src.at<Vec3b>(i + 1, j - 1)[2],
          src.at<Vec3b>(i - 1, j + 1)[2], src.at<Vec3b>(i - 1, j)[2], src.at<Vec3b>(i, j - 1)[2],
          src.at<Vec3b>(i - 1, j - 1)[2]);
      }
      else
        _dst.at<Vec3b>(i, j) = src.at<Vec3b>(i, j);
    }
  _dst.copyTo(dst);//拷贝
}
 
int main()
{
        Mat srcImage = imread("1.jpg");
        namedWindow("我是小狮子.png", 1);
  imshow("我是小狮子.png", srcImage);
        /****************对图像加jiaoyan噪声,并进行中值滤波******************/
    	salt_noise(srcImage, 4000);
  pepper_noise(srcImage, 4000);
  imshow("我是小小小狮子.png", srcImage);
  Mat Medical_showImage, Medical_showImage_1;
  MedianFlitering(srcImage, Medical_showImage);
  medianBlur(srcImage, Medical_showImage_1, 3);
  imshow("自定义中值滤波处理后", Medical_showImage);
  imshow("openCV自带的中值滤波", Medical_showImage_1);
}

 

发表评论

邮箱地址不会被公开。 必填项已用*标注

12 + 10 =