图像的仿射变换

使用C++、opencv进行图像的仿射变换

仿射变换(Affine Transformation或Affine Map),又称仿射映射,是指在几何中,一个向量空间进行一次线性变换并接上一个平移,变换为另一个向量空间的过程。它保持了二维图形的“平直性”(直线经过变换之后依然是直线)和“平行性”(二维图形之间的相对位置关系保持不变,平行线依然是平行线,且直线上点的位置顺序不变)。

更多仿射变换的原理可参考:http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/imgtrans/warp_affine/warp_affine.html


相关API:

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

 warpAffine()函数的作用是按照下面的公式对图像进行变换:

第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。

第二个参数,OutputArray类型的dst,函数调用后的运算结果存在这里,需和源图片有一样的尺寸和类型。

第三个参数,InputArray类型的M,2×3的变换矩阵。

第四个参数,Size类型的size,表示输出图像的尺寸

第五个参数,int类型的fags,插值方法的标识符。此参数有默认值INTER LⅠNEAR(线性插值),可选的插值方式如表7.1所示。

图像的仿射变换_第1张图片

第六个参数,int类型的borderMode,边界像素模式,默认值为BORDER CONSTANT。

第七个参数,const scalar&类型的border value,在恒定的边界情况下取的值,默认值为Scalar,即0。

Mat getPerspectiveTransform(InputArray src,InputArray dst,int solveMethod = DECOMP_LU )

getPerspectiveTransform()函数通过3点对应关系获得反射变换矩阵 ,返回类型是Mat

InputArray src是源图像

InputArray dst是目标图像

int solveMethod是计算方法,有默认值

Mat getRotationMatrix2D(Point2fcenter, double angle, double scale) 

getRotationMatrix2D()函数用于计算二维旋转变换矩阵。变换会将旋转中心映射到它自身。

第一个参数, Point2f类型的 center,表示源图像的旋转中心。

第二个参数, double类型的 angle,旋转角度。角度为正值表示向逆时针旋转(坐标原点是左上角)。

第三个参数, double类型的 scale,缩放系数。此函数计算以下矩阵

图像的仿射变换_第2张图片


代码如下:

 

#include "stdafx.h"
#include 
#include 
#include 
#include 

using namespace cv;

//全局变量
Mat src;
Mat warp_dst;
const char* remaptrackbarname = "remapvalue";
const char* warprotatetrackbarname = "warprotatevalue";
const char* warpscaletrackbarname = "warpscalevalue";
const char* remap_window = "Remap demo";
const char* warprotate_window = "warprotate demo";
const int remapmaxcount = 4, warprotatemaxcount = 360, warpscalemaxcount = 10;
int remapvalue, warprotatevalue = 180, warpscalevalue = 10;

// 函数声明
void remapcontrol(int, void*);
void warprotatecontrol(int, void*);
void warpaffinecontrol();

int main(int argc, char** argv)
{
	//读取图像
	src = imread("D:\\哀.jpg", 1);

	//把原图变小一倍
	resize(src, src, Size(0.5*src.cols, 0.5*src.rows));

	//创建窗口
	namedWindow(remap_window, CV_WINDOW_AUTOSIZE);
	namedWindow(warprotate_window, CV_WINDOW_AUTOSIZE);
	createTrackbar(remaptrackbarname, remap_window, &remapvalue, remapmaxcount, remapcontrol);
	createTrackbar(warprotatetrackbarname, warprotate_window, &warprotatevalue, warprotatemaxcount, warprotatecontrol);
	createTrackbar(warpscaletrackbarname, warprotate_window, &warpscalevalue, warpscalemaxcount, warprotatecontrol);
	remapcontrol(0, 0);
	warpaffinecontrol();
	warprotatecontrol(0, 0);
	waitKey();

	return 0;
}

void remapcontrol(int, void*)
{
	Mat  dst, map_x, map_y;
	dst.create(src.size(), src.type());
	map_x.create(src.size(), CV_32FC1);
	map_y.create(src.size(), CV_32FC1);
	for (int j = 0; j < src.rows; j++)
	{
		for (int i = 0; i < src.cols; i++)
		{
			switch (remapvalue)
			{
			case 0:
				map_x.at(j, i) = i;
				map_y.at(j, i) = j;
				break;

			case 1:
				if (i > src.cols*0.25 && i < src.cols*0.75 && j > src.rows*0.25 && j < src.rows*0.75)
				{
					map_x.at(j, i) = 2 * (i - src.cols*0.25) + 0.5;
					map_y.at(j, i) = 2 * (j - src.rows*0.25) + 0.5;
				}
				else
				{
					map_x.at(j, i) = 0;
					map_y.at(j, i) = 0;
				}
				break;
			case 2:
				map_x.at(j, i) = i;
				map_y.at(j, i) = src.rows - j;
				break;
			case 3:
				map_x.at(j, i) = src.cols - i;
				map_y.at(j, i) = j;
				break;
			case 4:
				map_x.at(j, i) = src.cols - i;
				map_y.at(j, i) = src.rows - j;
				break;
			} 
		}
	}
	remap(src, dst, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));

	imshow(remap_window, dst);
}
void warprotatecontrol(int, void*)
{
	Mat warp_rotate_dst;
	Mat rot_mat(2, 3, CV_32FC1);
	Point center = Point(warp_dst.cols / 2, warp_dst.rows / 2);
	double angle = warprotatevalue - 180;
	double scale = double(warpscalevalue) / 10;
	printf("%f\n", scale);
	// 通过上面的旋转细节信息求得旋转矩阵
	rot_mat = getRotationMatrix2D(center, angle, scale);

	// 旋转已扭曲图像
	warpAffine(warp_dst, warp_rotate_dst, rot_mat, warp_dst.size());
	imshow(warprotate_window, warp_rotate_dst);
}
void warpaffinecontrol()
{
	Point2f srcTri[3];
	Point2f dstTri[3];
	Mat warp_mat(2, 3, CV_32FC1);
	warp_dst = Mat::zeros(src.rows, src.cols, src.type());

	srcTri[0] = Point2f(0, 0);
	srcTri[1] = Point2f(src.cols - 1, 0);
	srcTri[2] = Point2f(0, src.rows - 1);

	dstTri[0] = Point2f(src.cols*0.0, src.rows*0.1);
	dstTri[1] = Point2f(src.cols*0.85, src.rows*0.25);
	dstTri[2] = Point2f(src.cols*0.15, src.rows*0.7);
	warp_mat = getAffineTransform(srcTri, dstTri);
	warpAffine(src, warp_dst, warp_mat, warp_dst.size());
};

源图像:

图像的仿射变换_第3张图片

结果图:

图像的仿射变换_第4张图片

你可能感兴趣的:(C++,opencv,图像处理)