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

OpenCV 图像仿射变换之旋转

一、知识点
1、void warpAffine(InputArray src, 
                  OutputArray dst, 
                  InputArray M, 
                  Size dsize, 
                  int flags = INTER_LINEAR, 
                  int borderMode = BORDER_CONSTANT, 
                  const Scalar & borderValue = Scalar());

(1)、对图像应用仿射变换(旋转、平移、缩放)。
(2)、参数说明:
    src: 输入图像。
    dst: 输出图像,大小为dsize,数据类型与src相同。
    M: 2 * 3转换矩阵(两行三列)。
    dsize: 输出图像的大小。
    flags: 插值方法,InterpolationFlags枚举值。可和WARP_INVERSE_MAP组合,意味着M是逆变换(dst-->src)。
    borderMode: 边界模式,像素外推方法,BorderTypes枚举值。
    borderValue: 边界值。 当borderMode为BORDER_CONSTANT时,borderValue为边界的像素颜色。
(3)、仿射变换公式:

dst(x,y) = src(M11x + M12y + M13, M21x + M22y + M23)| M11 M12 M13 |     | x ||             |  *  | y || M21 M22 M23 |     | 1 |


2、在OpenCV中,旋转矩阵M为:

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


3、在OpenCV中,平移矩阵M为:

    | 1   0   dx ||            || 0   1   dy |


4、但是2、3的矩阵只相对于原点变换,实际工作中,经常是2、3的结合。 
  对于绕任意点的旋转矩阵,OpenCV中提供getRotationMatrix2D()获取。

5、Mat getRotationMatrix2D(Point2f center, double angle, double scale);
  (1)、计算2D旋转的仿射矩阵,可以用来对图像进行旋转。
  (2)、参数说明:
      center: 源图像的旋转中心点,即源图像要围绕此点旋转。
      angle: 旋转的角度,以度为单位,正值逆时针旋转,负值顺时针旋转。
      scale: 缩放因子。 1.0不改变大小,0.5缩小一半,2.0放大一倍。
  (3)、原点在源图像的左上角。
    
6、旋转后新的图像大小计算:

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

二、示例代码

#include <iostream>
#include <opencv2/opencv.hpp>int main()
{//1.获取源图像cv::Mat src = cv::imread("../images/9.png");if (src.empty()){std::cout << "load src image error..." << std::endl;return -1;}cv::imshow("源图像", src);//2.获取源图像宽、高int w = src.cols;int h = src.rows;//3.获取围绕源图像中心点,逆时针旋转45度,不缩放的矩阵cv::Mat M = cv::getRotationMatrix2D(cv::Point2f(w / 2, h / 2), 45, 1.0);//4.仿射变换,但是旋转后图像四角被截断,并且有黑色背景cv::Mat dst1;cv::warpAffine(src, dst1, M, cv::Size(w, h));cv::imshow("绕中心点逆时针旋转45度", dst1);//5.改变旋转后图像大小,源图像四角不被截断double cosTheta = cv::abs(M.at<double>(0, 0));double sinTheta = cv::abs(M.at<double>(0, 1));int nw = w * cosTheta + h * sinTheta;int nh = h * cosTheta + w * sinTheta;M.at<double>(0, 2) += (nw / 2.0 - w / 2.0);M.at<double>(1, 2) += (nh / 2.0 - h / 2.0);cv::Mat dst2;cv::warpAffine(src, dst2, M, cv::Size(nw, nh));cv::imshow("改变大小,源图像四角不被截断", dst2);//6.填充背景cv::Scalar backColor(src.at<cv::Vec3b>(0, 0)[0], src.at<cv::Vec3b>(0, 0)[1], src.at<cv::Vec3b>(0, 0)[2]);cv::Mat dst3;cv::warpAffine(src, dst3, M, cv::Size(nw, nh), cv::INTER_LINEAR, 0, backColor);cv::imshow("填充背景", dst3);cv::waitKey(0);return 0;
}

输出结果:

相关文章:

  • Diffusion 扩散模型详解:驱动高质量 3D 内容生成的核心机制 (AI+3D 产品经理笔记 S2E05)
  • 使用扣子空间生成html个人主页
  • LVS(DR)群集
  • Navicat 技术指引 | TiDB 查询功能
  • 洛谷B3951 [GESP样题 五级] 小杨的队列
  • 跨语言RPC:使用Java客户端调用Go服务端的HTTP-RPC服务
  • iOS性能调优实践:结合KeyMob等多个工具提升应用稳定性与流畅度
  • 【并集查找 状态压缩】P9904 [COCI 2023/2024 #1] Labirint|普及+
  • Vue3+Cropper.js扩展h5移动端双指旋转
  • 25.6.17学习总结
  • java上传base64数据流的本地存储并返回给前端URL接口实现
  • Vue的路由配置我们平时需要去手动配置吗?还是说默认配置就可以了
  • Kafka 向 TDengine 写入数据
  • CSS3 渐变效果
  • Android及Harmonyos实现图片进度显示效果
  • 百度垂搜数据管理系统弹性调度优化实践
  • AI办公提效,Deepseek + wps生成ppt
  • 基于Java的Excel列数据提取工具实现
  • FastGPT、百度智能体、Coze与MaxKB四大智能体平台在政务场景下的深度对比
  • 【人工智能下的智算网络】广域网优化
  • 手机网站推广怎么做/seo首页网站
  • 安徽网站建设天锐科技/百度权重怎么查询
  • 个人又什么办法做企业网站/优化设计五年级上册语文答案
  • 政府制作网站收费/怎么做线上销售
  • 用旧电脑做网站/建立网站用什么软件
  • 成都建设网站那家好/汕头seo公司