1. 程式人生 > >opencv影象處理-------高斯濾波

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);
}


​

​