OpenCV几何图像变换(9)仿射变换函数warpAffine()的使用

news2024/9/21 22:34:32
  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

算法描述

函数是应用一个仿射变换到图像上。
warpAffine 函数使用指定的矩阵对源图像进行仿射变换:
dst ( x , y ) = src ( M 11 x + M 12 y + M 13 , M 21 x + M 22 y + M 23 ) \texttt{dst} (x,y) = \texttt{src} ( \texttt{M} _{11} x + \texttt{M} _{12} y + \texttt{M} _{13}, \texttt{M} _{21} x + \texttt{M} _{22} y + \texttt{M} _{23}) dst(x,y)=src(M11x+M12y+M13,M21x+M22y+M23)
当设置了标志 WARP_INVERSE_MAP 时。否则,先使用 invertAffineTransform 函数对变换进行反转,然后将反转后的矩阵放入上述公式中代替 M。该函数不能原地操作

warpAffine()函数用于应用仿射变换到图像上。仿射变换是一种线性变换,它可以包括旋转、缩放、平移和错切(shear)等操作。

函数原型


void cv::warpAffine	
(
	InputArray 	src,
	OutputArray 	dst,
	InputArray 	M,
	Size 	dsize,
	int 	flags = INTER_LINEAR,
	int 	borderMode = BORDER_CONSTANT,
	const Scalar & 	borderValue = Scalar() 
)		

参数

  • 参数src 输入图像。
  • 参数dst 输出图像,它具有 dsize 的大小和与 src 相同的类型。
  • 参数M 2×3的变换矩阵。
  • 参数dsize 输出图像的大小。
  • 参数flags 插值方法的组合(参见 InterpolationFlags)和可选标志 WARP_INVERSE_MAP,该标志表示 M 是逆变换(dst→src)。
  • 参数borderMode 像素外推方法(参见 BorderTypes);当 borderMode=BORDER_TRANSPARENT 时,意味着目标图像中对应于源图像中的“异常值”的像素不会被函数修改。
  • 参数borderValue 在存在常数边界时所使用的值;默认情况下,它是 0。

代码示例


#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/opencv.hpp>

using namespace cv;

int main( int argc, char** argv )
{
    // 读取图像
    Mat image = imread( "/media/dingxin/data/study/OpenCV/sources/images/fruit_small.jpg", IMREAD_COLOR );

    if ( image.empty() )
    {
        std::cerr << "Error: Could not open or find the image." << std::endl;
        return -1;
    }

     // 获取图像的尺寸
    int cols = image.cols;
    int rows = image.rows;
    
    // 计算旋转中心点
    Point2f center(cols / 2.0, rows / 2.0);
    
    // 设置旋转角度和缩放因子
    double angle = 45.0; // 旋转角度
    double scale = 1.0;  // 缩放因子
    
    // 计算旋转矩阵
    Mat rotationMatrix = getRotationMatrix2D(center, angle, scale);
    
    // 获取输出图像的大小
    Size dsize(cols, rows);
    
    // 创建输出图像
    Mat rotatedImage;
    
    // 应用仿射变换
    warpAffine(image, rotatedImage, rotationMatrix, dsize, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));


    // ===错切===

    // 设置错切系数
    double shearX = 0.5; // 水平方向错切系数
    double shearY = 0.5; // 垂直方向错切系数
    
    // 计算错切矩阵
    Mat shearMatrix = (Mat_<double>(2,3) << 1, shearX, 0, shearY, 1, 0);
    
    // 创建输出图像
    Mat shearedImage;
    
    // 设置输出图像的大小
    Size dsize2(image.cols, image.rows);
    
    // 应用仿射变换
    warpAffine(image, shearedImage, shearMatrix, dsize2, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));

    // 平移

       // 设置平移距离
    int dx = 100; // 水平方向平移距离
    int dy = 50;  // 垂直方向平移距离
    
    // 计算平移矩阵
    Mat translationMatrix = (Mat_<double>(2,3) << 1, 0, dx, 0, 1, dy);
    
    // 创建输出图像
    Mat translatedImage;
    
    // 设置输出图像的大小
    Size dsize3(image.cols, image.rows);
    
    // 应用仿射变换
    warpAffine(image, translatedImage, translationMatrix, dsize3, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));

    // 缩放
      // 设置缩放比例
    double scaleX = 0.5; // 水平方向缩放比例
    double scaleY = 0.5; // 垂直方向缩放比例
    
    // 计算缩放矩阵
    Mat scalingMatrix = (Mat_<double>(2,3) << scaleX, 0, 0, 0, scaleY, 0);
    
    // 创建输出图像
    Mat scaledImage;
    
    // 设置输出图像的大小
    Size dsize4(image.cols * scaleX, image.rows * scaleY);
    
    // 应用仿射变换
    warpAffine(image, scaledImage, scalingMatrix, dsize4, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));
    
    
    // 显示结果
   
    imshow("原始图像", image);
    imshow("旋转图像", rotatedImage);
    imshow("错切图像", shearedImage);
    imshow("平移图像", translatedImage);
    imshow("缩放图像", scaledImage);
    
    waitKey(0);

    return 0;
}

