opencv学习小结-(4) 使用 均 值滤波来平滑图像

需要使用到该 库函数

CV_EXPORTS_W void blur( InputArray src, OutputArray dst, Size ksize, Point anchor = Point(-1,-1), int borderType = BORDER_DEFAULT );

均值滤波:线性平均滤波器,它通过求窗口内所有像素的平均值来得到中心像素点的像素值,就比如下图:

均值滤波示例程序如下:

//jun盐噪声
void salt_noise(Mat image, int n) 
{
 
  int i, j;
  for (int k = 0; k < n / 2; k++) {
 
    // rand() is the random number generator
    i = std::rand() % image.cols; // % 整除取余数运算符,rand=1022,cols=1000,rand%cols=22
    j = std::rand() % image.rows;
 
    if (image.type() == CV_8UC1) { // gray-level image
 
      image.at<uchar>(j, i) = 255; //at方法需要指定Mat变量返回值类型,如uchar等
 
    }
    else if (image.type() == CV_8UC3) { // color image
 
      image.at<cv::Vec3b>(j, i)[0] = 255; //cv::Vec3b为opencv定义的一个3个值的向量类型
      image.at<cv::Vec3b>(j, i)[1] = 255; //[]指定通道,B:0,G:1,R:2
      image.at<cv::Vec3b>(j, i)[2] = 255;
    }
  }
}
//椒噪声
void pepper_noise(Mat image, int n) 
{
 
  int i, j;
  for (int k = 0; k < n; k++) {
 
    // rand() is the random number generator
    i = std::rand() % image.cols; // % 整除取余数运算符,rand=1022,cols=1000,rand%cols=22
    j = std::rand() % image.rows;
 
    if (image.type() == CV_8UC1) { // gray-level image
 
      image.at<uchar>(j, i) = 0; //at方法需要指定Mat变量返回值类型,如uchar等
 
    }
    else if (image.type() == CV_8UC3) { // color image
 
      image.at<cv::Vec3b>(j, i)[0] = 0; //cv::Vec3b为opencv定义的一个3个值的向量类型
      image.at<cv::Vec3b>(j, i)[1] = 0; //[]指定通道,B:0,G:1,R:2
      image.at<cv::Vec3b>(j, i)[2] = 0;
    }
  }
}
 
//均值滤波
void AverFiltering(const Mat &src, Mat &dst) {
  if (!src.data) return;
  //at访问像素点
  for (int i = 1; i < src.rows; ++i)
    for (int j = 1; j < src.cols; ++j) {
      if ((i - 1 >= 0) && (j - 1) >= 0 && (i + 1) < src.rows && (j + 1) < src.cols) {//边缘不进行处理
        dst.at<Vec3b>(i, j)[0] = (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 + 1)[0] + src.at<Vec3b>(i, j + 1)[0] +
          src.at<Vec3b>(i + 1, j)[0]) / 9;
        dst.at<Vec3b>(i, j)[1] = (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)[1] + src.at<Vec3b>(i, j + 1)[1] +
          src.at<Vec3b>(i + 1, j)[1]) / 9;
        dst.at<Vec3b>(i, j)[2] = (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 + 1)[2] + src.at<Vec3b>(i, j + 1)[2] +
          src.at<Vec3b>(i + 1, j)[2]) / 9;
      }
      else {//边缘赋值
        dst.at<Vec3b>(i, j)[0] = src.at<Vec3b>(i, j)[0];
        dst.at<Vec3b>(i, j)[1] = src.at<Vec3b>(i, j)[1];
        dst.at<Vec3b>(i, j)[2] = src.at<Vec3b>(i, j)[2];
      }
    }
}
 
int main()
{
        Mat srcImage = imread("1.jpg");
  namedWindow(".jpg", 1);
  imshow(".jpg", srcImage);
  /*********************对图像进行椒盐化并进行均值滤波****************/
  Mat image1(srcImage.size(), srcImage.type());
  Mat image2;
  salt_noise(srcImage, 4000);
  pepper_noise(srcImage, 4000);
  imshow("均鞭智能生成图像", srcImage);
  AverFiltering(srcImage, image1);
  blur(srcImage, image2, Size(3, 3));//openCV库自带的均值滤波函数
  imshow("自定义均值滤波", image1);
  imshow("openCV自带的均值滤波", image2);
}

发表评论

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

3 + 12 =