opencv 图像的缩放(放大,缩小),翻转与旋转

目录

opencv 图像的缩放(放大,缩小),翻转,旋转1、图像的缩放,旋转过程中为什么需要插值:2、常见的插值算法包括:3、图像的缩放,翻转,旋转:(1)图像的缩放 cv2::resize(),用于改变图像大小的函数,它可以用于图像的放大、缩小操作:函数原型:示例:将一个图像缩小为原来的一半(2)图像的翻转 cv2::flip(),用于实现图像翻转(镜像)操作的函数,它可以在水平方向、垂直方向或者同时在两个方向上进行翻转:函数原型:示例:将一个图像沿水平方向进行翻转(3)图像的旋转 cv2::warpAffine(),用于实现图像仿射变换的函数(图像仿射变换是指对图像进行平移、旋转、缩放、翻转等几何变换的操作)函数原型:示例:将一个图像按照指定角度进行旋转上面例子旋转后图像并不能保证完全可见,还需要计算旋转后图像的宽度和高度,以及旋转后中心点坐标。


opencv 图像的缩放(放大,缩小),翻转,旋转

1、图像的缩放,旋转过程中为什么需要插值:
通过使用适当的插值方法,可以确保图像在变换过程中保持合理的视觉品质和准确性;

(1)非整数坐标位置: 在进行缩放、翻转、旋转等变换时,新位置的坐标通常是浮点数,不一定是整数。例如,对于一个2倍放大的操作,像素的坐标会变成原来的两倍,如1.5、3.7等。但图像只能在整数坐标位置获取像素值;

(2)保持图像连续性: 插值算法可以保持图像在变换过程中的连续性和平滑性,避免出现锯齿状的边缘或形变;

2、常见的插值算法包括:
最近邻插值(cv2::INTER_NEAREST): 选择距离变换位置最近的一个像素的值作为新位置的像素值;
双线性插值(cv2::INTER_LINEAR): 使用相邻四个像素的加权平均值来估计新位置的像素值;
双三次插值(cv2::INTER_CUBIC): 使用相邻16个像素的加权平均值来估计新位置的像素值;
3、图像的缩放,翻转,旋转:
(1)图像的缩放 cv2::resize(),用于改变图像大小的函数,它可以用于图像的放大、缩小操作:
函数原型:

void cv::resize(
    InputArray src,
    OutputArray dst,
    Size dsize,
    double fx = 0, 
    double fy = 0,
    int interpolation = INTER_LINEAR
);

参数解释:
src:输入图像;
dst:输出图像;
dsize:输出图像的大小,通常使用cv::Size()来指定; 
fx:沿水平轴的缩放因子,如果设置为0,则通过 fy 来确定缩放比例; 
fy:沿垂直轴的缩放因子,如果设置为0,则通过 fx 来确定缩放比例; 
interpolation:插值算法(
    INTER_NEAREST
    INTER_LINEAR    默认
        INTER_CUBIC    适合放大操作
); 

示例:将一个图像缩小为原来的一半

#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>

using namespace cv;
using namespace std;

int main() {
    //读取图像,BGR存储在Mat矩阵里
    Mat src = cv::imread("C:\\cpp\\image\\suzy4.jpg");
    if (src.empty()) {
        printf("could not load image..../n");
        return -1;
    }

    imshow("src", src);

    // 通过指定缩放因子,将图像缩小为原来的一半
    cv::Mat amplify1, amplify2, reduce1, reduce2;
    cv::resize(src, amplify1, cv::Size(), 0.5, 0.5, cv::INTER_LINEAR);
    cv::imshow("amplify1", amplify1);

    // 通过指定输出图像的尺寸,将图像缩小为原来的一半
    int w = src.cols;
    int h = src.rows;
    cv::resize(src, amplify2, cv::Size(w/2, h/2), 0, 0, cv::INTER_LINEAR);
    cv::imshow("amplify2", amplify2);

    // 通过指定缩放因子,将图像放大为原来的1.5倍
    cv::resize(src, reduce1, cv::Size(), 1.5, 1.5, cv::INTER_LINEAR);
    cv::imshow("reduce1", reduce1);

    // 通过指定输出图像的尺寸,将图像放大为原来的1.5倍
    cv::resize(src, reduce2, cv::Size(w*1.5, h*1.5), 0, 0, cv::INTER_LINEAR);
    cv::imshow("reduce2", reduce2);

    waitKey();
    destroyAllWindows();
    return 0;
}

