opencv影象處理-------高斯濾波
阿新 • • 發佈:2018-11-12
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); }