c++视觉处理---仿射变换和二维旋转变换矩阵的函数
仿射变换cv::warpAffine
cv::warpAffine 是OpenCV中用于执行仿射变换的函数。仿射变换是一种线性变换,可用于执行平移、旋转、缩放和剪切等操作。下面是 cv::warpAffine 函数的基本用法:
cv::warpAffine(src, dst, M, dsize, flags, borderMode, borderValue);
src: 输入图像。dst: 输出图像,用于存储仿射变换后的结果。M: 2x3仿射变换矩阵,包含变换的参数。dsize: 输出图像的尺寸。flags: 插值方法,通常使用cv::INTER_LINEAR进行双线性插值。cv::INTER_NEAREST最近邻插值cv::INTER_AREA区域插值cv::INTER_CUBIC三次样条插值cv::INTER_LANCZOS4Lanczos插值cv::CV_WARP_FILL_OUTLIERS填充所有输出图像的象素。如果部分象素落在输入图像的边界 外,那么它们的值设定为 fillvalcv::CV_WARP_INVERSE_MAP表示 M为输出图像到输入图像的反变换。因此可以直接用来做 象素插值。否则,warpAffine函数从M矩阵得到反变换
borderMode: 边界模式,可选参数,定义当像素越出图像边界时的处理方式,通常使用cv::BORDER_CONSTANT或cv::BORDER_REPLICATE。borderValue: 当borderMode为cv::BORDER_CONSTANT时使用,用于指定图像边界外的像素值。
通过提供仿射变换矩阵 M,您可以指定图像的变换方式,包括平移、旋转、缩放和剪切等。然后,cv::warpAffine 函数会根据给定的变换参数将输入图像进行变换,输出结果保存在 dst 中。
以下是一个简单的示例,演示如何使用 cv::warpAffine 进行图像的平移操作:
#include <opencv2/opencv.hpp>int main() {cv::Mat image = cv::imread("1.jpg", cv::IMREAD_COLOR);if (image.empty()) {std::cerr << "无法加载图像" << std::endl;return -1;}// 定义仿射变换矩阵(平移操作)cv::Mat warpMatrix = (cv::Mat_<double>(2, 3) << 1, 0, 50, 0, 1, 30);cv::Mat result;// 应用仿射变换cv::warpAffine(image, result, warpMatrix, image.size());cv::imshow("原始图像", image);cv::imshow("仿射变换后的图像", result);cv::waitKey(0);return 0;
}
在这个示例中,我们定义了一个仿射变换矩阵 warpMatrix,该矩阵包含平移操作的参数。然后,我们使用 cv::warpAffine 函数将变换应用于原始图像,生成了变换后的结果。您可以根据需要修改 warpMatrix 中的值以实现不同的仿射变换效果。

二维旋转变换矩阵的函数:cv::getRotationMatrix2D
cv::getRotationMatrix2D 是OpenCV中用于获取二维旋转变换矩阵的函数。这个函数用于构造一个仿射变换矩阵,该矩阵用于执行二维图像的旋转操作。下面是 cv::getRotationMatrix2D 函数的基本用法:
cv::Mat cv::getRotationMatrix2D(cv::Point2f center, double angle, double scale);
center: 旋转中心的坐标,通常是旋转图像的中心点。angle: 旋转的角度(以度为单位)。scale: 缩放因子,通常设置为1.0。
函数返回一个2x3的仿射变换矩阵,该矩阵包含了旋转和缩放的参数。
以下是一个示例,演示如何使用 cv::getRotationMatrix2D 函数构造旋转变换矩阵,然后应用该变换矩阵来旋转图像:
#include <opencv2/opencv.hpp>int main() {cv::Mat image = cv::imread("1.jpg", cv::IMREAD_COLOR);if (image.empty()) {std::cerr << "无法加载图像" << std::endl;return -1;}// 旋转中心坐标cv::Point2f center(image.cols / 2.0, image.rows / 2.0);// 旋转角度(以度为单位)double angle = 30;// 缩放因子double scale = 1.0;// 获取旋转变换矩阵cv::Mat rotationMatrix = cv::getRotationMatrix2D(center, angle, scale);cv::Mat result;// 应用仿射变换cv::warpAffine(image, result, rotationMatrix, image.size());cv::imshow("原始图像", image);cv::imshow("旋转后的图像", result);cv::waitKey(0);return 0;
}
在这个示例中,我们使用 cv::getRotationMatrix2D 函数获取旋转变换矩阵,然后将该变换矩阵应用于原始图像,以实现旋转效果。您可以根据需要调整 center、angle 和 scale 参数来执行不同的旋转和缩放操作。

