opencv中有关图像尺寸、翻转与仿射变换
函数原型:
void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation = INTER_LINEAR)
src:输入图像
dst:输出图像,图像的数据类型与src相同
dsize:输出图像尺寸
fx:水平轴的比例因子
fy:垂直轴的比例因子
interpolation:插值方法的标志
一般情况下dsize与fx(fy)使用其一即可,当出现dsize与fx最终调整的结果不一致时,以dsize为准
最后一个参数选择的插值不同对于最终缩放效果会不同。
插值方法标志表:
标志参数 | 简记 | 作用 |
---|---|---|
INTER_NEAREST | 0 | 最近邻插值法 |
INTER_LINEAR | 1 | 双线性插值法 |
INTER_CUBIC | 2 | 双三次插值 |
INTER_AREA | 3 | 使用像素区域关系重新采样,首选用于图像缩小,图像放大时效果与INTER_NEAREST相似 |
INTER_LANCZOS4 | 4 | Lanczos插值法 |
INTER_LINEAR_EXACT | 5 | 位精确双线性插值法 |
INTER_MAX | 7 | 用掩码进行插值 |
示例代码:
#include //加载OpenCV4的头文件
#include
#include
using namespace std;
using namespace cv; //OpenCV命名空间
int main()
{
Mat gray = imread("lena.png", IMREAD_GRAYSCALE);
if (gray.empty())
{
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
Mat smallImg, bigImg0, bigImg1, bigImg2;
resize(gray, smallImg, Size(15, 15), 0, 0, INTER_AREA); //先将图像缩小
resize(smallImg, bigImg0, Size(30, 30), 0, 0, INTER_NEAREST); //最近邻插值
resize(smallImg, bigImg1, Size(30, 30), 0, 0, INTER_LINEAR); //双线性插值
resize(smallImg, bigImg2, Size(30, 30), 0, 0, INTER_CUBIC); //双三次插值
namedWindow("smallImg", WINDOW_NORMAL); //图像尺寸太小,一定要设置可以调节窗口大小标志
imshow("smallImg", smallImg);
namedWindow("bigImg0", WINDOW_NORMAL);
imshow("bigImg0", bigImg0);
namedWindow("bigImg1", WINDOW_NORMAL);
imshow("bigImg1", bigImg1);
namedWindow("bigImg2", WINDOW_NORMAL);
imshow("bigImg2", bigImg2);
waitKey(0);
return 0; //程序结束
}
smallImg:
bigImg0:
图像翻转模型
void flip(InputArray src, OutputArray dst, int flipCode)
src:输入图像
dst:输出图像
flipcode:翻转方式标志。数值大于0表示绕y轴进行翻转;数值等于0,表示绕x轴进行翻转;数值小于0,表示绕两个轴翻转
示例程序:
#include //加载OpenCV4的头文件
#include
#include
using namespace std;
using namespace cv; //OpenCV命名空间
int main()
{
Mat img = imread("lena.png");
if (img.empty())
{
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
Mat img_x, img_y, img_xy;
flip(img, img_x, 0); //以x轴对称
flip(img, img_y, 1); //以y轴对称
flip(img, img_xy, -1); //先以x轴翻转,再以y轴翻转
imshow("img", img);
imshow("img_x", img_x);
imshow("img_y", img_y);
imshow("img_xy", img_xy);
waitKey(0);
return 0; //程序结束
}
三次翻转结果:img_x, img_y, img_xy
图像的仿射变换用于图像的旋转,实现图像的旋转,首先需要确定旋转角度和旋转中心,之后确实旋转矩阵,最终通过仿射变换实现图像的旋转。
Mat getRotationMatrix2D(Point2f center, double angle, double scale)
center:图像旋转的中心位置
angle:图像旋转的角度,单位为度,正值为逆时针旋转
scale:两个轴的比例因子,可以实现旋转过程中的图像缩放,不缩放则输入1
图像返回一个Mat矩阵
另一个3点对应求变换矩阵M的函数为:
Mat getAffineTransform(const Point2f src[], const Point2f dst[])
src[ ]:源图像中的3个像素坐标
dst[ ]:目标图像中的3个像素坐标
函数返回一个2*3的变换矩阵
void warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags = INTER_LINEAR, int borderMode = BORDER_CONSTANT, const Scalar& borderValue = Scalar())
src: 输入图像
dst:仿射变换后输出图像,与src数据类型相同,尺寸与dsize相同
M:2*3的变换矩阵
dsize:输出图像的尺寸
flags:插值方法标志
borderMode:像素边界外推方法的标志
borderValue:填充边界使用的数值,默认情况下为0
标志参数 | 简记 | 作用 |
---|---|---|
INTER_NEAREST | 0 | 最近邻插值法 |
INTER_LINEAR | 1 | 双线性插值法 |
INTER_CUBIC | 2 | 双三次插值 |
INTER_AREA | 3 | 使用像素区域关系重新采样,首选用于图像缩小,图像放大时效果与INTER_NEAREST相似 |
INTER_LANCZOS4 | 4 | Lanczos插值法 |
INTER_LINEAR_EXACT | 5 | 位精确双线性插值法 |
INTER_MAX | 7 | 用掩码进行插值 |
WARP_FILL_OUTLIERS | 8 | 填充所有输出图像的像素,如果部分像素落在输入图像的边界外,则它们的值设定为fillval |
WARP_INVERSE_MAP | 16 | 设置为M输出图像到输入图像的反变换 |
仿射变换就是图像的旋转、平移和缩放操作的统称,可以表示为线性变换和平移变换的叠加。仿射变换的数学表示是先乘以一个线性变换矩阵再加上一个平移向量。
示例程序:
#include //加载OpenCV4的头文件
#include
#include
using namespace std;
using namespace cv; //OpenCV命名空间
int main()
{
Mat img = imread("lena.png");
if (img.empty())
{
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
Mat rotation0, rotation1, img_warp0, img_warp1;
double angle = 45; //设置图像旋转的角度
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); //进行仿射变换
imshow("img_warp0", img_warp0);
//根据定义的3个点进行仿射变换
Point2f src_points[3];
Point2f dst_points[3];
src_points[0] = Point2f(0, 0); //原始图像中的3个点
src_points[1] = Point2f(0, (float)(img.cols - 1));
src_points[2] = Point2f((float)(img.rows - 1), (float)(img.cols - 1));
//仿射变换后图像中的3个点
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);
rotation1 = getAffineTransform(src_points, dst_points); //根据对应点求取仿射变换矩阵
warpAffine(img, img_warp1, rotation1, dst_size); //进行仿射变换
imshow("img_warp1", img_warp1);
waitKey(0);
return 0; //程序结束
}
img_warp0:
img_warp1:
感谢阅读!
也欢迎大家关注小白博主,多多鼓励一下!