当前位置: 首页 > news >正文

第二十一节 图像旋转



void QUickdemo::roate_demo(Mat& image)
{
    Mat dst, M;
    int w = image.cols;
    int h = image.rows;
    M = getRotationMatrix2D(Point2f(w / 2, h / 2), 45, 1.0);--M = getRotationMatrix2D(Point2f(w / 2, h / 2), 45, 1.0);:使用getRotationMatrix2D函数生成一个旋转矩阵M。这个函数的参数分别是旋转中心(这里是图像的中心,即Point2f(w / 2, h / 2))、旋转角度(这里是 45 度)和缩放因子(这里是 1.0,表示不进行缩放)。


重新计算新图像尺寸
    double cos = abs(M.at<double>(0, 0));
    double sin = abs(M.at<double>(0, 1));

--double cos = abs(M.at<double>(0, 0)); double sin = abs(M.at<double>(0, 1));:从旋转矩阵中获取对应的值,用于计算新图像的宽度和高度。其中的cos和sin是计算新图像的重要数值。

在这段代码中,从M.at<double>(0, 0)和M.at<double>(0, 1)获取值是因为旋转矩阵的结构决定的。

一个 2D 旋转矩阵通常具有以下形式:

| cosθ  -sinθ |
| sinθ   cosθ |

其中,cosθ在第一行第一列(对应(0, 0)),sinθ在第一行第二列(对应(0, 1))。

代码中通过获取这两个位置的值,可以得到与旋转角度相关的余弦值和正弦值,用于后续计算旋转后图像的新宽度和新高度等操作。


    int nw = cos * w + sin * h;
    int nh = cos * h + sin * w;

--

int nw = cos * w + sin * h; int nh = cos * h + sin * w;:计算旋转后的图像的新宽度nw和新高度nh。
    M.at<double>(0, 2) += (nw / 2 - w / 2);
    M.at<double>(1, 2) += (nh / 2 - h / 2);

这两行代码的作用是调整旋转矩阵M中的平移量,以确保旋转后的图像中心与新图像的中心对齐。

1. M.at<double>(0, 2) += (nw / 2 - w / 2);

• M.at<double>(0, 2)代表旋转矩阵M中第一行第三列的元素,它控制着图像在水平方向上的平移量。

• nw / 2是新图像宽度的一半,w / 2是原始图像宽度的一半。计算nw / 2 - w / 2得到的是新图像中心与原始图像中心在水平方向上的偏移量。

• 将这个偏移量加到M.at<double>(0, 2)上,就调整了水平方向的平移量,使得旋转后的图像在水平方向上的中心与新图像的中心对齐。

2. M.at<double>(1, 2) += (nh / 2 - h / 2);

• 同理,M.at<double>(1, 2)是旋转矩阵M中第二行第三列的元素,控制着图像在垂直方向上的平移量。

• nh / 2是新图像高度的一半,h / 2是原始图像高度的一半。计算nh / 2 - h / 2得到新图像中心与原始图像中心在垂直方向上的偏移量。

• 将这个偏移量加到M.at<double>(1, 2)上,调整垂直方向的平移量,使得旋转后的图像在垂直方向上的中心与新图像的中心对齐。

    warpAffine(image, dst, M, Size(nw, nh), INTER_LINEAR, 0, Scalar(255, 0, 0));

这行代码使用 OpenCV 库中的 warpAffine 函数对图像进行仿射变换(这里主要是旋转)。

1. image:

• 这是输入的原始图像,即要进行旋转操作的图像。

2. dst:

• 这是输出的目标图像,函数执行后,经过旋转后的图像将存储在这个变量中。

3. M:

• 这是一个 2x3 的变换矩阵,它描述了如何对图像进行变换,包括旋转、平移、缩放等操作。在前面的代码中,这个矩阵是通过 getRotationMatrix2D 函数生成,并根据旋转角度和图像尺寸进行了调整。

4. Size(nw, nh):

• 这指定了输出图像的大小,其中 nw 是新图像的宽度,nh 是新图像的高度,这两个值在前面的计算中已经根据旋转角度和原始图像尺寸确定。

5. INTER_LINEAR:

• 这是插值方法的标志,表示在图像变换过程中使用线性插值。线性插值可以在图像放大或缩小时提供相对平滑的效果。

6. 0:

• 这是边界外推法的标志,这里表示使用默认的边界外推方法。

7. Scalar(255, 0, 0):

• 这是用于填充边界的颜色值,这里表示用蓝色(R = 255,G = 0,B = 0)填充边界。如果在图像变换过程中出现了新的边界区域,这些区域将用指定的颜色填充。

    imshow("tt", dst);


}


http://www.mrgr.cn/news/51755.html

相关文章:

  • 卡码网KamaCoder 96. 城市间货物运输 III
  • Vite创建Vue3项目以及Vue3相关基础知识
  • 深入理解队列(Queue)的实现(纯小白进)
  • Django开发流程
  • 用docker安装的mongo使用mongodump可以正常执行,但是在生成目录下找不到生成的文件
  • idea中高级实用的调试技巧
  • 三色标记产生漏标问题的条件
  • 2、CSS笔记
  • 面试题:在 React 中如何绑定事件
  • 一篇文章带你搞懂总线舵机驱动电路
  • sky_take_out苍穹外卖开发(day-1)
  • Flutter SVG 图片加载速度提升 98% 的技巧
  • MinIO配置与使用
  • 如何在 JavaScript 项目中限制Node.js版本
  • QOwnNotes:开源界的黑马,专业人士的不二之选
  • mysql用户管理(user表列信息介绍,本质,管理操作),数据库的权限管理(权限列表,权限操作)
  • 探索人工智能在数学教育上的应用——使用大规模语言模型解决数学问题的潜力和挑战
  • 深度学习 %matplotlib inline
  • 微服务的特点
  • mysql学习教程,从入门到精通,sql序列使用(45)