opencv图像处理-------高斯滤波

opencv高斯滤波原理

          高斯滤波是一种线性平滑滤波器,运用此滤波器,图像中各个点的像素值由它邻域像素的加权累加值来替换。把邻域中每个像素位置对应的权重系数存放在一个矩阵中,矩阵中心的元素对应正在当前正在应用此滤波器的像素,此矩阵成为内核或者掩码,在这里高斯函数主要用于根据像素的位置坐标(可以是1维也可以是2维坐标)计算出对应的权重,得到权重矩阵(即内核)

  二维高斯函数

         一维高斯函数

不同sigma对应曲线,可以发现sigma越大,越接近中心点(运用滤波器的像素点)的像素权重越大。一个图像应用一个线性滤波器,相当于将内核移动到图像的每个像素上,并将每个对应像素乘以它对应的权重(这要取决于离被应用像素点的距离),这个运算成为卷积。

opencv高斯滤波示例及参数解析

           

cv::GaussianBlur(image,  // 输入图像
                result,  // 输出图像
		cv::Size(5, 5),  //  滤波器尺寸,即选取邻域矩阵大小
		  3); //控制高斯曲线形状的参数sigma,sigma越小,高斯曲线越高瘦,离中心点越近的点权重越大
	

简单高斯滤波自定义实现(便于理解,仅作参考)

​
​
double **getGuassionArray(int size,double sigma) //得到权重矩阵
{	
    int i, j;	
    double sum = 0.0;
	int center = size; //以第一个点的坐标为原点,求出中心点的坐标 	
    double **arr = new double*[size];//建立一个size*size大小的二维数组	
    for (i = 0; i < size; ++i)		
      arr[i] = new double[size];		
    for (i = 0; i < size; ++i)		
       for (j = 0; j < size; ++j) 
       {			
         arr[i][j] = exp(-((i - center)*(i - center) + (j - center)*(j - center)) / 
                    (sigma*sigma * 2));	//应用高斯函数	
         sum += arr[i][j];		
       }	
    for (i = 0; i < size; ++i)		
       for (j = 0; j < size; ++j)			
           arr[i][j] /= sum;	
    return arr;
} 
void Gaussian(const Mat image, Mat &result) 
{	
    if (!image.data) return;	
    double **arr;	
    Mat tmp(image.size(), image.type());	
    for (int i = 0; i < image.rows; ++i)		
      for (int j = 0; j < image.cols; ++j) 
     {	
      //边缘不进行处理			
      if ((i - 1) > 0 && (i + 1) < image.rows && (j - 1) > 0 && (j + 1) < image.cols) 
      {				
        arr = getGuassionArray(3, 1);//自定义得到的权值数组				
        tmp.at<Vec3b>(i, j)[0] = 0;				
        tmp.at<Vec3b>(i, j)[1] = 0;				
        tmp.at<Vec3b>(i, j)[2] = 0;				
        for (int x = 0; x < 3; ++x) 
       {					
         for (int y = 0; y < 3; ++y)
        {							
       tmp.at<Vec3b>(i, j)[0] += arr[x][y] * image.at<Vec3b>(i + 1 - x, j + 1 - y)[0];							
       tmp.at<Vec3b>(i, j)[1] += arr[x][y] * image.at<Vec3b>(i + 1 - x, j + 1 - y)[1];							
       tmp.at<Vec3b>(i, j)[2] += arr[x][y] * image.at<Vec3b>(i + 1 - x, j + 1 - y)[2];					
        }				
       }			
      }		
    }	
    tmp.copyTo(result);
}


​

​

猜你喜欢

转载自blog.csdn.net/qq_41598851/article/details/82961975