opencv#20 仿射变换

如果知道原始图像中的三个点和变换后三个点的对应关系,那么就知道了唯一的仿射变换关系,使得原图像变化到变换后的图像,也就是说图像中三个点时一一对应的,通过三个点就知道对应关系,因此被称为三点变换。

如图仿射变换矩阵中有散列三列数据,前两列矩阵a表示我要旋转部分,第三列矩阵b可以称其为平移部分,通过三个点可以唯一确定一个m,这个m就是我们的仿射变换矩阵,通过这个变换矩阵和我们原图像中的像素位置,进行运算,就可以得到变换后的像素所在位置,从而进行图像的仿射变换。

仿射变换相关函数

warpAffine()

void cv::warpAffine(InputArray    src,
                    OutputArray   dst,
                    InputArray    M,
                    Size          dsize,
                    int           flags = INTER_LINEAR,
                                  bordeMode = 
                    int           BORDER_CONSTANT,
                    const Scalar & borderValue = Scalar()
                   )

·src:输入图像

·dst:仿射变换后输出图像,与src数据类型相同,但是尺寸与dsize相同

·M:2x3的变换矩阵

·dsize:输出图像的尺寸

·flags:插值方法标志

·dorderMode:像素边界外推方法的标志

·borderValue:填充边界使用的数值,默认情况下为0

边界填充方法和对应标志

我们最常用的时特定值的方式进行填充,往往我们并不关心这些填充的数据,它只是给我们的运算以及显示提供了一些帮助,它不含有真正的图像中的信息,因此我们采用最简单的方式即可,它的好处是0是黑色的,它既不影响图像中颜色信息,纹理信息等其它信息的表达,同时它又相对比较简单。

图像旋转

计算放射变换矩阵 = getRotationMatrix2D() 

void cv::getRotationMatrix2D(Point2f center,
                             double  angle,
                             double  scale
                            )

·center:图像旋转的中心位置

·angle:图像旋转的角度,单位为度,正值为逆时针旋转

·scale:两个轴的比例因子,可以实现旋转过程中的图像缩放,不缩放输入1.

 计算仿射变换矩阵

getAffine Transform()

Mat cv::getAffineTransform(const Point2f src[],
                            const Point2f dst[]
                           )

·src[]:原图像中的三个像素坐标。

·dst():目标图像中的三个像素坐标。

示例

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv; //opencv的命名空间
using namespace std;

int main()
{
	Mat img = imread("E:/opencv/opencv-4.6.0-vc14_vc15/opencv/lenac.png");
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}

	Mat rotation0, img_warp0;

	double angle = 30; //设置图像旋转的角度
	Size dst_size(img.rows, img.cols);//设置输出图像尺寸
	Point2f center(img.rows / 2.0, img.cols / 2.0); //设置图像的旋转中心

	rotation0 = getRotationMatrix2D(center, angle, 1); //计算仿射变换矩阵

	warpAffine(img, img_warp0, rotation0, dst_size, 1); //进行仿射变换
	imshow("img_warp0", img_warp0);

	//三点法计算仿射变换的仿射变换矩阵
	Point2f src_points[3];
	Point2f dst_points[3];
	src_points[0] = Point2f(0, 0);//原始图像三中的三个点(选取的是三个顶点)
	src_points[1] = Point2f(0, (float)(img.cols - 1));
	src_points[2] = Point2f((float)(img.rows - 1),(float)(img.cols - 1));
	dst_points[0] = Point2f((float)(img.rows)*0.11, (float)(img.cols)*0.20); //仿射变换后图像中的三个点
	dst_points[1] = Point2f((float)(img.rows)*0.15, (float)(img.cols) * 0.70);
	dst_points[2] = Point2f((float)(img.rows)*0.81, (float)(img.cols) * 0.85);

	Mat rotation1, img_warp1;

	rotation1 = getAffineTransform(src_points, dst_points); //根据对应点求取仿射变换矩阵
	warpAffine(img, img_warp1, rotation1, dst_size); //进行仿射变换


	imshow("img_warp1", img_warp1);

	waitKey(0);
	return 0;

}

结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值