python学opencv|读取图像(三十一)缩放图像的三种方法

news2025/1/15 21:38:38

【1】引言

前序学习进程中,我们至少掌握了两种方法,可以实现对图像实现缩放。

第一种方法是调用cv2.resize()函数实现,相关学习链接为:

python学opencv|读取图像(三)放大和缩小图像_python opencv 读取图片缩放-CSDN博客

第二种方法是在cv2.getRotationMatrix2D()函数旋转缩放图像时,顺带实现了图像缩放:

python学opencv|读取图像(二十八)使用cv2.getRotationMatrix2D()函数旋转缩放图像-CSDN博客

实际上,对于第二种方法,如果我们只设置旋转角度=0,其实就是只对图像进行放大和缩小。为验证这个猜想,我们可以做测试。

【2】前两种方法代码测试

【2.1】cv2.getRotationMatrix2D()函数缩放

首先我们给出完整代码:

import cv2 as cv # 引入CV模块
import numpy as np #引入numpy模块

# 读取图片
src = cv.imread('src.png')
rows=len(src) #读取图像行数
cols=len(src[0]) #读取图像列数
center=(rows/2,cols/2) #旋转中心
#M=np.float32([[1,0,50],
              #[0,1,200]]) #M矩阵,x=50,y=200
M=cv.getRotationMatrix2D(center,0,0.8) #旋转并缩放图像
dst=cv.warpAffine(src,M,(cols,rows)) #输出图像
cv.imshow('src-pingyi', dst)  # 在屏幕展示绘制圆形的效果
cv.imwrite('src-suofang.png', dst)  # 保存图像
cv.waitKey()  # 图像不会自动关闭
cv.destroyAllWindows()  # 释放所有窗口

其中对于函数的设置,把旋转角度设定为0,缩放倍数为0.8:

M=cv.getRotationMatrix2D(center,0,0.8) #旋转并缩放图像

使用的原始图像为:

图1 src.png

缩放后的图像为:

图2  缩小0.8倍后的图像

如果我们把缩放倍数放大到1.5倍:

M=cv.getRotationMatrix2D(center,0,1.5) #旋转并缩放图像

代码运行后的图像为:

图3 放大1.5倍后的图像

其实对比图1、图2和图3,会发现图3对原始图像进行了裁切,这种放大效果和cv2.resize()函数相比不一样,cv2.resize()函数本身不会裁切。

【2.2】cv2.resize()函数缩放

为了实现对比cv2.resize()函数放大效果的对比,调用该函数来放大图像,给出完整代码如下:

import cv2  # 引入CV模块

# 读取图片
image = cv2.imread('src.png')

# 定义放大因子
scale_factor = 1.5

# 放大图片,使用立方插值
scaled_image = cv2.resize(image, None, fx=scale_factor, fy=scale_factor, interpolation=cv2.INTER_CUBIC)  # INTER_CUBIC插值

# 保存结果
cv2.imwrite('scaled_image-001-INTER_CUBIC m15.png', scaled_image)

