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要怎麼看最新回應呢?找不到像無名小站一樣,網頁右邊有專屬的回應欄位
讚讚
嗨~我已經新增「迴響」模組,你可以在部落格右側看到最新五個迴響~
之前我有想過要不要放,沒想到真有這個需求,那就放在那兒給大家按好嚕:)
讚讚