Opencv学习-图像翻转变换

news2024/11/16 17:52:37

1. flip函数介绍(翻转)

void cv::flip(InputArray src, OutputArray dst, int flipCode )

src:输入图像。
dst:输出图像,与 src 具有相同的大小、数据类型及通道数。
flipCode:翻转方式标志。数值大于 0 表示绕 y 轴进行翻转;数值等于 0,表示绕 x 轴进行翻转;数值小于 0,表示绕两个轴翻转。

1.1 代码示例:

#include <opencv2/opencv.hpp> 
#include <iostream> 

using namespace std; 
using namespace cv; 

int main() 
{ 
    Mat img = imread("../pic/gril_1.jpg"); 
    if (img.empty()) 
    { 
        cout << "请确认图像文件名称是否正确" << endl; 
        return -1; 
    } 
    
    Mat img_x, img_y, img_xy; 
    flip(img, img_x, 0); //以 x 轴对称
    flip(img, img_y, 1); //以 y 轴对称
    flip(img, img_xy, -1); //先以 x 轴对称,再以 y 轴对称
    imshow("img", img); 
    imshow("img_x", img_x); 
    imshow("img_y", img_y); 
    imshow("img_xy", img_xy); 
    waitKey(0); 
    return 0; 
}

1.2 结果:

2. 图像仿射变换

2.1 getRotationMatrix2D()函数介绍

Mat cv::getRotationMatrix2D (Point2f center, double angle, double scale )

center:图像旋转的中心位置。
angle:图像旋转的角度,单位为度,正值为逆时针旋转。
scale:两个轴的比例因子,可以实现旋转过程中的图像缩放,不缩放则输入1。

该函数输入旋转角度和旋转中心,返回图像旋转矩阵,返回值的数据类型为 Mat 类,是一个2× 3 的矩阵。如果我们已知图像旋转矩阵,那么可以自己生成旋转矩阵而不调用该函数。该函数生成的旋转矩阵与旋转角度和旋转中心的关系如下:

2.2  warpAffine()函数介绍

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:仿射变换后输出图像,与src数据类型相同,尺寸与dsize相同。
M:  2×3的变换矩阵。
dsize:输出图像的尺寸。
flags:插值方法标志,。
borderMode:像素边界外推方法标志。
borderValue:填充边界使用的数值,默认情况下为0。

                                                                 插值方法标志

                                                            边界外推的方法标志

这个函数使用仿射变换来将输入图像映射到输出图像。仿射变换包括旋转、缩放、平移等操作,但不包括扭曲和剪切。这个函数非常有用,特别是在需要将图像映射到另一个大小或以特定方式旋转或倾斜图像时。 

warpAffine函数可以参考:

【C++】【Opencv】cv::warpAffine()仿射变换函数详解,实现平移、缩放和旋转等功能-CSDN博客

2.3 getAffineTransform函数介绍

Mat cv::getAffineTransform(const Point2f src[], const Point2f dst[] )

src[]:源图像中的 3 个像素坐标。

dst[] :目标图像中的 3 个像素坐标
该函数两个输入量都是存放浮点坐标的数组,在生成数组的时候,与像素点的输入顺序无关, 但是需要保证像素点的对应关系,函数的返回值是一个 2 × 3 的变换矩阵。有了前面变换矩阵的取,就可以利用 warpAffine() 函数实现矩阵的仿射变换。

2.4 代码示例:

#include <opencv2/opencv.hpp> 
#include <iostream> 
#include <vector> 

using namespace std; 
using namespace cv; 

