opencv-------高斯滤波
高斯濾波(Gauss Filter)是線性濾波中的一種。在OpenCV圖像濾波處理中,高斯濾波用于平滑圖像,或者說是圖像模糊處理,因此高斯濾波是低通的。其廣泛的應用在圖像處理的減噪過程中,尤其是被高斯噪聲所污染的圖像上。
高斯濾波的基本思想是: 圖像上的每一個像素點的值,都由其本身和鄰域內(nèi)其他像素點的值經(jīng)過加權平均后得到。其具體操作是,用一個核(又稱為卷積核、掩模、矩陣)掃描圖像中每一個像素點,將鄰域內(nèi)各個像素值與對應位置的權值相稱并求和。從數(shù)學的角度來看,高斯濾波的過程是圖像與高斯正態(tài)分布做卷積操作。
注意: 高斯濾波是將二維高斯正態(tài)分布放在圖像矩陣上做卷積運算。考慮的是鄰域內(nèi)像素值的空間距離關系,因此對彩色圖像處理時應分通道進行操作,也就是說操作的圖像原矩陣時用單通道數(shù)據(jù),最后合并為彩色圖像。
一、幾個概念
1. 什么是低通濾波、平滑圖像、圖像模糊處理?
平滑圖像與圖像模糊處理是相同的含義。平滑處理即是通過操作后,使得圖像的像素值與鄰域內(nèi)其他像素值的的變化程度減小。在一張圖像上,邊緣的像素值是變化程度最劇烈的地方,而其他相對平緩。因此,平滑圖像最直觀的表現(xiàn)是圖像的上物體的邊緣輪廓變得模糊。
低通濾波是指僅允許低頻率信號通過。一張圖像上的大部分能量聚集在低頻和中頻上,而高頻大多是圖像中物體的邊緣部分,也有可能是高頻噪聲點。在單通道中,各像素點的取值都在(0~255)中,因此,低通濾波通過一定的闕值設置,有去除高頻信號和平緩邊緣的效果。
2. 什么是核(又稱為卷積核、掩模、矩陣)?
核的本質其實就是一個大小固定、由數(shù)值參數(shù)組成的數(shù)學矩陣,例如一個3*3的核就是一個3*3的矩陣,而矩陣中的數(shù)據(jù)則為權值。
3. 什么是卷積運算?
卷積運算是指輸入圖像中某一像素點的鄰域的各個值(包括該點)與卷積算子中的值做矩陣相乘運算,最后得到輸出值。
卷積算子的公式:
g(i,j) 代表原圖像矩陣上的(i,j)點的值,它是輸出值。
f(i-k,j-l) 代表原圖像矩陣上(i,j)點的鄰域中的對應點的值。
h(k,,l) 代表與f(i-k , j-l)這個值在核對應位置的點的值
請看下圖:這里用的是f(i-k,j-l)h(k,l)
由上圖我們看到,矩陣f是將要進行操作的圖像矩陣,當前的(i,j)是(2,2)點。h為核,其以中心(0,0)為參考點。因此f矩陣對應范圍即為f(2,2)的鄰域。矩陣g為圖像輸出矩陣,g(2,2)的值為輸出值。
注意:卷積算子和相關算子在核上是180度翻轉的矩陣,請不要搞混
4.核(卷積核、掩模、矩陣等)
在3的卷積運算中,用到的公式是:
g(i, j) = ∑ f(i-k, j-l)h(k, l) 。其中 k,l代表核上的坐標。而核的坐標明顯與數(shù)組下標不一致。因此,我們需要做一個轉換以滿足用數(shù)組下標來訪問該核的數(shù)據(jù)。
假設有3*3數(shù)組a,它與核的對應關系為
a(0, 0) ===> h(-1, -1) a(0, 1) ===> h(-1, 0) a(0, 2) ===> h(-1, 1)
a(1, 0) ===> h(0, -1) a(1, 1) ===> h(0, 0) a(1, 2) ===> h(0, 1)
a(2, 0) ===> h(1, -1) a(2, 1) ===> h(1, 0) a(2, 2) ===> h(1, 1)
對于3*3數(shù)組,其下標是0開始的,假設該數(shù)組的參考點(ai, aj)為中心,則有
g(i, j) = ∑ f(i-(k-ai), j-(l-aj))h(k, l)
帶入數(shù)組參考點(1, 1),則有
g(i, j) = ∑ f(i-(k-1), j-(l-1))h(k, l)
此時,k,l可以從0開始取值
?5.圖像通道分離與合并(cv::Mat)
// src 原圖像,多通道// [1] 彩色圖片通道分離std::vector<cv::Mat> channels;cv::split(&src, channels);// [3] 濾波// OpenCV中操作// channels[0] ==> B通道// channels[1] ==> G通道// channels[2] ==> R通道// 省略對各個通道的處理// [4] 合并返回cv::merge(channels, *dst);二、高斯函數(shù)
高斯濾波,顧名思義,這是一個建立在高斯正態(tài)分布基礎上的濾波器。首先我們來了解高斯函數(shù)。(圖片來源于網(wǎng)絡)
一維高斯函數(shù):
可以看到,G(x)的跟sigma的取值有極大的關系。sigma取值越大,圖像越平緩,sigma取值越小,圖像越尖銳。
二維高斯函數(shù):
二維高斯是構建高斯濾波器的基礎。可以看到,G(x,y)在x軸y軸上的分布是一個突起的帽子的形狀。這里的sigma可以看作兩個值,一個是x軸上的分量sigmaX,另一個是y軸上的分量sigmaY。對圖像處理可以直接使用sigma并對圖像的行列操作,也可以用sigmaX對圖像的行操作,再用sigmaY對圖像的列操作。它們是等價的。
當sigmaX和sigmaY取值越大,整個形狀趨近于扁平;當sigmaX和sigmaY取值越小,整個形狀越突起。
高斯濾波原理就是將上圖的二維正態(tài)分布應用在二維的矩陣上,G(x,y)的值就是矩陣上的權值,將得到的權值進行歸一化,將權值的范圍約束在[0,1]之間,并且所有的值的總和為1。
假設一個3*3的核,sigma取值1.5以及sigma取5.0,歸一化后其權值分布分別是:
假設一個5*5的核,sigma取值1.5以及sigma取5.0,經(jīng)歸一化后其權值分布分別是:
可以看到,權值的分布是以中間高四周低來分布的。并且距離中心越遠,其對中心點的影響就越小,權值也就越小。
因此可以總結:
(1)在核大小固定的情況下,sigma值越大,權值分布越平緩。因此,鄰域各個點的值對輸出值的影響越大,最終結果造成圖像越模糊。
(2)在核大小固定的情況下,sigma值越小,權值分布越突起。因此,鄰域各個點的值對輸出值的影響越小,圖像變化也越小。假如中心點權值為1,其他點權值為0,那么最終結果是圖像沒有任何變化。
(3)sigma固定時,核越大圖像越模糊。
(4)sigma固定時,核越小圖像變化越小。
三、高斯濾波器實現(xiàn)
首先看效果:
對于椒鹽圖作處理
對于高斯噪聲圖作處理
(1)main函數(shù):讀取圖片 ==> 高斯濾波 ==> 結果顯示
int main(void) {// [1] src讀入圖片cv::Mat src = cv::imread("Median_pic.jpg");// [2] dst目標圖片cv::Mat dst;// [3] 高斯濾波 sigma越大越平越模糊myGaussianFilter(&src, &dst, 5, 1.5f);// [4] 窗體顯示cv::imshow("src", src);cv::imshow("dst", dst);cv::waitKey(0);cv::destroyAllWindows();return 0; }(2)彩色圖像通道分離處理,每個通道都進行高斯濾波,最后合并
void myGaussianFilter(cv::Mat *src, cv::Mat *dst, int n, double sigma) {// [1] 初始化*dst = (*src).clone();// [2] 彩色圖片通道分離std::vector<cv::Mat> channels;cv::split(*src, channels);// [3] 濾波// [3-1] 確定高斯正態(tài)矩陣double **array = getGaussianArray(n, sigma);// [3-2] 高斯濾波處理for (int i = 0; i < 3; i++) {gaussian(&channels[i], array, n);}// [4] 合并返回cv::merge(channels, *dst);return ; }(3)生成高斯正態(tài)分布核(卷積核,掩模等)
/* 獲取高斯分布數(shù)組 (核大小, sigma值) */ double **getGaussianArray(int arr_size, double sigma) {int i, j;// [1] 初始化權值數(shù)組double **array = new double*[arr_size];for (i = 0; i < arr_size; i++) {array[i] = new double[arr_size];}// [2] 高斯分布計算int center_i, center_j;center_i = center_j = arr_size / 2;double pi = 3.141592653589793;double sum = 0.0f;// [2-1] 高斯函數(shù)for (i = 0; i < arr_size; i++ ) {for (j = 0; j < arr_size; j++) {array[i][j] = //后面進行歸一化,這部分可以不用//0.5f *pi*(sigma*sigma) * exp( -(1.0f)* ( ((i-center_i)*(i-center_i)+(j-center_j)*(j-center_j)) /(2.0f*sigma*sigma) ));sum += array[i][j];}}// [2-2] 歸一化求權值for (i = 0; i < arr_size; i++) {for (j = 0; j < arr_size; j++) {array[i][j] /= sum;printf(" [%.15f] ", array[i][j]);}printf("\n");}return array; }(4)進行高斯濾波操作
/* 高斯濾波 (待處理單通道圖片, 高斯分布數(shù)組, 高斯數(shù)組大小(核大小) ) */ void gaussian(cv::Mat *_src, double **_array, int _size) {cv::Mat temp = (*_src).clone();// [1] 掃描for (int i = 0; i < (*_src).rows; i++) {for (int j = 0; j < (*_src).cols; j++) {// [2] 忽略邊緣if (i > (_size / 2) - 1 && j > (_size / 2) - 1 &&i < (*_src).rows - (_size / 2) && j < (*_src).cols - (_size / 2)) {// [3] 找到圖像輸入點f(i,j),以輸入點為中心與核中心對齊// 核心為中心參考點 卷積算子=>高斯矩陣180度轉向計算// x y 代表卷積核的權值坐標 i j 代表圖像輸入點坐標// 卷積算子 (f*g)(i,j) = f(i-k,j-l)g(k,l) f代表圖像輸入 g代表核// 帶入核參考點 (f*g)(i,j) = f(i-(k-ai), j-(l-aj))g(k,l) ai,aj 核參考點// 加權求和 注意:核的坐標以左上0,0起點double sum = 0.0;for (int k = 0; k < _size; k++) {for (int l = 0; l < _size; l++) {sum += (*_src).ptr<uchar>(i-k+(_size/2))[j-l+(_size/2)] * _array[k][l];}}// 放入中間結果,計算所得的值與沒有計算的值不能混用temp.ptr<uchar>(i)[j] = sum;}}}// 放入原圖(*_src) = temp.clone(); }總結
以上是生活随笔為你收集整理的opencv-------高斯滤波的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: swal 弹窗html页面,SweetA
- 下一篇: 德州学院计算机专业地址,德州学院 计算机