# 显示结果
cv2.imshow('Scaled Image15 ', scaled_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

代码运行后的输出效果为:

图4 图片放大1.5倍但没有任何裁切

由图4可见,图片放大了1.5倍,但没有任何裁切。

【3】第三种方法

在前序学习进程中,我们成功实现了对图像的倾斜拉伸,相关链接为:

python学opencv|读取图像(二十九)使用cv2.getAffineTransform()函数倾斜拉伸图像-CSDN博客

文章中已经说明,倾斜拉伸是通过控制图像的顶点实现的。首次启发,我们把图像的顶点按照固定比例缩小和放大,这样就能实现图像的缩放。为此,展开代码测试。

这里使用的原始图像为:

图5

【3.1】缩小

首先给出完整代码:

import cv2 as cv # 引入CV模块
import numpy as np #引入numpy模块

# 读取图片
src = cv.imread('srcm.png')

#设置点
rows=len(src) #读取图像行数
cols=len(src[0]) #读取图像列数
p1=np.zeros((3,2),np.float32) #32位浮点型全0矩阵
p1[0]=[0,0] #第一点
p1[1]=[cols-1,0] #第二点
p1[2]=[0,rows-1] #第三点
p2=np.zeros((3,2),np.float32) #32位浮点型全0矩阵
p2[0]=[0,0] #新的第一点
p2[1]=[0.8*(cols-1),0] #新的第二点
p2[2]=[0,0.8*(rows-1)] #新的第三点

#center=(rows/2,cols/2) #旋转中心
#M=np.float32([[1,0,50],
              #[0,1,200]]) #M矩阵,x=50,y=200
M=cv.getAffineTransform(p1,p2)
#M=cv.getRotationMatrix2D(center,60,0.8) #旋转并缩放图像
dst=cv.warpAffine(src,M,(cols,rows)) #输出图像
cv.imshow('srcm-qxls', dst)  # 在屏幕展示绘制圆形的效果
cv.imwrite('srcm-qxls-8.png', dst)  # 保存图像
cv.waitKey()  # 图像不会自动关闭
cv.destroyAllWindows()  # 释放所有窗口

在这里,对新的点设置了0.8倍的缩小因子:

p1=np.zeros((3,2),np.float32) #32位浮点型全0矩阵
p1[0]=[0,0] #第一点
p1[1]=[cols-1,0] #第二点
p1[2]=[0,rows-1] #第三点
p2=np.zeros((3,2),np.float32) #32位浮点型全0矩阵
p2[0]=[0,0] #新的第一点
p2[1]=[0.8*(cols-1),0] #新的第二点
p2[2]=[0,0.8*(rows-1)] #新的第三点

代码运行后的输出效果为:

图6 缩小0.8倍

由图6可见,图像成功缩小为原来的0.8倍。

【3.2】放大

修改缩放因子,把图像放大1.5倍:

p1=np.zeros((3,2),np.float32) #32位浮点型全0矩阵
p1[0]=[0,0] #第一点
p1[1]=[cols-1,0] #第二点
p1[2]=[0,rows-1] #第三点
p2=np.zeros((3,2),np.float32) #32位浮点型全0矩阵
p2[0]=[0,0] #新的第一点
p2[1]=[1.5*(cols-1),0] #新的第二点
p2[2]=[0,1.5*(rows-1)] #新的第三点

此时,会惊喜地发现一个猫猫头:

图7 放大1.5倍

显然,cv2.getAffineTransform()函数在放大图像的时候,也会对图像进行裁切。

【4】效果对比

结合上面的使用效果,会发现:

使用cv2.getRotationMatrix2D()函数、cv2.resize()函数和cv2.getAffineTransform函数均可以实现图像缩放;

在图像缩小效果上,三个函数差不多,只是cv2.getRotationMatrix2D()函数和cv2.getAffineTransform函数会保留原本画布的大小,会看到一些纯色的背景;

在图像放大效果上,三个函数不一样,cv2.getRotationMatrix2D()函数和cv2.getAffineTransform函数会会裁切图像依然会保留原有画布的大小,图像超出画布大小的部分会被裁切,而cv2.resize()函数不会裁切图像,会等比例放大图像的所有部分。

图8 三种图像缩放效果对比

【5】总结

掌握了python+opencv实现图像缩放的三种方法。

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

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

相关文章

rk3568 , buildroot , qt ,使用sqlite, 动态库, 静态库

问题说明: 客户反馈 ,buildroot 系统 ,使用qt 使用sqlite ,有报错,无法使用sqlite. 测试情况说明: 我自己测试,发现, buildroot 自己默认就是 使能了 sqlite 的。 是否解决说明&…

Windows图形界面(GUI)-QT-C/C++ - Qt图形绘制详解

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 Qt绘图基础 QPainter概述 基本工作流程 绘图事件系统 paintEvent事件 重绘机制 文字绘制技术 基本文字绘制 ​编辑 高级文字效果 基本图形绘制 线条绘制 ​编辑 形状绘制 …

OpenArk64:Windows 系统分析与逆向工程工具详解

引言 在 Windows 系统的底层操作和逆向工程领域,OpenArk 是一款备受推崇的开源工具集。而 OpenArk64.exe 是 OpenArk 工具的 64 位版本,专门用于 64 位 Windows 系统。它提供了强大的功能,帮助用户深入分析系统内核、进程、文件、注册表等&a…

浅谈计算机网络02 | SDN控制平面

计算机网络控制平面 一、现代计算机网络控制平面概述1.1 与数据平面、管理平面的关系1.2 控制平面的发展历程 二、控制平面的关键技术剖析2.1 网络层协议2.1.1 OSPF协议2.1.2 BGP协议 2.2 SDN控制平面技术2.2.1 SDN架构与原理2.2.2 OpenFlow协议2.2.3 SDN控制器 一、现代计算机…

【C++】PP5015 [NOIP2018 普及组] 标题统计

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 提示数据规模与约定 💯方法分析方法1:我的做法实…

从玩具到工业控制--51单片机的跨界传奇【2】

咱们在上一篇博客里面讲解了什么是单片机《单片机入门》,让大家对单片机有了初步的了解。我们今天继续讲解一些有关单片机的知识,顺便也讲解一下我们单片机用到的C语言知识。如果你对C语言还不太了解的话,可以看看博主的C语言专栏哟&#xff…

线程池面试题目集合

最近面试中总是问到ThreadPoolExecutor类相关问题,在此集中整理下。 问题1.ThreadPoolExecutor的关键参数是哪些,任务添加过程中,内部线程是怎样构建的? a)任务到达时,线程池数目小于核心线程数corePoolSize&#xff0…