(2)图像的翻转 cv2::flip(),用于实现图像翻转(镜像)操作的函数,它可以在水平方向、垂直方向或者同时在两个方向上进行翻转:
函数原型:

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

参数解释:
src:输入图像;
dst:输出图像;
flipCode:翻转方式(
    0    -> 沿x轴翻转(垂直翻转)(上下翻转)
    1    -> 沿y轴翻转(水平翻转)(左右翻转)
    -1    -> 同时沿x和y轴翻转(对角线翻转)
); 

示例:将一个图像沿水平方向进行翻转

#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>using namespace cv;
using namespace std;int main() {//读取图像,BGR存储在Mat矩阵里Mat src = cv::imread("C:\\cpp\\image\\suzy1.jpg");if (src.empty()) {printf("could not load image..../n");return -1;}imshow("src", src);cv::Mat flipped_image;cv::flip(src, flipped_image, 1);    // 沿y轴翻转cv::imshow("Flipped Image", flipped_image);waitKey();destroyAllWindows();return 0;
}

 (3)图像的旋转 cv2::warpAffine(),用于实现图像仿射变换的函数(图像仿射变换是指对图像进行平移、旋转、缩放、翻转等几何变换的操作)

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

1、参数解释:
src:输入图像;
dst:输出图像;
M:仿射变换矩阵,用于定义变换关系,这里定义的是旋转矩阵,需要借助cv2.getRotationMatrix2D()函数定义图像旋转参数,函数返回一个cv::Mat类型的矩阵,其中包含了进行旋转变换的矩阵信息;
dsize:输出图像的大小,通常使用cv::Size()来指定;  
flags :插值算法(
    INTER_NEAREST
    INTER_LINEAR    默认
        INTER_CUBIC    适合放大操作
); 
borderMode:边界模式,默认为BORDER_CONSTANT常数边界模式;
borderValue:borderValue默认值等于Scalar(),表示创建一个所有通道值为0的常量颜色,

2、定义旋转矩阵:
cv::Mat cv::getRotationMatrix2D(
    cv::Point2f center,     // 旋转的中心坐标 (x, y),类型为cv::Point2f,使用的是浮点数作为坐标
    double angle,         // 旋转角度,以度为单位(正值表示逆时针旋转,负值表示顺时针旋转)
    double scale        // 缩放比例,可选参数,默认为1.0
);

3、注意:
const Scalar& borderValue = Scalar()表达式的含义如下:
Scalar 是OpenCV库中用于表示多通道颜色值的数据类型,可以包括1到4个通道;
borderValue 是函数的参数名,它表示用于边界填充的颜色值;
=Scalar() 表示给定参数的默认值,在这里Scalar()创建了一个所有通道值为0的标量(黑色),用于作为默认的边界填充颜色;
const修饰符,表示borderValue是一个常量引用,即在函数中不能对其进行修改;

#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>

using namespace cv;
using namespace std;

int main() {
    //读取图像,BGR存储在Mat矩阵里
    Mat src = cv::imread("C:\\cpp\\image\\suzy1.jpg");
    if (src.empty()) {
        printf("could not load image..../n");
        return -1;
    }
    //namedWindow("src", WINDOW_NORMAL);
    imshow("src", src);

    cv::Mat rotated_image;
    // 图像src的中心点坐标
    cv::Point2f center(src.cols/2.0, src.rows/2.0);
    // 定义一个角度
    double angle = 45.0;
    // 定义了一个旋转矩阵
    cv::Mat rotation_matrix = cv::getRotationMatrix2D(center, angle, 1.0);
    // 将图像按照定义的rotation_matrix旋转变换的矩阵信息,进行旋转
    cv::warpAffine( src, rotated_image, rotation_matrix, src.size(), INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 255) );

    cv::imshow("Rotated Image", rotated_image);

    waitKey();
    destroyAllWindows();
    return 0;
}

上面例子旋转后图像并不能保证完全可见,还需要计算旋转后图像的宽度和高度,以及旋转后中心点坐标