运行结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2069030.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Elasticsearch:使用 ELSER 进行语义搜索 - sparse_vector

Elastic Learned Sparse EncodeR&#xff08;或 ELSER&#xff09;是由 Elastic 训练的 NLP 模型&#xff0c;可让你使用稀疏向量表示执行语义搜索。语义搜索不是根据搜索词进行文字匹配&#xff0c;而是根据搜索查询的意图和上下文含义检索结果。 本教程中的说明向你展示了如…

[医疗 AI ] 3D TransUNet:通过 Vision Transformer 推进医学图像分割

[医疗 AI ] 3D TransUNet&#xff1a;通过 Vision Transformer 推进医学图像分割’ 论文地址 - https://arxiv.org/pdf/2310.07781 0. 摘要 医学图像分割在推进医疗保健系统的疾病诊断和治疗计划中起着至关重要的作用。U 形架构&#xff0c;俗称 U-Net&#xff0c;已被证明在…

提高实时多媒体传输效率的三大方法

实时多媒体数据传输面临的挑战 实时多媒体数据的传输具有数据量巨大、对时延和时延抖动高度敏感及能容忍丢分组的特点。然而&#xff0c;当今互联网的网络层协议提供的仅是一种“尽最大努力服务”&#xff0c;对分组的端到端时延、时延抖动和分组丢失率等指标不做任何承诺。这…

MySQL的延迟复制

目录 1 MySQL 延迟复制介绍 1.1 延迟复制语法&#xff1a; 1.2 延迟复制可用于多种用途&#xff1a; 1.3 延迟复制的有关的参数 1.4 延迟复制的操作 2 MySQL 延迟复制 实操 2.1 实验环境 2.2 对 SLAVE --MySQL-3 进行延迟复制操作 2.3 停止相关进程的原因 2.4 实验测试 2.5 动…

Variomes:支持基因组变异筛选的高召回率搜索引擎

《Bioinformatics》2022 Variomes&#xff1a; https://candy.hesge.ch/Variomes Source code&#xff1a; https://github.com/variomes/sibtm-variomes SynVar&#xff1a; https://goldorak.hesge.ch/synvar 文章摘要&#xff08;Abstract&#xff09; 动机&#xff08;Mot…

读软件开发安全之道:概念、设计与实施07密码学(上)

1. 加密工具 1.1. 加密工具之所以没有得到充分使用&#xff0c;就是因为人们往往认为密码学是一个准入门槛极高的专业领域 1.2. 如今的加密学大部分都源自纯数学&#xff0c;所以只要能够正确使用&#xff0c;加密学确实行之有效 1.2.1. 不代表这些算法本身确实无法破解&…

机器学习 | 基于wine数据集的KMeans聚类和PCA降维案例

KMeans聚类&#xff1a;K均值聚类是一种无监督的学习算法&#xff0c;它试图根据数据的相似性对数据进行聚类。无监督学习意味着不需要预测结果&#xff0c;算法只是试图在数据中找到模式。在k均值聚类中&#xff0c;我们指定希望将数据分组到的聚类数。该算法将每个观察随机分…

四大消息队列:Kafka、ActiveMQ、RabbitMQ、RocketMQ对比

四大消息队列&#xff1a;Kafka、ActiveMQ、RabbitMQ、RocketMQ对比 1. 社区活跃度2. 持久化消息3. 技术实现4. 高并发性能5. RabbitMQ与Kafka对比 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在软件开发中&#xff0c;消息队列&#xf…

【Redis】Redis数据结构——Hash 哈希