程序员独立开发竞品分析:确定网站使用什么建站系统

要确定一个网站使用的建站系统,可以通过以下几种方法尝试分析: 查看页面源代码: 打开网站,右键点击页面并选择“查看页面源代码”。在代码中查找一些常见的建站系统标志,例如: WordPress 的迹象&#xff1a…

基于Media+Unity的手部位姿三维位姿估计

使用mediapipe Unity 手部位姿三维位姿估计 参考文章 基于Mediapipe的姿势识别并同步到Unity人体模型中 MediapipeUnity3d实现虚拟手_unity mediapipe-CSDN博客 需求 我的需求就是快速、准确的跟踪手部位姿并实现一个三维显示。 主要思路 搭建mdeiapipe系统&#xff0c…

构建高性能网络服务:从 Socket 原理到 Netty 应用实践

1. 引言 在 Java 网络编程中,Socket 是实现网络通信的基础(可以查看我的上一篇博客)。它封装了 TCP/IP 协议栈,提供了底层通信的核心能力。而 Netty 是在 Socket 和 NIO 的基础上,进一步封装的高性能、异步事件驱动的…

Python入门10:高阶函数

一、什么是高阶函数 1.1、高阶函数的概念和作用: 高阶函数是指 接受函数作为参数 或者 返回函数 作为结果的函数。它在函数式编程中是一个重要概念(函数式编程(Functional Programming , FP )是一 种编程范式&#xf…

python-leetcode-矩阵置零

73. 矩阵置零 - 力扣(LeetCode) class Solution:def setZeroes(self, matrix: List[List[int]]) -> None:"""Do not return anything, modify matrix in-place instead."""m, n len(matrix), len(matrix[0])row_zero …

MySQL数据库(SQL分类)

SQL分类 分类全称解释DDLData Definition Language数据定义语言,用来定义数据库对象(数据库,表,字段)DMLData Manipulation Language数据操作语言,用来对数据库表中的数据进行增删改DQLData Query Languag…

计算机网络 笔记 网络层1

网络层功能概述 主要的任务是把分组从源端传输到目的端,为分组交换网上的不同主句提供通信服务,网络层的传输单位是数据报。 主要的功能; 1,路由选择:路由选择指网络层根据特定算法,为数据包从源节点到目…

MyBatis-什么是MyBatis?以及MyBatis的快速入门。

简介 什么是 MyBatis? 什么是MyBatis? MyBatis是一款优秀的 持久层 框架,用于简化JDBC的开发。(框架:是一个半成品软件,是一套可重用的、通用的、软件基础代码模型。在框架的基础上进行软件开发更加高效、规范、通用、…

Linux Kernel 之十 详解 PREEMPT_RT、Xenomai 的架构、源码、构建及使用

概述 现在的 RTOS 基本可以分为 Linux 阵营和非 Linux 阵营这两大阵营。非 Linux 阵营的各大 RTOS 都是独立发展,使用上也相对独立;而 Linux 阵营则有多种不同的实现方法来改造 Linux 以实现实时性要求。本文我们重点关注 Linux 阵营的实时内核实现方法! 本文我们重点关注 …

Swift 趣味开发:查找拼音首字母全部相同的 4 字成语(上)

概述 Swift 语言是一门现代化、安全、强大且还算性感的语言。在去年 WWDC 24 中苹果正式推出了秃头码农们期待许久的 Swift 6.0,它进一步完善了 Swift 语言的语法和语义,并再接再厉——强化了现代化并发模型的安全性和灵活性。 这里我们不妨用 Swift 来…

docker一张图理解

1、push 将本地的镜像上传到镜像仓库,要先登陆到镜像仓库。参数说明: –disable-content-trust : 忽略镜像的校验,默认开启 # 上传本地镜像myapache:v1到镜像仓库中。 docker push myapache:v1 1.2、search 从Docker Hub查找镜像。参数说明: –…

IoTDB 常见问题 QA 第三期

关于 IoTDB 的 Q & A IoTDB Q&A 第三期持续更新!我们将定期汇总我们将定期汇总社区讨论频繁的问题,并展开进行详细回答,通过积累常见问题“小百科”,方便大家使用 IoTDB。 Q1:查询最新值 & null 数据相加方…

MyBatis实现数据库的CRUD

本文主要讲解使用MyBatis框架快速实现数据库中最常用的操作——CRUD。本文讲解的SQL语句都是MyBatis基于注解的方式定义的,相对简单。 Mybatis中#占位符和$拼接符的区别 “#”占位符 在使用MyBatis操作数据库的时候,可以直接使用如下SQL语句删除一条数…