综合案例
#include <opencv2/opencv.hpp>
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>using namespace std;
using namespace cv;
#include <iostream>
#include <fstream>
using namespace cv; //包含cv命名空间
#include <opencv2/core/core.hpp>
#define WINDOW_NAME1 " 【原始图窗口】 " //为窗口标题定义的宏
#define WINDOW_NAME2 " 【经过 Warp后的图像】 " //为窗口标题定义的宏
#define WINDOW_NAME3 " 【经过 Warp和 Rotate后的图像】 " //为窗口标题定
static void ShowHelpText();
/// 【main()函数】-------------------------- -
// 描述: 控制台应用程序的入口函数, 我们的程序从这里开始执行
int main()
{//【0】改变 console字体颜色system("color 1A");//【0】显示欢迎和帮助文字ShowHelpText();//【1】参数准备//定义两组点, 代表两个三角形Point2f srcTriangle[3];Point2f dstTriangle[3];//定义一些 Mat变量Mat rotMat(2, 3, CV_32FC1);Mat warpMat(2, 3, CV_32FC1);Mat srcImage, dstImage_warp, dstImage_warp_rotate;//【2】加载源图像并作一些初始化srcImage = imread("1.jpg", 1);if (!srcImage.data) { printf("读取图片错误, 请确定目录下是否有imread函数指定的图片存在~! \n"); return false; }// 设置目标图像的大小和类型与源图像一致dstImage_warp = Mat::zeros(srcImage.rows, srcImage.cols, srcImage.type());//【3】设置源图像和目标图像上的三组点以计算仿射变换srcTriangle[0] = Point2f(0, 0);srcTriangle[1] = Point2f(static_cast<float>(srcImage.cols - 1), 0);srcTriangle[2] = Point2f(0, static_cast<float>(srcImage.rows - 1));dstTriangle[0] = Point2f(static_cast<float>(srcImage.cols * 0.0), static_cast<float>(srcImage.rows * 0.33));dstTriangle[1] = Point2f(static_cast<float>(srcImage.cols * 0.65), static_cast<float>(srcImage.rows * 0.35));dstTriangle[2] = Point2f(static_cast<float>(srcImage.cols * 0.15), static_cast<float>(srcImage.rows * 0.6));//【4】求得仿射变换warpMat = getAffineTransform(srcTriangle, dstTriangle);//【5】对源图像应用刚刚求得的仿射变换warpAffine(srcImage, dstImage_warp, warpMat, dstImage_warp.size());//【6】对图像进行缩放后再旋转// 计算绕图像中点顺时针旋转50度缩放因子为0.6的旋转矩阵Point center = Point(dstImage_warp.cols / 2, dstImage_warp.rows / 2);double angle = -30.0;double scale = 0.8;// 通过上面的旋转细节信息求得旋转矩阵rotMat = getRotationMatrix2D(center, angle, scale);// 旋转已缩放后的图像warpAffine(dstImage_warp, dstImage_warp_rotate, rotMat, dstImage_warp.size());//【7】显示结果imshow(WINDOW_NAME1, srcImage);imshow(WINDOW_NAME2, dstImage_warp);imshow(WINDOW_NAME3, dstImage_warp_rotate);// 等待用户按任意按键退出程序waitKey(0);return 0;
}
//一 【ShowHelpText()函数】---------------------- -
// 描述: 输出一些帮助信息
static void ShowHelpText()
{//输出一些帮助信息printf("\n\n\n\t欢迎来到【仿射变换】示例程序~ \n\n");//printf("\t当前使用的OpenCV版本为 OpenCV "CV_VERSION);
}

