一、图像尺寸变化
图像插值原理
在图像变换的过程中往往需要对像素进行相关的操作。如上图(左)所示,我们会遇到两个相邻的像素块需要映射到同样的位置中,或者两个相邻的位置的像素中间需要映射出一个位置的像素块。这时候我们就需要一些差值的方法。如上图(右)所示,是一个双线性插值操作。
图像缩放、翻转、拼接
缩放:
reslize(lnputArray src, OutputArray dst,Size dsize, double fx=e,
double fy = e, int interpolation = INTER_LINEAR
src:输入图像。
dst:输出图像,图像的数据类型与src相同。
dsize:输出图像的尺寸。
fx:水平轴的比例因子,如果将水平轴变为原来的两倍,则赋值为2,与dsize作用类似。
fy:垂直轴的比例因子,如果将垂直轴变为原来的两倍,则赋值为2,与dsize作用类似。
interpolation:差值方法的标志。
翻转:
cvflip(lnputArray src,OutputArray dst, int flipCode)
src:输入图像。
dst:输出图像,与src具有相同的大小和数据类型以及通道数。
flipCode:翻转方式标志,数值大于0表示绕y轴进行翻转;数值等于0,表示绕x轴进行翻转﹔数值小于0表示绕两个轴旋转。
拼接:
横向拼接
hconcat(InputArray src1, lnputArray src2, outputArray dst)
纵向拼接
vconcat(InputArray src1, lnputArray src2, outputArray dst)
srcl:第一个需要拼接的Mat类矩阵。
src2:第二个需要拼接的Mat类矩阵,与第一个参数具有相同的宽度、数据类型和通道数
dst:拼接后的Mat类矩阵。
代码实例如下:
Mat src = imread("图片1.png");
//缩小图像以及插值操作
Mat smallLmg, bigLmg0, bigLmg1, bigLmg2;
//缩小图像
resize(src, smallLmg, Size(15, 15), 0, 0, INTER_AREA);
//最近邻差值操作
resize(smallLmg, bigLmg0, Size(30, 30), 0, 0, INTER_NEAREST);
//双线性插值
resize(smallLmg, bigLmg1, Size(30, 30), 0, 0, INTER_LINEAR);
//双三次插值
resize(smallLmg, bigLmg2, Size(30, 30), 0, 0, INTER_CUBIC);
Mat img_x, img_y, img_xy;
//沿x轴翻转
flip(src, img_x, 0);
//沿y轴翻转
flip(src, img_y, 1);
//先沿x轴翻转,再沿y轴翻转
flip(src, img_xy, -1);
二、图像的仿射变换
warpAffine(InputArray src, outputArray dst, InputArray M, Size dsize, int flags = INTER_LINEAR,borderMode =, int BORDER__CONSTANT, const Scalar & borderValue = scalar())
src:输入图像。
dst:仿射变换后输出图像,与src数据类型相同,但是尺寸与dsize相同。M:2×3的变换矩阵(如上图的仿射变换矩阵)。
dsize:输出图像的尺寸。
flags:插值方法标志。
borderMode:像素边界外推方法的标志。
borderValue:填充边界使用的数值,默认情况下为0。
图像旋转:
getRotationMatrix2D (Point2f center, double angle, double scale
center:图像旋转的中心位置。
angle:图像旋转的角度,单位为度,正值为逆时针旋转。
scale:两个轴的比例因子,可以实现旋转过程中的图像缩放,不缩放输入1。
计算仿射变换矩阵:
Mat cv::getAffineTransform ( const Point2f src[], const Point2f dst[]
src[]:原图像中的三个像素坐标。
dst[]:目标图像中的三个像素坐标。
示例如下:
//读取图片
Mat src = imread("图片1.png");
if (!src.data)
{
printf("不能打开空图片");
return -1;
}
//定义仿射变换的矩阵、仿射变换后的图像
Mat rotation, img_warp;
//设置图像旋转的角度
double angle = 30;
//设置输出图像的尺寸
Size dst_size(src.rows, src.cols);
//设置图像的旋转中心
Point2f center(src.rows / 2.0, src.cols / 2.0);
//计算仿射变换的矩阵
rotation = getRotationMatrix2D(center, angle, 1);
//进行仿射变换
warpAffine(src, img_warp, rotation, dst_size);
imshow("img_warp", img_warp);
//三点法仿射变换
Point2f src_points[3];
Point2f dst_points[3];
//原始图像中的三个点
src_points[0] = Point2f(0, 0);
src_points[1] = Point2f(0, (float)(src.cols - 1));
src_points[2] = Point2f((float)(src.rows - 1), (float)(src.cols - 1));
//仿射变换后图像中的三个点
dst_points[0] = Point2f((float)(src.rows)*0.11, (float)(src.cols)*0.20);
dst_points[1] = Point2f((float)(src.rows)*0.15, (float)(src.cols)*0.70);
dst_points[2] = Point2f((float)(src.rows)*0.81, (float)(src.cols)*0.85);
Mat rotation1, img_warp1;
//根据对应点求取仿射变换矩阵
rotation1 = getAffineTransform(src_points, dst_points);
//进行仿射变换
warpAffine(src, img_warp1, rotation1, dst_size);
imshow("img_warp1", img_warp1);
三、图像透视变换
透视矩阵求解:
getPerspectiveTransform(const Point2f src[], const Point2f dst[], int soliveMethod = DECOMP_LU
src[]:原图像中的四个像素坐标。
dst[]:目标图像中的四个像素坐标。
solveMethod:计算透视变换矩阵方法的选择标志
透视变换函数:
warpPerspective(lnputArray src, outputArray dst, InputArray M, size dsize, int flags = INTER_LINEAR, borderMode, int BORDER_CONSTANT, const Scalar & borderValue = Scalar(
src:输入图像。
dst:透视变换后输出图像,与src数据类型相同,但是尺寸与dsize相同。
M:3×3的变换矩阵。
dsize:输出图像的尺寸。
flags:插值方法标志。
borderMode:像素边界外推方法的标志。
borderValue:填充边界使用的数值,默认情况下为0。
//读取图片
Mat src = imread("图片1.png");
if (!src.data)
{
printf("不能打开空图片");
return -1;
}
Point2f src_points[4];
Point2f dst_points[4];
//找到四个角点的坐标
src_points[0] = Point2f(5.0, 10.0);
src_points[1] = Point2f(10.0, 8.0);
src_points[2] = Point2f(1.0, 10.0);
src_points[3] = Point2f(15.0, 15.0);
//透视变换后的四个角点的坐标
dst_points[0] = Point2f(0.0, 0.0);
dst_points[1] = Point2f(10.0, 0.0);
dst_points[2] = Point2f(0.0, 10.0);
dst_points[3] = Point2f(10.0, 10.0);
//设置变换矩阵,变换后的图像的Mat对象
Mat rotation, img_wrap;
//获取透视变换的矩阵
rotation = getPerspectiveTransform(src_points, dst_points);
//进行透视变换投影
warpPerspective(src, img_wrap, rotation, src.size());
//显示变换后的图像
imshow("src", src);
imshow("img_wrap", img_wrap);