几何变换和图像特征仿射变换

举报
Gere 发表于 2022/08/07 19:27:05 2022/08/07
【摘要】 OpenCV中的仿射变换仿射变换:一个任意的仿射变换都能表示为 乘以一个矩阵 (线性变换) 接着再 加上一个向量 (平移).通常一个图像有三种变换:1、旋转2、平移3、缩放通常用2X3的矩阵来表示一个仿射变换:变 换 矩 阵 A = [ a 11 a 12 a 21 a 22 ] 变换矩阵A=\begin{bmatrix}a_{11}&a_{12}\\a_{21}&a_{22}\end{bm...

OpenCV中的仿射变换

仿射变换:一个任意的仿射变换都能表示为 乘以一个矩阵 (线性变换) 接着再 加上一个向量 (平移).
通常一个图像有三种变换:
1、旋转
2、平移
3、缩放
通常用2X3的矩阵来表示一个仿射变换:

变 换 矩 阵 A = [ a 11 a 12 a 21 a 22 ] 变换矩阵A=\begin{bmatrix}a_{11}&a_{12}\\a_{21}&a_{22}\end{bmatrix} A=[a11a21a12a22]
平 移 变 化 M = [ t x t y ] 平移变化M=\begin{bmatrix} t_x\\t_y \end{bmatrix} M=[txty]
通常将两个变换合为一个: 仿 射 变 换 矩 阵 T = [ a 11 a 12 t x a 21 a 22 t y ] 仿射变换矩阵T=\begin{bmatrix}a_{11}&a_{12}&t_x\\a_{21}&a_{22}&{t_y} \end{bmatrix} 仿T=[a11a21a12a22txty]
假设原坐标为 ( x 原 , y 原 ) (x_原,y_原) (x,y)经过仿射变换:
[ x 新 y 新 ] = [ a 11 a 12 a 21 a 22 ] ∗ [ x 原 y 原 ] + [ t x t y ] \begin{bmatrix}x_新\\y_新 \end{bmatrix}=\begin{bmatrix} a_{11}&a_{12}\\a_{21}&a_{22}\end{bmatrix}*\begin{bmatrix}x_原\\y_原 \end{bmatrix}+\begin{bmatrix}t_x\\t_y \end{bmatrix} [xy]=[a11a21a12a22][xy]+[txty]
以上为仿射变换的分步。
直接使用仿射变换矩阵T:
[ x 新 y 新 ] = [ a 11 a 12 t x a 21 a 22 t y ] ∗ [ x 原 y 原 1 ] \begin{bmatrix} x_新\\y_新\end{bmatrix}=\begin{bmatrix}a_{11}&a_{12}&t_x\\a_{21}&a_{22}&{t_y} \end{bmatrix}*\begin{bmatrix}x_原\\y_原\\1\end{bmatrix} [xy]=[a11a21a12a22txty]xy1

下面是几个函数的API:
利用变换前的点和变换后的点求出仿射变换矩阵:

getAffineTransform(
	原图像的点的集合,
	变换后的图像的点的集合
);

利用旋转角度和缩放比例来求出仿射变换矩阵:

getRotationMatrix2D(
	中心点,
	旋转角度,
	缩放比例
);

最后根据仿射变换矩阵对图像进行操作:

warpAffine(
	输入图像,
	输出图像,
	仿射变换矩阵,
	原图像.size()
);
#include "opencv2/opencv.hpp"
#include <iostream>


using namespace std;
using namespace cv;

int main()
{
    Mat test = Mat::zeros(500,500,CV_8UC3);
    imshow("test",test);
    Point2f p[3];
    Point2f q[3];
    p[0] = Point2f(200,300);
    p[1] = Point2f(400,100);
    p[2] = Point2f(70,80);
    line(test,p[0],p[1],Scalar(255,255,255),3,8);
    line(test,p[0],p[2],Scalar(255,255,255),3,8);
    line(test,p[2],p[1],Scalar(255,255,255),3,8);
    q[0] = Point2f(300,300);
    q[1] = Point2f(500,100);
    q[2] = Point2f(170,80);
    line(test,q[0],q[1],Scalar(255,255,255),3,8);
    line(test,q[0],q[2],Scalar(255,255,255),3,8);
    line(test,q[2],q[1],Scalar(255,255,255),3,8);
    Mat tr = getAffineTransform(p,q);
    cout << tr << endl;
    imshow("test",test);
    Mat src = imread("/home/dynamicw/Project/C++_Project/opencvtest/src/lesson01/source/map.png");
    Mat dst;
    Point center = Point(src.cols/2,src.rows/2);
    double angle = -50.0;
    double scale = 0.6;
    tr = getRotationMatrix2D(center,angle,scale);
    warpAffine(src,dst,tr,src.size());
    imshow("dst",dst);
    waitKey(0);
    return 0;
}
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。