一、函數原型
該函數
參數
angleInDegrees
默認為false,即弧度,當置為true時,則輸出為角度。
phase函數根據函數
來計算角度,計算精度大約為0.3弧度,當x,y相等時,angle為0。

數學上函數atan2為:

該函數的值域為,可以通過對負數結果加
的方法,將函數的結果映射到
范圍內。
而c++中atan2函數是通過正切值返回弧度的,並通過判斷x,y的正負決定象限,因此c++中atan2函數值域是從-Pi到Pi的。
二、小實驗
Mat mat1(Size(
4
,
1
), CV_32FC1), mat2(Size(
4
,
1
), CV_32FC1), mat3;
mat1.at < float > ( 0 , 0 ) = 1 ; mat2.at < float > ( 0 , 0 ) = 1 ;
mat1.at < float > ( 0 , 1 ) = 1 ; mat2.at < float > ( 0 , 1 ) = - 1 ;
mat1.at < float > ( 0 , 2 ) = - 1 ; mat2.at < float > ( 0 , 2 ) = 1 ;
mat1.at < float > ( 0 , 3 ) = - 1 ; mat2.at < float > ( 0 , 3 ) = - 1 ;
phase(mat1,mat2,mat3, true );
mat1.at < float > ( 0 , 0 ) = 1 ; mat2.at < float > ( 0 , 0 ) = 1 ;
mat1.at < float > ( 0 , 1 ) = 1 ; mat2.at < float > ( 0 , 1 ) = - 1 ;
mat1.at < float > ( 0 , 2 ) = - 1 ; mat2.at < float > ( 0 , 2 ) = 1 ;
mat1.at < float > ( 0 , 3 ) = - 1 ; mat2.at < float > ( 0 , 3 ) = - 1 ;
phase(mat1,mat2,mat3, true );
最后mat3的計算結果:。由此可以看出opencv phase計算出的角度從0°-360°是已x軸正方向為0°,逆時針旋轉增加,符合我們平常角度的計算方式。
三、實際運用
使用函數來計算圖像方向場
原始圖像
代碼
//變量
Mat img = cv::imread( "e:/template/***。png",0);
Mat grad1,grad2,angle;
Sobel(img, grad1, CV_64FC1, 1, 0); //求梯度
Sobel(img, grad2, CV_64FC1, 0, 1);
blur(grad1,grad1,Size(6,6));
blur(grad2,grad2,Size(6,6));
phase(grad1, grad2, angle, true); //求角度
normalize(angle, angle, 0, 255, NORM_MINMAX); //歸一化 方便顯示,和實際數據沒有關系
angle.convertTo(angle,CV_8UC1);
說明
在進行角度計算之前,對sobel計算的兩個結果分別進行了6*6的平均卷積,這是基本的去噪思路。而后到phase一行,角度就已經求出來了,后面是為了方便顯示。
注意,這里的角度是以x正方向為0,以逆時針為正方向,0-360的度量。並且顯而易見分了內外。這個圓是比較簡單的,如果對於復雜圖像,就必須對角度的概念有深入理解。