相关文章:
c++视觉处理---仿射变换和二维旋转变换矩阵的函数
仿射变换cv::warpAffine cv::warpAffine 是OpenCV中用于执行仿射变换的函数。仿射变换是一种线性变换,可用于执行平移、旋转、缩放和剪切等操作。下面是 cv::warpAffine 函数的基本用法: cv::warpAffine(src, dst, M, dsize, flags, borderMode, borde…...
uiautomator2遍历子元素.all()
当你获取了页面某个元素之后 elements d(’//*[clickable“true”]’).all() 返回的是一个list,其中是<uiautomator2.xpath.XMLElement>类型的变量。 可以通过以下方式获取它所有子类的信息。 for ele in elements:children ele.elem.getchildren()注意…...
【手写数据库toadb】SQL字符串如何被数据库认识? 词法语法分析基础原理,常用工具
词法语法分析 专栏内容: 手写数据库toadb 本专栏主要介绍如何从零开发,开发的步骤,以及开发过程中的涉及的原理,遇到的问题等,让大家能跟上并且可以一起开发,让每个需要的人成为参与者。 本专栏会定期更新,对应的代码也会定期更新,每个阶段的代码会打上tag,方便阶段…...
手把手教你基于windows系统使用GNVM进行node切换版本
GNVM是什么? GNVM 是一个简单的 Windows 下 Node.js 多版本管理器,类似的 nvm nvmw nodist 。 安装 进入官网,下载你所需要的包,直达链接 下载完成 放到我们的node环境包下,点击运行 请注意区分: 不存在 Node.js 环…...
c#画五角星
c#画一个五角星,最重要的就是计算哪些坐标点出来,也是最难的一部分,这要涉及到一些数学方面的知识.对数学坐标知识不是很熟的人,如果想学画图,我建议多去看一下数学书,对我们写程序的人来说是没有什么坏处可言的. 想学习的朋友可以一起学习,我觉得分享学习是一种快乐,所以把自…...
第三章 数据链路层 | 计算机网络(谢希仁 第八版)
文章目录 第三章 数据链路层3.1 使用点对点信道的数据链路层3.1.1 数据链路和帧3.1.2 三个基本问题 3.2 点对点协议PPP3.2.1 PPP协议的特点3.2.2 PPP协议的帧格式3.2.3 PPP协议的工作状态 3.3 使用广播信道的数据链路层3.3.1 局域网的数据链路层3.3.2 CSMA/CD协议3.3.3 使用集线…...
李沐机器学习环境配置相关
李沐机器学习环境配置相关 condapython环境安装指令安装miniconda安装cpu版本torch安装jupyter测试GPU是否可以使用 conda 退出 conda 环境 conda deactivate进入都d2l环境 conda activate d2l启动jupyter notebook: jupyter notebookpython 列出所有安装的包 pip lsit环…...
零基础Linux_16(基础IO_文件)笔试选择题:文件描述符+ionde和动静态库
目录 一. 文件描述符等 1. Linux下两个进程可以同时打开同一个文件,这时如下描述错误的是: 2. 以下关于标准输入输出错误的描述正确的是 3. 以下描述正确的是 4. 以下描述正确的是 [多选] 5. 在bash中,在一条命令后加入”1>&2”…...
基于OpenCV的灰度图的图片相似度计算
from skimage.metrics import structural_similarity as ssim import matplotlib.pyplot as plt import cv2 def picture_recognization(imagname):# 读取两张图片image1 cv2.imread(D:/AutoTest/PythonProject/standard_img/ imagname)image2 cv2.imread(D:/AutoTest/Pytho…...
【python海洋专题二十】subplots_adjust布局调整
上期读取soda,并subplot 但是存在一些不完美,本期修饰 本期内容 subplots_adjust布局调整 1:未调整布局的 2:调整布局 往期推荐 【python海洋专题一】查看数据nc文件的属性并输出属性到txt文件 【python海洋专题二】读取水深…...
TensorFlow入门(二十四、初始化学习参数)
参数的初始化关系到网络能否训练出好的结果或者是以多快的速度收敛,对训练结果有着重要的影响。 初始化学习参数需要注意的规则 不可以将网络中的所有参数初始化为0,也不能全部初始化为同一个值。如果参数全部初始化为0或者是同一个值,会使得所有神经元的输出都是相同的,进而造…...
工厂WMS系统货架位管理:优化仓储效率
货架位管理作为WMS系统中的重要环节,对于提高工厂的仓储效率和精确库存管理至关重要。本文将从多个角度全方位介绍工厂的WMS系统货架位管理,探讨其重要性以及如何优化、应用该系统,提升工厂的仓储效率和运营水平。 1. 优化仓库空间利用&…...
[C++随想录] 继承
继承 继承的引言基类和子类的赋值转换继承中的作用域派生类中的默认成员函数继承与友元继承与静态成员多继承的结构棱形继承的结构棱形虚拟继承的结构继承与组合 继承的引言 概念 继承(inheritance)机制是面向对象程序设计使代码可以 复用的最重要的手段,它允许程序…...
ARM-day9
按键控制小灯、蜂鸣器、风扇,按一次启动,第二次关闭 key_it.c #include "key_it.h"//按键3的配置 void key3_it_config() {//RCC使能GPIOF时钟RCC->MP_AHB4ENSETR | (0x1<<5);GPIOF->MODER & (~(0x3<<16));EXTI->E…...
2386: [余姚2015] 幸运数字(luck)
目录 题目描述 输入 输出 样例输入 样例输出 提示 来源: 代码: 题目描述 今年圣诞节,小明收到了很多礼物,每个礼物上都有一个数字,表示对小明的祝福。可是小明有自己的想法,对小明来说,4或者7的倍数…...
【JUC系列-13】深入理解DelayQueue延迟队列的底层原理
JUC系列整体栏目 内容链接地址【一】深入理解JMM内存模型的底层实现原理https://zhenghuisheng.blog.csdn.net/article/details/132400429【二】深入理解CAS底层原理和基本使用https://blog.csdn.net/zhenghuishengq/article/details/132478786【三】熟练掌握Atomic原子系列基本…...
Leetcode---365周赛
题目列表 2873. 有序三元组中的最大值 I 2874. 有序三元组中的最大值 II 2875. 无限数组的最短子数组 2876. 有向图访问计数 一、有序三元组中的最大值I 看一眼该题的数据范围,直接三层for循环暴力枚举,时间复杂度O(n^3),代码如下 class…...
Java使用opencv实现人脸识别、人脸比对
1. opencv概述 OpenCV是一个开源的计算机视觉库,它提供了一系列丰富的图像处理和计算机视觉算法,包括图像读取、显示、滤波、特征检测、目标跟踪等功能。 opencv官网:https://opencv.org/ opencv官网文档:https://docs.opencv.or…...
Redis HyperLogLog的使用
Redis HyperLogLog知识总结 一、简介二、使用 一、简介 Redis HyperLogLog是一种数据结构,用于高效地计算基数(集合中唯一元素的数量)。它的主要作用是用于在内存中高效地存储和计算大量数据的基数,而无需完全存储所有的数据。Hy…...
Apisix-Ingress服务发现详解
apisix Apache APISIX 是一个基于微服务 API 网关,其不仅可以处理南北向的流量,也可以处理东西向的流量即服务之间的流量。Apache APISIX 集成了控制面板和数据面,与其他 API 网关相比,Apache APISIX 的上游、路由、插件全是动态的…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么?它的作用是什么? Spring框架的核心容器是IoC(控制反转)容器。它的主要作用是管理对…...
云原生周刊:k0s 成为 CNCF 沙箱项目
开源项目推荐 HAMi HAMi(原名 k8s‑vGPU‑scheduler)是一款 CNCF Sandbox 级别的开源 K8s 中间件,通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度,为容器提供统一接口,实现细粒度资源配额…...
