基于OpenCV平滑图像
cv::blur
cv::GaussianBlur (高斯模糊)
cv::medianBlur (中值模糊)
cv::bilateralFilter (雙邊濾波)
理論
進行圖像平滑的目的有很多,本文的目的是減少噪音。
線性濾波為最常用濾波方式, 輸出像素的值 g(i,j) 取決于一組輸入像素f(i+k,j+l)的加權和:
- g(i,j)=∑k,lf(i+k,j+l)h(k,l)
其中,h(k,l) 被稱為核(濾波器的系數).也就是一個滑動窗.
歸一化塊濾波器
最簡單的濾波器,每一個像素的輸出值,是其核決定的相鄰像素的均值。核的形式如下:
- K=1Kwidth?Kheight???????11..111..111..1...............11111???????
高斯濾波
高斯濾波是一種線性平滑濾波,適用于消除高斯噪聲,廣泛應用于圖像處理的減噪過程。通俗的講,高斯濾波就是對整幅圖像進行加權平均的過程,每一個像素點的值,都由其本身和鄰域內的其他像素值經過加權平均后得到。高斯濾波的具體操作是:用一個模板(或稱卷積、掩模)掃描圖像中的每一個像素,用模板確定的鄰域內像素的加權平均灰度值去替代模板中心像素點的值。
可能是最有用的濾波器 (不是最快的).高斯濾波是通過像素點和高斯核卷積和實現。通過下圖作說明,還記得 1維 高斯核像什么么?
-
假設圖像是1維的, 可以看到排在中間位置的像素具有最大的權重. 相鄰像素的權因子隨著和中心像素的距離的增大遞減。
備注:- 2維高斯核函數可以表示為 : G0(x,y)=Ae?(x?μx)22σ2x+?(y?μy)22σ2y
- 2維高斯核函數可以表示為 : G0(x,y)=Ae?(x?μx)22σ2x+?(y?μy)22σ2y
? 其中 μ 是均值 (the peak) , σ 表示方差 (per each of the variables x and y)
中值濾波
中值濾波是基于排序統計理論的一種能有效抑制噪聲的非線性信號處理技術,中值濾波的基本原理是把數字圖像或數字序列中一點的值用該點的一個鄰域中各點值的中值代替,讓周圍的像素值接近的真實值,從而消除孤立的噪聲點。中值濾波對脈沖噪聲有良好的濾除作用,特別是在濾除噪聲的同時,能夠保護信號的邊緣,使之不被模糊。這些優良特性是線性濾波方法所不具有的。
雙邊濾波
目前為止,已經介紹了一些圖像平滑方法,雖然消除了噪聲但是同事也平滑了邊緣。為了避免平滑邊緣可以使用雙邊濾波。
雙邊濾波(Bilateral filter)是一種非線性的濾波方法,是結合圖像的空間鄰近度和像素值相似度的一種折衷處理,同時考慮空域信息和灰度相似性,達到保邊去噪的目的。具有簡單、非迭代、局部的特點。
雙邊濾波器的好處是可以做邊緣保存(edge preserving),一般過去用的維納濾波或者高斯濾波去降噪,都會較明顯地模糊邊緣,對于高頻細節的保護效果并不明顯。雙邊濾波器顧名思義比高斯濾波多了一個高斯方差sigma-d,它是基于空間分布的高斯濾波函數,所以在邊緣附近,離的較遠的像素不會太多影響到邊緣上的像素值,這樣就保證了邊緣附近像素值的保存。但是由于保存了過多的高頻信息,對于彩色圖像里的高頻噪聲,雙邊濾波器不能夠干凈的濾掉,只能夠對于低頻信息進行較好的濾波。
和高斯濾波器類似,雙邊濾波器也考慮相鄰的像素分配的權重。這些權重有兩個組成部分,第一個是高斯濾波器相同權權重。第二個是考慮相鄰像素之間的強度的差異和評價。
詳細的介紹參見這里 this link
代碼
打開一副圖像并應用4種平滑方法。
/*** file Smoothing.cpp* brief Sample code for simple filters* author OpenCV team*/#include "opencv2/imgproc.hpp" #include "opencv2/imgcodecs.hpp" #include "opencv2/highgui.hpp"using namespace std; using namespace cv;/// Global Variables int DELAY_CAPTION = 1500; int DELAY_BLUR = 100; int MAX_KERNEL_LENGTH = 31;Mat src; Mat dst; char window_name[] = "Smoothing Demo";/// Function headers int display_caption( const char* caption ); int display_dst( int delay );/*** function main*/ int main( void ) {namedWindow( window_name, WINDOW_AUTOSIZE );/// Load the source imagesrc = imread( "lena.jpg", IMREAD_COLOR );if( display_caption( "Original Image" ) != 0 ) { return 0; }dst = src.clone();if( display_dst( DELAY_CAPTION ) != 0 ) { return 0; }/// Applying Homogeneous blurif( display_caption( "Homogeneous Blur" ) != 0 ) { return 0; }//![齊次模糊]for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 ){ blur( src, dst, Size( i, i ), Point(-1,-1) );if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }//![blur]/// Applying Gaussian blurif( display_caption( "Gaussian Blur" ) != 0 ) { return 0; }//![高斯濾波]for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 ){ GaussianBlur( src, dst, Size( i, i ), 0, 0 );if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }//![高斯濾波]/// Applying Median blurif( display_caption( "Median Blur" ) != 0 ) { return 0; }//![中值濾波]for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 ){ medianBlur ( src, dst, i );if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }//![中值濾波]/// Applying Bilateral Filterif( display_caption( "Bilateral Blur" ) != 0 ) { return 0; }//![雙邊濾波]for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 ){ bilateralFilter ( src, dst, i, i*2, i/2 );if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }//![雙邊濾波]/// Wait until user press a keydisplay_caption( "End: Press a key!" );waitKey(0);return 0; }/*** @function display_caption*/ int display_caption( const char* caption ) {dst = Mat::zeros( src.size(), src.type() );putText( dst, caption,Point( src.cols/4, src.rows/2),FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255) );imshow( window_name, dst );int c = waitKey( DELAY_CAPTION );if( c >= 0 ) { return -1; }return 0; }/*** @function display_dst*/ int display_dst( int delay ) {imshow( window_name, dst );int c = waitKey ( delay );if( c >= 0 ) { return -1; }return 0; }總結
以上是生活随笔為你收集整理的基于OpenCV平滑图像的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图像技术在直播中怎么用
- 下一篇: 基于OpenCV的膨胀和腐蚀