哈希 命令hsethgethexistshdelhkeyshvalshgetallhmgethlenhsetnxhincrbyhincrbyfloat命令小结 内部编码使用场景缓存⽅式对⽐ ⼏乎所有的主流编程语⾔都提供了哈希&#xff08;hash&#xff09;类型&#xff0c;它们的叫法可能是哈希、字典、关联数组、映射。在 Redis 中&#…

Python furl库:一键搞定复杂URL操作

更多Python学习内容&#xff1a;ipengtao.com 在Web开发和数据处理的过程中&#xff0c;URL的解析、修改和构建是不可避免的操作。然而&#xff0c;直接操作URL字符串不仅繁琐&#xff0c;而且容易出错。Python的furl库提供了一种简单且强大的方法来处理URL&#xff0c;使得URL…

简易的 Websocket + 心跳机制 + 尝试重连

文章目录 演示大纲基础 WebSocket前端: 添加心跳机制前端: 尝试重新连接历史代码 还没有写完&#xff0c;bug 是有的&#xff0c;我在想解决办法了… 演示 大纲 基础的 webSocket 连接前后端&#xff1a;添加心跳机制后端无心跳反应&#xff0c;前端尝试重新连接设置重新连接…

Java 日常反常识踩坑

作者&#xff1a;若渝 本文主要是日常业务开发中自身碰到过跟常识不一致的坑&#xff0c;问题虽然基础&#xff0c;但却可能造成比较大的线上问题。 一、转 BigDecimal 类型时精度丢失 public class Test { public static void main(String[] args) { BigDecimal bi…

算法-分隔链表

一、题目描述 (一) 题目 给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。你应当保留两个分区中每个节点的初始相对位置。 (二) 示例 示例 1&#xff1a; 输入&#xff1a;…

用Python实现9大回归算法详解——07. 支持向量机回归算法

1. 支持向量机回归的基本概念 支持向量机回归&#xff08;Support Vector Regression, SVR&#xff09;是支持向量机&#xff08;SVM&#xff09;的一个应用&#xff0c;主要用于回归任务。与分类任务中的 SVM 类似&#xff0c;SVR 通过找到一个最大化边界&#xff08;即支持向…

[WUSTCTF2020]spaceclub

上sublime txt 每一行的长短对应一个二进制位&#xff0c;长空格是1&#xff0c;短空格是0&#xff0c;全部替换掉得到 上python脚本 import binasciiwith open(attachment_5.txt, r) as file:lines file.readlines() # 逐行读取文本内容output # 初始化输出字符串# 遍历…

vscode 写了未定义的方法不报错,配置全局ESLint

最近接触了一个旧的vue2的项目&#xff0c;里面没有ts和eslint配置 在正在维护的页面里复制了其他页面的一个方法&#xff0c;方法里面包含lodash的cloneDeep&#xff0c;cloneDeep在这个页面并没有引入&#xff0c;但是vscode却没有提示&#xff0c;很不友好&#xff0c;容易…

JUC阻塞队列(五):SynchronousQueue

1、SynchronousQueue介绍 SynchronousQueue与前边的其他几个阻塞队列的差异是挺大的&#xff0c;在一般逻辑中队列是一个用 来存储数据的中间容器&#xff08;前边几个阻塞队列也是用来存放数据的&#xff09;&#xff0c;但SynchronousQueue 却不是用来存放数据的&#xff0c;…

自动控制——用描述函数法分析非线性系统的稳定性与自激振荡

用描述函数法分析非线性系统的稳定性与自激振荡 引言 在控制系统中&#xff0c;非线性系统的稳定性和自激振荡&#xff08;self-oscillation&#xff09;问题往往较线性系统更为复杂。为了分析这些问题&#xff0c;描述函数法&#xff08;Describing Function Method&#xf…

QtWebEngineView加载本地网页

直接加载放在exe同级目录下的资源是不行的&#xff0c;需要把资源通过qrc放到exe里面&#xff0c;然后通过类似qrc:/robotHtml/index.html这样的路径加载才行。 mWebView new QWebEngineView(parent);// mWebView->load(QUrl::fromLocalFile("./robotHtml/index.html&…

Vue3集成高德离线地图实践

1. 离线地图效果预览 2. 地图下载器下载离线地图 根据需要选择地图&#xff0c;我这边选择高德地图&#xff0c;层级选择0-15级别即可&#xff0c;进行下载 3. 放到nginx内网服务器 注意配置允许跨域 4. Vue3核心代码 // main.js // 初始化vue-amap initAMapApiLoader({o…