OpenCV有太多好玩的程式,而且好玩到我半夜不想睡覺XD~過去我常玩影像處理軟體,只是操作介面就可以讓我玩得很開心,如今可以接觸程式碼來調整更細節的部份,讓我玩起來更加有成就感,也許在不久的將來,我就可以將OpenCV寫到手機上去跑,讓身邊的親朋好友目睹我的傑作~哈!話說,最近Instagram紅透半面天,我也來寫一個吧~就從影像模糊化 (Image Smoothing)開始。
- 環境設定參考:Visual Studio 2010 安裝 OpenCV 2.4 beta
- 範例程式:C:\OpenCV2.4beta\samples\cpp\tutorial_code\ImgProc\Smoothing.cpp
/** Theme: Image Smoothing compiler: Visual Studio 2010 with OpenCV 2.4 beta Date: 101/05/24 Author: HappyMan Blog: https://cg2010studio.wordpress.com/ */ #include <iostream> #include <vector> #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/features2d/features2d.hpp" using namespace std; using namespace cv; /// Global Variables int DELAY_CAPTION = 1500; int DELAY_BLUR = 100; int MAX_KERNEL_LENGTH = 31; int THRESHOLD = 7; Mat src; Mat dst; char window_name[] = "Smoothing Demo"; /// Function headers int display_caption( char* caption ); int display_dst( int delay ); int main( int argc, char** argv ) { namedWindow( window_name, CV_WINDOW_AUTOSIZE ); /// Load the source image src = imread( "HappyMan's Girl.jpg", 1 ); if( display_caption( "Original Image" ) != 0 ) { return 0; } dst = src.clone(); if( display_dst( DELAY_CAPTION ) != 0 ) { return 0; } /// Applying Homogeneous blur if( 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(i==THRESHOLD) imwrite( "girl_Homogeneous.jpg", dst ); if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } } /// Applying Gaussian blur if( 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(i==THRESHOLD) imwrite( "girl_Gaussian.jpg", dst ); if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } } /// Applying Median blur if( display_caption( "Median Blur" ) != 0 ) { return 0; } for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 ) { medianBlur ( src, dst, i ); if(i==THRESHOLD) imwrite( "girl_Median.jpg", dst ); if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } } /// Applying Bilateral Filter if( 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(i==THRESHOLD) imwrite( "girl_Bilateral.jpg", dst ); if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } } /// Wait until user press a key display_caption( "End: Press a key!" ); waitKey(0); return 0; } int display_caption( char* caption ) { dst = Mat::zeros( src.size(), src.type() ); putText( dst, caption, Point( src.cols/4, src.rows/2), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255) ); imshow( window_name, dst ); int c = waitKey( DELAY_CAPTION ); if( c >= 0 ) { return -1; } return 0; } int display_dst( int delay ) { imshow( window_name, dst ); int c = waitKey ( delay ); if( c >= 0 ) { return -1; } return 0; }
程式會陸續demo四種篩選效果:
- Homogeneous Blur
- Gaussian Blur
- Median Blur
- Bilateral Blur
Gaussian Blur和Bilateral Blur目前我讀論文比較常見,也許影像處理軟體都有這些效果,只是它總不會告訴你這叫什麼效果,比較好一點的軟體會有預覽圖給你參考。
我使用我的MV女孩相片來demo:
程式每個效果都會跑一個迴圈,效果的程度會逐漸加大直到MAX_KERNEL_LENGTH,另外我設定THRESHOLD來儲存影像,陸續設定7、15、29三個閥值得到的結果來展示差異。(點圖可放大)
Homogeneous Blur
Gaussian Blur
Median Blur
Bilateral Blur
除非要深入研究模糊技術,不然只要效果是我們要的就直接拿來用吧!看似Bilateral Blur沒啥變化,事實上它的效果是有做保留邊緣的動作,也就是若顏色差異幅度太大,就會判定它是邊緣而不給予模糊,而顏色差異幅度較小,就會模糊化。簡單來Bilateral Blur可以消除雜訊,有篇論文可參考:Fast Bilateral Filtering for the Display of High-Dynamic-Range Images,想簡單瞭解理論可以參考:雙邊濾波器 (Bilateral Filter)。
我們也可以觀察到字體的變化,模糊化的程度挺有趣的呢!
參考:OpenCV v2.4.0 documentation » Image Processing、【OpenCV】鄰域濾波:方框、高斯、中值、雙邊濾波。
Comments on: "[OpenCV] 影像模糊化 (Image Smoothing)" (6)
[…] 在了解雙邊濾波器 (Bilateral Filter)理論之後,來試驗程試跑出來的效果。比起其它影像模糊化 (Image Smoothing)的方法,雙邊濾波器執行時間較長然模糊效果較佳!我所使用的筆電跑本程式每張圖約2.5分鐘。 […]
讚讚
MEDIAN BLUR 好像將深色部份強調出來一樣
讚讚
你說的沒錯,有那種效果:)
讚讚
[…] 看了上圖就可以知道雙邊濾波器可以做到怎樣的效果,此外還可以比較其它濾波器的效果,可以參考我的文章:影像模糊化 (Image Smoothing),是我以OpenCV提供的模糊化函式來作測試。 […]
讚讚
真的很好玩,一張張的新影像讓我好幾次玩到隔天早上!請問你的Blog要怎麼看最新回應呢?找不到像無名小站一樣,網頁右邊有專屬的回應欄位
讚讚
嗨~我已經新增「迴響」模組,你可以在部落格右側看到最新五個迴響~
之前我有想過要不要放,沒想到真有這個需求,那就放在那兒給大家按好嚕:)
讚讚