PhotoShop算法實現進階-模糊濾鏡-運動模糊(二十四)
來源:程序員人生 發布時間:2014-12-18 08:46:56 閱讀次數:3770次
PhotoShop算法實現進階-模糊濾鏡-運動模糊(2104)
kezunhai@gmail.com
http://blog.csdn.net/kezunhai
造成圖象退化或說使圖象模糊的緣由有很多種,如果是由于在攝像時相機和被攝景物之間有相對運動而釀成的圖象模糊則稱為運動模糊。所得到圖象中的景物常常會模糊不清,我們稱之為運動模糊圖象。運動模糊(Motion Blur)是1種抓取物體運動狀態效果的濾鏡,主要利用物體運動時暴光的攝影手法,摹擬出在攝像中拍攝運動物體的間接暴光功能,從而使圖象產生出1種動態效果。它通經常使用來制造物體掠過或移動的效果。
實現原理:運動模糊濾鏡沿特定的方向,并以特定的強度進行模糊處理。首先,在數學上,Y軸向上為正,而在圖象處理中,Y軸向下為正,所以在獲得用戶指定方向角度后,應先將其沿正方形旋轉180°;接著,解決圖象在指定方向上的位移問題。運動莫不是簡單地將圖象在指定的圖象上移來移去,而是在距離限定的范圍內,按某種方式復制并疊加像素。簡單地可以看成,將1幅圖象的多張副本疊放在指定的方向上,然后取其平均值;最后,要解決的問題就是圖象的透明度,處理Alpha分類,這樣終究產生的模糊效果才更理想。
實現算法:
// 添加運動模糊效果
// angle:運動的方向, distance:運動的距離
// 這里只是粗略的計算,以dx的長度為準,也能夠以dy或dx+dy等長度為準
// 如果需要更精確的計算,請參考有關專業文獻
void PhotoShop::MotionBlur(Mat& img, Mat& dst, int angle/* =30 */, int distance/* =100 */)
{
angle = angle%360;
if ( distance <1 ) distance = 1;
if ( distance > 200) distance = 200;
double radian = ((double)angle+180.0)/180.0*PI; // 角度轉弧度
int dx = (int)((double)distance* cos(radian)+0.5);
int dy = (int)((double)distance* sin(radian)+0.5);
int sign;
if ( dx<0) sign = ⑴;
if ( dx>0) sign = 1;
int height = img.rows;
int width = img.cols;
int chns = img.channels();
if (dst.empty())
dst.create(height, width, img.type());
int i,j ,k, i0, j0, p, sum, count;
for ( i=0; i<height; i++)
{
unsigned char* dstData = (unsigned char*)dst.data + dst.step*i;
for ( j=0; j<width; j++)
{
for ( k=0; k<chns; k++)
{
sum = 0, count =0;
for ( p=0; p<abs(dx); p++)
{
i0 = i + p*sign;
j0 = j + p*sign;
if ( i0>=0 && i0<height && j0>=0 && j0<width)
{
count++;
sum += getPixel(img, i0, j0, k);
}
}
if ( count == 0)
{
dstData[j*chns+k] = getPixel(img, i, j, k);
}
else
{
dstData[j*chns+k] = saturate_cast<uchar>(sum/(double)count+0.5);
}
}// for k
} // for j
}
}
測試效果(angle=60, distance = 50):

再來張女神的最愛:

下面這篇文章詳細介紹了運動模糊,有興趣的讀者可以參考:
1、甚么是運動模糊(Motion Blur)
2、 高質量單幅圖片運動去模糊
作者:kezunhai 出處:http://blog.csdn.net/kezunhai 歡迎轉載或分享,但請務必聲明文章出處。
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