int main() 
{ 
    Mat img = imread("../pic/gril_1.jpg"); 
    if (img.empty()) 
    { 
        cout << "请确认图像文件名称是否正确" << endl; 
        return -1; 
    } 
    
    Mat rotation0, rotation1, img_warp0, img_warp1,img_warp2; 
    double angle = -90; //设置图像旋转的角度
    Size dst_size(img.rows, img.cols); //设置输出图像的尺寸
    Point2f center(img.rows / 2.0, img.cols / 2.0); //设置图像的旋转中心
    rotation0 = getRotationMatrix2D(center, angle, 1); //计算仿射变换矩阵

    //cout << "rotation0 : \n" <<  rotation0 << endl;
    warpAffine(img, img_warp0, rotation0, dst_size); //进行仿射变换
    imshow("img_warp0", img_warp0); 
    //根据定义的 3 个点进行仿射变换
    Point2f src_points[3]; 
    Point2f dst_points[3]; 
    src_points[0] = Point2f(0, 0); //原始图像中的 3 个点
    src_points[1] = Point2f(0, (float)(img.cols - 1)); 
    src_points[2] = Point2f((float)(img.rows - 1), (float)(img.cols - 1)); 
    //仿射变换后图像中的 3 个点
    dst_points[0] = Point2f((float)(img.rows)*0.1, (float)(img.cols)*0.10); 
    dst_points[1] = Point2f((float)(img.rows)*0.1, (float)(img.cols)*0.80); 
    dst_points[2] = Point2f((float)(img.rows)*0.81, (float)(img.cols)*0.8); 
    rotation1 = getAffineTransform(src_points, dst_points); //根据对应点求取仿射变换矩阵
    //cout << "rotation1 : \n" <<  rotation1 << endl;
    warpAffine(img, img_warp1, rotation1, dst_size); //进行仿射变换
    warpAffine(img, img_warp2, rotation1, dst_size,WARP_FILL_OUTLIERS,BORDER_REPLICATE,10); //进行仿射变换
    imshow("img_warp1", img_warp1); 
    imshow("img_warp2", img_warp2); 
    waitKey(0); 
    return 0; 
}

 2.5 结果:

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

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

相关文章

geoserver发布wms服务

注意事项&#xff1a;因为这里我安装的是geoserver2.25.2&#xff0c;所以jdk版本换成11&#xff0c;安装17的时候点击浏览文件&#xff0c;右上角转圈&#xff0c;f12打开控制台发现报错500 1、新建工作空间 2、编辑工作空间 3、添加新的存储仓库 4、选择矢量数据源下的第一个…

嵌入式day18

shell脚本配置 shell编程&#xff1a;&#xff08;shell/bash&#xff08;linux&#xff09; ->命令解释器&#xff09; 解释类编程语言 边翻译边执行 擅长文件处理&#xff0c;系统操作 开发效率高 执行效率低 移植性好 c语言&#xff1a; 编程型语言 先编译再执行 擅长数…

(leetcode学习)42. 接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表…

Linux常用命令全

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 ☁️运维工程师的职责&#xff1a;监…

八大排序--快速排序、希尔排序、冒泡排序、归并排序、堆排序等经典排序算法思想

目录 排序的分类 基本概念 插入排序 直接插入排序 折半插入排序 希尔排序 交换排序 冒泡排序 快速排序 选择排序 简单选择排序 堆排序 二路归并排序 基数排序 选择算法需要考虑的因素 排序的分类 其中比较重要的已做标记&#xff0c;下面来简要介绍一下 基本概…

【Python】任推邦近30日推广数据采集+推送

不知道任推邦是啥的&#xff0c;可以查看之前的文章&#xff1a;夸克网盘扩容N次20T的方法 本文主要是针对夸克网盘的&#xff0c;其他项目有的没有提供接口&#xff0c;如果有也自行抓包&#xff0c;参考修改一下就行了。主要是将接口返回内容以html表格形式进行推送&#xf…

数据结构-二叉树(java实现)及相关的oj题

文章目录 树树的定义&#xff1a;关于树的相关概念&#xff1a;树的实际实现形式&#xff08;表现形式&#xff09;树的应用 二叉树二叉树的概念特殊的二叉树二叉树的性质&#xff1a;二叉树的存储实现&#xff1a;二叉树的模拟实现&#xff1a;实现的成员方法与属性&#xff1…

CSS3中动画的制作案例

