如何设置网站名字,做竞价的网站,短视频seo什么意思,公司建设网站需求分析报告仿射变换是一种二维变换#xff0c;它可以将一个二维图形映射到另一个二维图形上#xff0c;保持了图形的“形状”和“大小”不变#xff0c;但可能会改变图形的方向和位置。仿射变换可以用一个线性变换矩阵来表示#xff0c;该矩阵包含了六个参数#xff0c;可以进行平移…仿射变换是一种二维变换它可以将一个二维图形映射到另一个二维图形上保持了图形的“形状”和“大小”不变但可能会改变图形的方向和位置。仿射变换可以用一个线性变换矩阵来表示该矩阵包含了六个参数可以进行平移、缩放、旋转等操作。通过原理、函数和示例进行解析帮助大家理解和使用。
下面我们将依次实现平移、旋转、缩放和仿射变换等功能使用C语言和OpenCV库。 目录 原理和函数原理warpAffine()函数详解 示例平移原理运行示例 缩放原理缩小示例放大示例 旋转原理顺时针示例逆时针示例 总结 原理和函数
原理 由于矩阵A的最后一行为0,01所以认为A是仿射变换矩阵变换类型主要包括平移、缩放和旋转。
warpAffine()函数详解
warpAffine() 是 OpenCV 库中的一个函数用于进行二维仿射变换。该函数将输入图像映射到输出图像应用仿射变换。
函数原型如下
void cv::warpAffine(InputArray src, OutputArray dst, InputArray mat, Size dsize Size(), int flags INTER_LINEAR, int borderMode BORDER_CONSTANT, Scalar borderValue Scalar());参数详解src输入图像必须是单通道或三通道的8位或32位浮点型图像。
dst输出图像其大小和类型与输入图像相同。
mat2x3的变换矩阵。
dsize输出图像的大小如果这个参数为 Size() 则输出图像的大小将与输入图像相同。
flags用于指定插值的方法默认为线性插值。可用的选项有 INTER_NEAREST, INTER_LINEAR, INTER_CUBIC 等。
borderMode用于指定如何处理输出图像边缘的像素默认为常量填充模式。可用的选项有 BORDER_CONSTANT, BORDER_REPLICATE, BORDER_WRAP 等。
borderValue用于指定填充的边界值默认为0。这个函数使用仿射变换来将输入图像映射到输出图像。仿射变换包括旋转、缩放、平移等操作但不包括扭曲和剪切。这个函数非常有用特别是在需要将图像映射到另一个大小或以特定方式旋转或倾斜图像时。
示例
平移
原理
平移变换可以用一个3x3的变换矩阵来表示其中第一行和第二行表示原始图像的行向量和列向量第三行表示变换后的行向量和列向量和原理部分类似但有些版本只需要设置一个2x3的变换矩阵即可可以省略第三行。在本例中即定义的是2x3的变换矩阵我们将原始图像向右移动100个像素向下移动300个像素。其中数值为正则向正方向移数值为负则向反向相移。 如上述矩阵转换矩阵只需要设置第一行的第三个元素tx和第二行第三列的ty即可体现在2行3列的矩阵中如下面运行示例中的100和300所示。
运行示例
#include opencv2/opencv.hpp
#include iostreamusing namespace cv;
using namespace std;int main() {Mat src imread(ceshi.jpg);if (src.empty()) {cout Could not read the source image endl;return -1;}Mat trans_mat (Mat_double(2, 3) 1, 0, 100, 0, 1, 300);Mat dst;warpAffine(src, dst, trans_mat, src.size());imshow(Source Image, src);imshow(Affine Transformed Image, dst);imwrite(pingyi.jpg, dst);waitKey(0);return 0;
}在代码中Mat trans_mat (Mat_double(2, 3) 1, 0, 100, 0, 1, 300);是定义的一个2行3列的转换矩阵第一行是右移100第二行是下移300。最后我们使用warpAffine()函数进行仿射变换将原始图像映射到输出图像中并显示原始图像和变换后的图像。运行可以看到相应的效果如下图所示。 上面为原图下面为平移后的图像。
缩放
原理
仿射变换中的缩放指的是对图像进行等比例的放大或缩小。在仿射变换矩阵中可以通过设置第一行和第二行的元素来控制缩放。 由上面的平移可知第一行第三列和第二行第三列的数值是控制平移的在此处可知第一行第一列和第二行第二列是用于控制x轴和y轴的缩放比例的在下面的运行示例中也可以看出缩放因子在的位置与此相对应。
缩小示例
#include opencv2/opencv.hpp
#include iostreamusing namespace cv;
using namespace std;int main() {Mat src imread(ceshi.jpg);if (src.empty()) {cout Could not read the source image endl;return -1;}// 设置缩放比例double scale 0.5;// 计算缩放矩阵Mat scale_mat (Mat_double(2, 3) scale, 0, 0, 0, scale, 0);// 进行仿射变换Mat dst;warpAffine(src, dst, scale_mat, src.size());// 显示原始图像和变换后的图像imshow(Source Image, src);imshow(Affine Transformed Image, dst);imwrite(suoxiao.jpg, dst);waitKey(0);return 0;
}在上面的代码中我们首先读取一张名为“ceshi.jpg”的图像然后设置缩放比例为0.5。接着我们计算缩放矩阵其中第一行和第二行的前两个元素分别表示水平方向和垂直方向的缩放比例第三行和第四行的前两个元素为0表示不进行平移操作。最后我们使用warpAffine()函数进行仿射变换将原始图像映射到输出图像中并显示原始图像和变换后的图像。变换后的效果如下图所示。
放大示例
此处我们把缩放因子设置为1.5即放大
#include opencv2/opencv.hpp
#include iostreamusing namespace cv;
using namespace std;int main() {Mat src imread(ceshi.jpg);if (src.empty()) {cout Could not read the source image endl;return -1;}// 设置缩放比例double scale 1.5;// 计算缩放矩阵Mat scale_mat (Mat_double(2, 3) scale, 0, 0, 0, scale, 0);// 进行仿射变换Mat dst;warpAffine(src, dst, scale_mat, src.size());// 显示原始图像和变换后的图像imshow(Source Image, src);imshow(Affine Transformed Image, dst);imwrite(fangda.jpg, dst);waitKey(0);return 0;
}放大的效果如下图所示。 相当于把图像一部分放大但显示的内容比原图就少了很多因为图像的总体大小没有改变。
旋转
原理 此处以原点0,0坐标为中心进行α 是旋转角度。 旋转矩阵的元素是由旋转角度和旋转中心计算得出的。假设我们有一个二维坐标系其中原点是旋转中心x轴正方向是右方y轴正方向是上方。现在我们要将点 (x, y) 绕原点逆时针旋转θ角度那么旋转矩阵可以表示为
[ cosα, -sinα, 0 ]
[ sinα, cosα, 0 ]
其中cosθ 和 sinθ 是使用弧度值计算得出的。也可以是如下公式
若为上述A变换矩阵则当α 为正时旋转方向为顺时针当 α 为负时旋转方向为逆时针。 同时另外一种情况与此相反如变换矩阵为
[ cosα, sinα, 0 ]
[ -sinα, cosα, 0 ]则当α 为正时旋转方向为逆时针当 α 为负时旋转方向为顺时针。 此外也可以控制α 的值如α 为45和为-45逆顺情况是相反的。
下面进行两个示例分别进行顺时针和逆时针旋转。
顺时针示例
#include opencv2/opencv.hpp
#include iostreamusing namespace cv;
using namespace std;int main() {Mat src imread(ceshi.jpg);if (src.empty()) {cout Could not read the source image endl;return -1;}// 设置旋转角度double angle 45;// 计算旋转矩阵Mat rot_mat (Mat_double(2, 3) cos(angle), -sin(angle), sin(angle), cos(angle), 1, 0);cout cos(angle) endl;cout -sin(angle) endl;cout sin(angle) endl;//rot_mat rot_mat * 100; // 设置旋转中心点这里将图像中心设置为旋转中心// 进行仿射变换Mat dst;warpAffine(src, dst, rot_mat, src.size());// 显示原始图像和变换后的图像imshow(Source Image, src);imshow(Affine Transformed Image, dst);imwrite(shunshizhen.jpg, dst);waitKey(0);return 0;
}上述代码中设置的double angle 45;为旋转角度45为正数所以是逆时针旋转同时(Mat_double(2, 3) cos(angle), -sin(angle), sin(angle), cos(angle), 1, 0);转换矩阵表示当α 为正时旋转方向为顺时针当 α 为负时旋转方向为逆时针。 旋转结果为
逆时针示例
1通过改变 α的值如将上面顺时针的45变为-45. 2改变变换矩阵的顺序如使用Mat rot_mat (Mat_double(2, 3) cos(angle), sin(angle), -sin(angle), cos(angle), 1, 0);替换上面代码中的转换矩阵。 以原点0,0为中心逆时针旋转45度效果图如下:
总结
我们可以看出在使用warpAffine函数是比较方便的通过使用定义2行3列和通过上面的例子可以快速高效的实现平移、缩放和旋转等功能。