一、概述
逆转仿射变换。该函数计算由 2×3 矩阵 M 表示的逆仿射变换:
结果也是一个与 M 相同类型的 2×3 矩阵。
二、invertAffineTransform函数
1、函数原型
cv::invertAffineTransform (InputArray M, OutputArray iM)
2、参数详解
M | 原始仿射变换。 |
iM | 输出反向仿射变换。 |
三、OpenCV源码
1、源码路径
opencv\modules\imgproc\src\imgwarp.cpp
2、源码代码
void cv::invertAffineTransform(InputArray _matM, OutputArray __iM)
{
Mat matM = _matM.getMat();
CV_Assert(matM.rows == 2 && matM.cols == 3);
__iM.create(2, 3, matM.type());
Mat _iM = __iM.getMat();
if( matM.type() == CV_32F )
{
const softfloat* M = matM.ptr<softfloat>();
softfloat* iM = _iM.ptr<softfloat>();
int step = (int)(matM.step/sizeof(M[0])), istep = (int)(_iM.step/sizeof(iM[0]));
softdouble D = M[0]*M[step+1] - M[1]*M[step];
D = D != 0. ? softdouble(1.)/D : softdouble(0.);
softdouble A11 = M[step+1]*D, A22 = M[0]*D, A12 = -M[1]*D, A21 = -M[step]*D;
softdouble b1 = -A11*M[2] - A12*M[step+2];
softdouble b2 = -A21*M[2] - A22*M[step+2];
iM[0] = A11; iM[1] = A12; iM[2] = b1;
iM[istep] = A21; iM[istep+1] = A22; iM[istep+2] = b2;
}
else if( matM.type() == CV_64F )
{
const softdouble* M = matM.ptr<softdouble>();
softdouble* iM = _iM.ptr<softdouble>();
int step = (int)(matM.step/sizeof(M[0])), istep = (int)(_iM.step/sizeof(iM[0]));
softdouble D = M[0]*M[step+1] - M[1]*M[step];
D = D != 0. ? softdouble(1.)/D : softdouble(0.);
softdouble A11 = M[step+1]*D, A22 = M[0]*D, A12 = -M[1]*D, A21 = -M[step]*D;
softdouble b1 = -A11*M[2] - A12*M[step+2];
softdouble b2 = -A21*M[2] - A22*M[step+2];
iM[0] = A11; iM[1] = A12; iM[2] = b1;
iM[istep] = A21; iM[istep+1] = A22; iM[istep+2] = b2;
}
else
CV_Error( CV_StsUnsupportedFormat, "" );
}
四、效果图像示例
下面代码展示了先计算变换矩阵,然后对RGB图像进行旋转,之后再求逆变换矩阵,之后再应用到已经旋转的图像上。
#include <opencv2\opencv.hpp>
using namespace cv;
int main()
{
Mat3b RGBsrc = imread("path_to_image");
double Angle = 30.0;
// get rotation matrix for rotating the image around its center
Point2f center22(RGBsrc.cols / 2.0, RGBsrc.rows / 2.0);
Mat rot = getRotationMatrix2D(center22, Angle, 1.0);
// determine bounding rectangle
Rect bbox = RotatedRect(center22, RGBsrc.size(), Angle).boundingRect();
// adjust transformation matrix
rot.at<double>(0, 2) += bbox.width / 2.0 - center22.x;
rot.at<double>(1, 2) += bbox.height / 2.0 - center22.y;
Mat RotatedRGB;
warpAffine(RGBsrc, RotatedRGB, rot, bbox.size());
// Invert the affine transformation
Mat rotInv;
cv::invertAffineTransform(rot, rotInv);
// Get back the original image
Mat Rotatedback;
warpAffine(RotatedRGB, Rotatedback, rotInv, Size(RGBsrc.cols, RGBsrc.rows));
imshow("Original", RGBsrc);
imshow("Rotated", RotatedRGB);
imshow("Rotated Back", Rotatedback);
waitKey();
return 0;
}
代码首先定义了旋转矩阵rot,使用此矩阵对图像进行操作。
接着我们还可以使用invertAffineTransform函数计算rot的逆矩阵,得到rotInv,然后对上面的旋转的图像进行操作,得到近乎于原始图片的结果。
五、仿射变换相关参考
Opencv学习笔记 - 仿射变换/透视变换/对数极坐标变换_坐望云起的博客-CSDN博客_对数极坐标变换Opencv学习笔记 - 仿射变换/透视变换/对数极坐标变换https://skydance.blog.csdn.net/article/details/109705939Opencv学习笔记 常用函数、基础知识三 仿射变换_坐望云起的博客-CSDN博客仿射变换代表的是两幅图之间的关系。1、一个任意的仿射变换都能表示为 乘以一个矩阵 (线性变换) 接着再 加上一个向量 (平移).2、用仿射变换来处理,旋转 (线性变换),平移 (向量加),缩放操作 (线性变换)https://skydance.blog.csdn.net/article/details/108885176