直接上代码 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>-webkit-keyframes expand {0% {border-width: 4px;}50% {border-width: 12px;}100% {border-width: 4px;height: 130px;width: 15…

C#对象和类型

属性、方法、字段 字段和属性的区别 在C#中&#xff0c;字段&#xff08;fields&#xff09;和属性&#xff08;properties&#xff09;都是类的成员&#xff0c;它们提供了类存储数据的方式&#xff0c;但它们在用途和功能上有着明显的区别。 字段 字段通常用来存储类…

组合优化与凸优化相关算法 Julia实现

线性规划 方法有单纯形法&#xff08;简单&#xff0c;非多项式&#xff09;&#xff0c;椭圆法&#xff08;复杂&#xff0c;多项式&#xff0c;仅有理论价值&#xff09;&#xff0c;内点法&#xff08;非多项式&#xff0c;实际效率高&#xff09;。 以例子说明&#xff0…

C++第五篇 类和对象(下) 初始化列表

目录 1.再探构造函数 2.类型转换 3.static成员 4.友元 friiend 1.再探构造函数 (1).之前我们实现构造函数时&#xff0c;初始化成员变量主要使用函数体内赋值&#xff0c;构造函数初始化还有一种方式&#xff0c;就是初始化列表&#xff0c;初始化列表的使用方式是以一个冒…

[Spring] SpringBoot统一功能处理与图书管理系统

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…

分销商城小程序系统如何开发

uni-app框架&#xff1a;使用Vue.js开发跨平台应用的前端框架&#xff0c;编写一套代码&#xff0c;可编译到Android、小程序等平台。 框架支持:springboot/Ssm/thinkphp/django/flask/express均支持 前端开发:vue.js 可选语言&#xff1a;pythonjavanode.jsphp均支…

EDI是什么:EDI系统功能介绍

EDI全称Electronic Data Interchange&#xff0c;也被称为“无纸化贸易”。EDI实现企业间&#xff08;B2B&#xff09;自动化通信&#xff0c;帮助贸易伙伴和组织完成更多的工作、加快物流时间并消除人为错误。 EDI遵从国际报文标准&#xff0c;使得业务数据按照结构化或是标准…

音频文件怎么转换成mp3?这5种方法快速转换

音频文件格式繁多&#xff0c;从WAV到FLAC&#xff0c;从AAC到OGG&#xff0c;每一种都有其独特的优势和应用场景。但当我们需要将音频文件分享给朋友、上传到网络平台或进行跨设备播放时&#xff0c;MP3格式因其广泛的兼容性和较小的文件体积&#xff0c;往往成为首选。给大家…

「字符串」实现Trie(字典树|前缀树)的功能 / 手撕数据结构(C++)

概述 在浏览器搜索栏里输入几个字&#xff0c;就弹出了以你的输入为开头的一系列句子。浏览器是怎么知道你接下来要输什么的&#xff1f; 来看看字典树干了什么。 字典树是一种高效记录字符串和查找字符串的数据结构。它以每个字符作为一个节点对字符串进行分割记录&#xff0c…

48 集合应用案例

编写代码时除了要准确地实现功能之外&#xff0c;还要考虑代码的优化&#xff0c;尽量找到一种更快、更好的方法实现预定功能。Python 字典和集合都使用哈希表来存储元素&#xff0c;元素查找速度非常快&#xff0c;关键字 in 作用于字典和集合时比作用于列表要快得多。 impor…

【数据结构之单链表的实现(不带头)】

1.单链表 1.1概念与结构 链表是一种物理存储结构上非连续&#xff0c;非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针连接次序实现的。 可以用下图便于理解 节&#xff08;结&#xff09;点&#xff1a; 与顺序表不同的是&#xff0c;链表里面的每节“车…

三十种未授权访问漏洞合集

未授权访问漏洞介绍 未授权访问可以理解为需要安全配置或权限认证的地址、授权页面存在缺陷&#xff0c;导致其他用户可以直接访问&#xff0c;从而引发重要权限可被操作、数据库、网站目录等敏感信息泄露。---->目录遍历 目前主要存在未授权访问漏洞的有:NFS服务&a…

百度飞桨 OCR识别

百度飞桨 OCR识别代码 import warnings import time import cv2 as cv import paddlehub as hub # Load the image img cv.imread("1.jpg") height, width, channels img.shape imglist [img] ocr hub.Module(name"ch_pp-ocrv3", enable_mkldnnTrue) …