目录
2.1 采用cv::cartToPolar和cv::polarToCart进行坐标变换
1 概念讲解及用处
直角坐标与极坐标变换是指在直角坐标系和极坐标系之间进行转换的过程。在直角坐标系下,每个点由其x和y坐标表示;而在极坐标系下,每个点由其距离和角度表示。直角坐标与极坐标变换可以用于不同领域的应用,如图像处理、机器视觉等。
图像处理:通过直角坐标与极坐标的相互转换,可以实现一些特定的图像处理操作,如滤波、边缘检测等。
机器视觉:在机器视觉领域中,直角坐标与极坐标变换常用于目标检测、特征提取以及图像匹配等任务。
2 函数详解
2.1 采用cv::cartToPolar和cv::polarToCart进行坐标变换
在OpenCV中,直角坐标与极坐标变换的主要函数为cv::cartToPolar和cv::polarToCart。
void cv::cartToPolar(
InputArray x, // 输入的x坐标
InputArray y, // 输入的y坐标
OutputArray magnitude, // 输出的距离
OutputArray angle, // 输出的角度
bool angleInDegrees = false // 角度是否以度为单位,默认为弧度
);
void cv::polarToCart(
InputArray magnitude, // 输入的距离
InputArray angle, // 输入的角度
OutputArray x, // 输出的x坐标
OutputArray y, // 输出的y坐标
bool angleInDegrees = false // 角度是否以度为单位,默认为弧度
);
2.1 采用cv::warpPolar()进行坐标变换
在OpenCV中,直角坐标与极坐标变换的也可以使用函数为warpPolar()进行变换。warpPolar函数是OpenCV中用于执行极坐标和直角坐标之间转换的函数。它可以将图像从直角坐标系(笛卡尔坐标系)转换为极坐标系,或者将图像从极坐标系转换回直角坐标系。
以下是warpPolar函数的完整原型:
void warpPolar(InputArray src, OutputArray dst, Size dsize, Point2f center, double maxRadius, int flags);
参数说明:
src:输入图像,可以是单通道或多通道图像。
dst:输出图像,用于存储结果。
dsize:目标图像大小,当进行直角坐标到极坐标的转换时,指定输出图像的尺寸;当进行极坐标到直角坐标的转换时,指定输出图像的尺寸与输入图像相同。
center:极坐标的原点位置,即旋转中心点。
maxRadius:极坐标的最大半径。
flags:插值方式和极坐标映射方式标志位,两个方法之间用+或|连接。
极坐标映射方式有:
WARP_POLAR_LINEAR以选择线性极轴映射(默认值)
WARP_POLAR_LOG以选择半对数极坐标映射
WARP_INVERSE_MAP进行反向映射。
warpPolar函数实现了两种模式的转换:
直角坐标到极坐标:当dsize参数非空时,函数将输入图像从直角坐标系转换为极坐标系,并将结果存储在dst中。转换过程中,会根据center和maxRadius定义的原点位置和半径范围进行变换。
极坐标到直角坐标:当dsize参数为空时,函数将输入图像从极坐标系转换为直角坐标系,并将结果存储在dst中。转换过程中,会根据center和maxRadius定义的原点位置和半径范围进行变换。
需要注意的是,在进行极坐标到直角坐标的转换时,需要提供与输入图像相同尺寸的目标图像大小(dsize),以确保输出图像尺寸正确。
3 数学原理及数学推导公式
3.1 直角坐标到极坐标的转换
数学原理及推导公式如下:
3.2 极坐标到直角坐标的转换
数学原理及推导公式如下:
其中,(x, y)是直角坐标系中的点坐标,(r, )是极坐标系中的距离和角度。
4 用C++编写代码进行实现
4.1 示例代码1
下面是一个使用OpenCV和C++实现直角坐标与极坐标变换的示例代码:
#include <opencv2/opencv.hpp>
int main()
{
// 定义直角坐标系下的x和y坐标
cv::Mat x = cv::Mat::ones(3, 3, CV_32F) * 2; // x坐标为常数2
cv::Mat y = cv::Mat::ones(3, 3, CV_32F) * 3; // y坐标为常数3
// 定义极坐标变量
cv::Mat magnitude, angle;
// 进行直角坐标到极坐标的转换
cv::cartToPolar(x, y, magnitude, angle);
// 输出结果
std::cout << "Magnitude:\n" << magnitude << std::endl;
std::cout << "Angle:\n" << angle << std::endl;
// 定义极坐标
cv::Mat magnitude2 = cv::Mat::ones(3, 3, CV_32F) * 5; // 距离为常数5
cv::Mat angle2 = cv::Mat::ones(3, 3, CV_32F) * CV_PI / 4; // 角度为常数π/4
// 定义直角坐标变量
cv::Mat x2, y2;
// 进行极坐标到直角坐标的转换
cv::polarToCart(magnitude2, angle2, x2, y2);
// 输出结果
std::cout << "X:\n" << x2 << std::endl;
std::cout << "Y:\n" << y2 << std::endl;
return 0;
}
以上代码中,我们首先定义了直角坐标系下的x和y坐标,然后使用cv::cartToPolar函数将其转换为极坐标系下的距离和角度。接着,我们定义了极坐标系下的距离和角度,然后使用cv::polarToCart函数将其转换为直角坐标系下的x和y坐标。最后,输出转换结果。
4.2 示例代码2
#include <opencv2/opencv.hpp>
int main() {
// 读取图像
cv::Mat image = cv::imread("zsxq.png");
// 将图像从直角坐标系转换为极坐标系
cv::Mat polarImage;
double maxRadius = hypot(image.cols / 2, image.rows / 2); // 极坐标半径范围
cv::Point2f center(image.cols / 2, image.rows / 2); // 极坐标原点位置
double thetaRange = 360.0; // 极坐标角度范围
cv::warpPolar(image, polarImage, cv::Size(), center, maxRadius, cv::INTER_LINEAR + cv::WARP_FILL_OUTLIERS);
// 显示极坐标图像
// 将图像从极坐标系转换为直角坐标系
cv::Mat cartesianImage;
cv::warpPolar(polarImage, cartesianImage, image.size(), center, maxRadius, cv::INTER_LINEAR + cv::WARP_INVERSE_MAP);
// 显示直角坐标图像
cv::imshow("Polar Image", polarImage);
cv::imshow("Cartesian Image", cartesianImage);
cv::waitKey(0);
return 0;
}
在示例代码中,我们首先读取一幅图像,然后使用warpPolar函数将图像从直角坐标系转换为极坐标系。我们定义了极坐标的原点位置和半径范围,并指定了插值方法。得到的极坐标图像存储在polarImage中,并显示出来。
接下来,我们再次使用warpPolar函数将极坐标图像转换回直角坐标系。我们传入了目标图像大小和其他参数,包括原点位置、半径范围和插值方法。得到的直角坐标图像存储在cartesianImage中,并显示出来。