本次介绍图像的透视变换和极坐标变换
图像的透视变换主要指的是按照物体成像投影规律进行变换,即将物体重新投影到新的成像平面,常用于机器人视觉导航中,透视前与透视后的图像之间的变换可以用3*3的变换矩阵表示,而该矩阵可以通过4个对应点的坐标获取,因此透视变换又称作“四点变换”。
Mat getPerspectiveTransform(const Point2f src[], const Point2f dst[], int solveMethod = DECOMP_LU)
src[]:原图像中的4个像素坐标
dst[]:目标图像中的4个像素坐标
solveMethod:选择计算透视变换矩阵方法的标志,一般情况下选用最佳主轴元素的高斯消元法DECOMP_LU
void warpPerspective(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags = INTER_LINEAR, int borderMode = BORDER_CONSTANT, const Scarlar & borderValue = Scalar())
src:输入图像
dst:透视变换后输出图像,与src数据类型相同,但是尺寸与dsize相同
M:3*3的变换矩阵
dsize:输出图像的尺寸
flags:插值方法标志
borderMode:像素边界外推方法的标志
borderValue:填充边界使用的数值,默认情况下为0
示例程序:
#include //加载OpenCV4的头文件
#include
#include
using namespace std;
using namespace cv; //OpenCV命名空间
int main()
{
Mat img = imread("noobcvqr.png");
if (img.empty())
{
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
Point2f src_points[4];
Point2f dst_points[4];
//通过Image Watch查看的二维码4个角点坐标
src_points[0] = Point2f(94.0, 374.0);
src_points[1] = Point2f(507.0, 380.0);
src_points[2] = Point2f(1.0, 623.0);
src_points[3] = Point2f(627.0, 627.0);
//期望透视变换后二维码4个角点的坐标
dst_points[0] = Point2f(0.0, 0.0);
dst_points[1] = Point2f(627.0, 0.0);
dst_points[2] = Point2f(0.0, 627.0);
dst_points[3] = Point2f(627.0, 627.0);
Mat rotation, img_warp;
rotation = getPerspectiveTransform(src_points, dst_points); //计算透视变换矩阵
warpPerspective(img, img_warp, rotation, img.size()); //透视变换投影
imshow("img", img);
imshow("img_warp", img_warp);
waitKey(0);
return 0; //程序结束
}
运行结果:
noobcvqr.png:
通过将图像在直角坐标系与极坐标系中相互变换,可以使一个图形以不同的方式呈现。比如圆形的图像上的文字,经过极坐标变换后可以垂直地排列在新图像的边缘,便于对文字进行识别和检测。
void warpPloar(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 | 逆变换 |
示例程序:
#include //加载OpenCV4的头文件
#include
#include
using namespace std;
using namespace cv; //OpenCV命名空间
int main()
{
Mat img = imread("dial.png");
if (img.empty())
{
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
Mat img1, img2;
Point2f center = Point2f(img.cols / 2, img.rows / 2); //极坐标在图像中的原点
//正极坐标变换
warpPolar(img, img1, Size(300, 600), center, center.x, INTER_LINEAR + WARP_POLAR_LINEAR);
//逆极坐标变换
warpPolar(img1, img2, Size(img.rows, img.cols), center, center.x, INTER_LINEAR + WARP_POLAR_LINEAR + WARP_INVERSE_MAP);
imshow("原表盘图", img);
imshow("表盘极坐标变换结果", img1);
imshow("逆变换结果", img2);
waitKey(0);
return 0; //程序结束
}
img:
img1:
img2:
感谢阅读!
也欢迎大家关注小白博主,多多鼓励一下!