#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>using namespace cv;
using namespace std;int main() {//读取图像,BGR存储在Mat矩阵里Mat src = cv::imread("C:\\cpp\\image\\suzy1.jpg");if (src.empty()) {printf("could not load image..../n");return -1;}//namedWindow("src", WINDOW_NORMAL);imshow("src", src);cv::Mat dst;int w = src.cols;int h = src.rows;// 图像src的中心点坐标cv::Point2f center(w/2.0, h/2.0);// 定义一个角度double angle = 45.0;// 定义了一个旋转矩阵cv::Mat M = cv::getRotationMatrix2D(center, angle, 1.0);// 下几行代码用于调整旋转后图像的位置,确保旋转后图像完全可见double cos = abs(M.at<double>(0, 0));double sin = abs(M.at<double>(0, 1)); // 旋转后图像的宽度nw和高度nhint nw = int( abs(cos)*w + abs(sin)*h );int nh = int( abs(sin)*w + abs(cos)*h );// 旋转后图像的中心点位置M.at<double>(0, 2) += (nw/2 - w/2);M.at<double>(1, 2) += (nh/2 - h/2);// 由于计算出的 nw 和 nh 可能是浮点数,但 cv::warpAffine()函数的第四个参数(目标图像的大小)需要整数类型cv::Size newSize(nw, nh);// 将图像按照定义的rotation_matrix旋转变换的矩阵信息,进行旋转cv::warpAffine( src, dst, M, newSize, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 255, 255) );cv::imshow("Rotated Image", dst);waitKey();destroyAllWindows();return 0;
}

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

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

相关文章

混凝土搅拌站中的智能化系统应用

随着科技的飞速发展&#xff0c;混凝土搅拌站已经进入了现代化、智能化的新时代。现代自动化、智能化技术的应用&#xff0c;使得混凝土搅拌站更加高效、准确、可靠&#xff0c;同时也提高了生产效率和质量。本文将带你深入探索混凝土搅拌站中运用到现代自动化、智能化的方方面…

Java代码基础算法练习-删除有序数组中的重复项-2024.05.07

任务描述&#xff1a; 有一批同学需要计算各自的出生年月是否闰年。请使用算法计算出他们的出生年份是否闰年。 解决思路&#xff1a; 如果要一次性输出结果&#xff0c;就是先输入数字n&#xff0c;确定首先循环几次&#xff0c;在每次循环中进行闰年判断操作&#xff0c;每次…

国外的Claude3.5 Sonnet Artifacts和国内的CodeFlying孰强孰弱?

在Claude 3.5 Sonnet发布后&#xff0c;最受大家关注的问题应该就是它在编写代码能力上的变化。 要知道在Claude3.0发布以来的这几个月就因为它的编写代码能力而一直受到人们的诟病。 那Anthropic这次终于是不负众望&#xff0c;在Claude 3.5 Sonnet中更新了一个叫做Artifact…

【STM32】SysTick系统滴答定时器

1.SysTick简介 CM4内核的处理和CM3一样&#xff0c;内部都包含了一个SysTick定时器&#xff0c;SysTick 是一个24 位的倒计数定时器&#xff0c;当计到0 时 &#xff0c;将 从RELOAD 寄存器中自动重装载定时初值。只要不把它在SysTick 控制及状态寄存器中的使能位清除&#xf…

使用阿里云效API操作流水线

使用阿里云效&#xff08;Alibaba Cloud DevOps&#xff09;API操作流水线时&#xff0c;需要注意以下几个方面&#xff1a; 认证与授权 确保你已经获取了正确的访问凭证&#xff08;AccessKey ID 和 AccessKey Secret&#xff09;&#xff0c;并且这些凭证具有足够的权限来执行…

优维“统一开放平台”:开放、开发、集成、客制化

基于丰富完善的产品体系&#xff0c;优维重磅推出了统一开放平台。这款由优维自主设计与研发&#xff0c;集数据开发、能力开放、能力集成、客制化为一体的统一开放平台&#xff0c;具备应用市场、应用开发、连接能力、采控平台、API集市、开发者工具等功能模块&#xff0c;可为…

探索MySQL的执行奥秘:从查询执行到数据存储与优化的深入解析

MySQL是一个功能强大且广泛应用的关系数据库管理系统。理解MySQL的执行机制、优化策略以及数据存储方式&#xff0c;对于数据库开发和管理至关重要。本文将详细解析这些内容&#xff0c;通过具体实例和实用建议&#xff0c;帮助读者深入掌握MySQL的高级特性。 一、MySQL的执行…

【RNN练习】LSTM-火灾温度预测

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前期准备工作 import torch.nn.functional as F import numpy as np import pandas as pd import torch from torch import nn1. 导入数据 data pd.read_cs…

Linux中信号的机制

在操作系统中,信号是一种软件中断,用于通知进程某个事件已经发生。信号可以分为两大类:同步信号和异步信号。 同步信号(Synchronous Signals) 同步信号通常是由于进程执行中的异常情况引起的,比如违反内存访问规则(段错误),执行非法指令(非法指令),或其他导致核心…

