CV_EXPORTS_W void cartToPolar(InputArray x, InputArray y,
OutputArray magnitude, OutputArray angle,
bool angleInDegrees = false);
x:Mat,這必須是單精度或雙精度浮點數組
y:Mat,其大小和類型必須與x相同
magnitude:輸出與x相同大小和類型的大小數組
angle:與x具有相同大小和類型的角度的輸出數組;角度以弧度(從0到2*Pi)或度(0到360度)度量
angleInDegrees:标志,訓示結果是以弧度(預設情況下是以弧度)還是以度度量
注意:輸入數組必須具有相同精度
作用1:根據勾股定理求出另一條邊的長度和三角形的角度(y/x=tan α)。
作用2:取梯度幅值和方向。先用sobel求出水準和垂直方向的梯度,再用cartToPolar求出梯度幅值和方向。
輸入x/y均為2維向量,其實作如下:
代碼1:
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main() {
Mat xx = Mat(2, 3, CV_32FC1, Scalar(6, 0, 0));
Mat yy = Mat(2, 3, CV_32FC1, Scalar(6, 0, 0));
cout << xx << endl;
cout << yy << endl;
Mat mag, angle;
cartToPolar(xx, yy, mag, angle, true);
cout << mag << endl;
cout << angle << endl;
}
// out
//看xx和yy的0,0位置,都是6,根據勾股定理第三邊是6*根号2=8.485281,角度是45度。
[6, 6, 6;
6, 6, 6]
[6, 6, 6;
6, 6, 6]
[8.485281, 8.485281, 8.485281;
8.485281, 8.485281, 8.485281]
[44.990456, 44.990456, 44.990456;
44.990456, 44.990456, 44.990456]
代碼2:
vector<Point2f> sides;//建立容器存坐标
sides.push_back(Point2f(3, 4));
sides.push_back(Point2f(6, 8));
sides.push_back(Point2f(1, 1));
Mat xpts(sides.size(), 1, CV_32F, &sides[0].x, 2 * sizeof(float));
Mat ypts(sides.size(), 1, CV_32F, &sides[0].y, 2 * sizeof(float));
cout << "x: " << xpts.t() << endl;
cout << "y: " << ypts.t() << endl;
Mat magnitude, angle;
cartToPolar(xpts, ypts, magnitude, angle);//調用庫函數
cout << "\nmagnitude: " << magnitude.t();
cout << "\nangle: " << angle.t() *180. / CV_PI << endl;
x: [3, 6, 1]
y: [4, 8, 1]
//看xx和yy的0,0位置分别是3和4,根據勾股定理第三邊是5,4/3 = tanα,α=53.136284度
magnitude: [5, 10, 1.4142135]
angle: [53.136284, 53.136284, 44.990456]
參考:
https://zj-image-processing.readthedocs.io/zh_CN/latest/opencv/code/[cartToPolar]%E4%BA%8C%E7%BB%B4%E5%90%91%E9%87%8F%E7%9A%84%E5%A4%A7%E5%B0%8F%E5%92%8C%E8%A7%92%E5%BA%A6/
https://blog.csdn.net/qq_30460949/article/details/91393048
https://zhuanlan.zhihu.com/p/75705284