画像のアフィン変換とは、空間直交座標系における 2 次元座標を別の 2 次元座標に変換することを指します。アフィン変換は、線形変換 (行列の乗算) と平行移動で表現できる線形変換です。プロセス。アフィン変換は主に、移動、スケーリング、反転、回転、せん断などの関連するコレクション変換操作を実装するために使用されます。
元の画像の空間座標 (x, y) は、アフィン変換によって (x^, y^) に変換されます。アフィン変換における一般的な変換は次のとおりです。
画像アフィン変換は、ほとんどの幾何学的変換操作に適用できます。
アフィン変換にopencvを使用する場合、まずアフィン変換行列が計算されますが、getRotationMatrix2D関数で角度をラジアンに変換してから回転行列を計算します。
Mat getRotationMatrix2D(Point2f center, double angle, double scale)
{
//角度转换
angle *= CV_PI / 180;
//计算旋转矩阵角度
double alpha = cos(angle) * scale;
double beta = sin(angle) * scale;
Mat M(2, 3, CV_64F);
double* m = (double*)M.data;
//构建旋转矩阵
m[0] = alpha;
m[1] = beta;
m[2] = (1 - alpha) * center.x - beta * center.y;
m[3] = -beta;
m[4] = alpha;
m[5] = beta * center.x + (1 - alpha) * center.y;
return M;
}
これにより2次元回転のアフィン変換行列が計算された後、warpAffine関数を通じてソース画像のアフィン変換を実行できます。
応用例(以下のコードを書く場合、上記のgetRotationMatrix2D関数を入れる必要はありません)
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main()
{
Mat src = imread("C:\\Users\\32498\\Pictures\\16.png");
if (!src.data)
{
return -1;
}
imshow("src", src);
//①点仿射
int nRows = src.rows;
int nCols = src.cols;
//定义仿射变换的二维点数组
//源图像和目标图像对应映射的三个点
Point2f srcPoint[3];
Point2f resPoint[3];
srcPoint[0] = Point2f(0, 0);
srcPoint[1] = Point2f(nCols - 1, 0);
srcPoint[2] = Point2f(0, nRows - 1);
resPoint[0] = Point2f(nCols * 0, nRows * 0.33);
resPoint[1] = Point2f(nCols * 0.85, nRows * 0.25);
resPoint[2] = Point2f(nCols * 0.15, nRows * 0.7);
//定义仿射变换矩阵2*3
Mat warpMat(Size(2, 3), CV_32F);
Mat result = Mat::zeros(nRows, nCols, src.type());
//计算仿射变换矩阵
warpMat = getAffineTransform(srcPoint, resPoint);
//根据仿射变换矩阵计算图像仿射变换
warpAffine(src, result, warpMat, result.size());
imshow("result", result);
waitKey();
//②角仿射
//设置仿射变换参数
Point2f centerPoint = Point2f(nCols / 2, nRows / 2);
double angle = -50;
double scale = 0.7;
//获取仿射变换矩阵
warpMat = getRotationMatrix2D(centerPoint, angle, scale);
//对源图像进行仿射变换
warpAffine(src, result, warpMat, result.size());
imshow("result", result);
waitKey();
return 0;
}
結果は次のとおりです。図 2 はポイント アフィン変換、図 3 は角度アフィン変換です (ただし、情報の一部が失われています)。