LLM大模型实战 —— DB-GPT阿里云部署指南

简介&#xff1a; DB-GPT 是一个实验性的开源应用&#xff0c;它基于FastChat&#xff0c;并使用vicuna-13b作为基础模型, 模型与数据全部本地化部署, 绝对保障数据的隐私安全。 同时此GPT项目可以直接本地部署连接到私有数据库, 进行私有数据处理&#xff0c; 目前已支持SQL生…

慌慌张张,匆匆忙忙,又是学习的一天

今天学进程 进程的状态 &#xff08;本科的考点我记得哈哈&#xff09; 什么是线程 线程的状态 线程和进程的区别 一个共享 一个私有 独立 多线程的优缺点 线程的分类 内核支持线程 用户级线程 组合方式线程 协程coroutine 进程 分配资源的最小单位 线程 是cpu调度的最小…

Spring AI之后,阿里推出Spring Cloud Alibaba AI,接入体验篇——Java也能方便用 AI

阿里推出Spring Cloud Alibaba AI&#xff0c;接入体验篇——Java也能方便用 AI 1.Spring AI2.Spring Cloud Alibaba AI3. 接入体验 1.Spring AI Spring AI 是 Spring 官方社区项目&#xff0c;旨在简化 Java AI 应用程序开发&#xff0c;让 Java 开发者像使用 Spring 开发普通…

NSSCTF-Web题目18(反序列化)

目录 [NISACTF 2022]babyserialize 1、题目 2、知识点 3、思路 [SWPUCTF 2022 新生赛]ez_ez_unserialize 4、题目 5、知识点 6、思路 [NISACTF 2022]babyserialize 1、题目 2、知识点 反序列化、绕过过滤、命令执行 3、思路 <?php include "waf.php";…

基于Vue,mysql,JavaEE的简单投票与投票管理系统

项目介绍 ​ 本项目&#xff0c;基于Vue2.6,mysql,JavaEE 实现简单的投票与投票管理系统 项目地址 VotingSystem: 投票系统1.0 管理员和普通用户 (gitee.com) 有问题请评论私聊哦 项目分类 数据库 创建投票人&#xff0c;被投票人&#xff0c;投票关系&#xff08;追踪谁…

float8格式

产生背景 在人工智能神经元网络中&#xff0c;一个参数用1字节表示即可&#xff0c;或者说&#xff0c;这是个猜想&#xff1a;因为图像的颜色用8比特表示就够了&#xff0c;所以说&#xff0c;猜想神经元的区分度应该小于256。 数字的分配 8比特有256个码位&#xff0c;分为…

图论学习 c++长方体嵌套问题

一个长&#xff0c;宽&#xff0c;高为X1&#xff0c;X2&#xff0c;X3的长方体之中算法可以存放一个长&#xff0c;宽&#xff0c;高Y1&#xff0c;Y2&#xff0c;Y3的长方体。备注两个长方体都可以旋转&#xff0c;下面是一个C程序&#xff0c;用于确定一个长方体是否可以放入…

Cython编译报错“numpy/arrayobject.h: No such file or directory”解决方案

问题背景 Cython是用来加速Python程序性能的一个工具&#xff0c;其基本使用逻辑就是将类Python代码(*.pyx扩展格式)编译成\(*.c,*.so\)动态链接库文件&#xff0c;然后就可以在正常的Python脚本文件中调用动态链接库的内部函数。编译过程中因为会去索引一些头文件&#xff0c;…

【操作与配置】WSL配置LINUX

WSL2&#xff08;Windows Subsystem for Linux 2&#xff09;是Microsoft开发的一项技术&#xff0c;允许用户在Windows操作系统上运行Linux发行版。WSL2是WSL&#xff08;Windows Subsystem for Linux&#xff09;的第二版&#xff0c;带来了许多改进和新特性。 官网&#xff…

EXCEL 复制后转置粘贴

nodepad 转置参考&#xff1a; https://editor.csdn.net/md/?articleId140014651 1. WPS复制后转置粘贴 复制-》右键-》顶部第一行-》粘贴行列转置&#xff0c;如下图&#xff1a; 2. Excel office365 本地版 2. Excel office365 在线版

涨知识!推荐6个非常好用的App!

AI视频生成&#xff1a;小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频https://aitools.jurilu.com/我从 50 个应用程序中选出了 6 个超级实用的应用程序。 每款应用程序都是最核心、最有益的知识提升工具&#xff01;每天打开它们&#xff0c;提神…