OpenCV对图像进行尺寸变换

简 介: 本博文给你展示了如何通过指定输出结果的宽高来对图像进行尺寸变化。你也了解如何根据比例因子来保持图像的纵横比不发生变化,从而在改变图像尺寸的过程中图像不发生形变。最后也讨论了不同的插值方法如何改变尺寸变化的结果的。

关键词 resizeOpenCV图片尺寸

简 介
目 录
Contents
样例代码
读入图像
尺寸变化
指定宽高
指定比例
插值方法
总 结
图片尺寸变化
网络演示程序

本文翻译自 Image Resizing with OpenCV中对事OpenCV中对于图像进行尺寸变换。

 

§00   介

  下面我们来谈谈如何通过OpenCV来对图片进行尺寸变化。 所谓的图片尺寸变化,就是沿着不同的坐标轴(也就是图片的高、宽)进行收缩,通过指定收缩尺度比例因子或者直接指定结果图片的尺寸(高、宽)。

  在进行图片尺寸变换的时候:

  • 如果你想保持图片不变形,维持相同的纵横比,则需要注意原始图像的尺寸比例(也就是宽度比上高度的数值)。
  • 在降低图片尺寸的时候,需要对于是图像进行重采样。
  • 增加图片的尺寸,则要求对图像进行重构,这意味着需要通过插值来获得增加像素点的数值。

  不同的插值方法用于完成这些操作。OpenCV也提供了部分这些方法,针对不同的应用可以选择合适的插值方法。

0.1 样例代码

  下面的代码通过指定对应的高、宽来对图像 进行拉伸或者压缩。随着你进一步研读代码,我们将进一步讨论是所有不同的尺度因子和插值方法来实现对图像的尺寸变化。

0.1.1 Python代码

# let's start with the Imports 
import cv2
import numpy as np# Read the image using imread function
image = cv2.imread('image.jpg')
cv2.imshow('Original Image', image)# let's downscale the image using new  width and height
down_width = 300
down_height = 200
down_points = (down_width, down_height)
resized_down = cv2.resize(image, down_points, interpolation= cv2.INTER_LINEAR)# let's upscale the image using new  width and height
up_width = 600
up_height = 400
up_points = (up_width, up_height)
resized_up = cv2.resize(image, up_points, interpolation= cv2.INTER_LINEAR)# Display images
cv2.imshow('Resized Down by defining height and width', resized_down)
cv2.waitKey()
cv2.imshow('Resized Up image by defining height and width', resized_up)
cv2.waitKey()#press any key to close the windows
cv2.destroyAllWindows()

0.1.2 C语言代码

// let's start with including libraries 
#include<opencv2/opencv.hpp>
#include<iostream>// Namespace to nullify use of cv::function(); syntax
using namespace std;
using namespace cv;int main()
{// Read the image using imread functionMat image = imread("image.jpg");imshow("Original Image", image);// let's downscale the image using new  width and heightint down_width = 300;int down_height = 200;Mat resized_down;//resize downresize(image, resized_down, Size(down_width, down_height), INTER_LINEAR);// let's upscale the image using new  width and heightint up_width = 600;int up_height = 400;Mat resized_up;//resize upresize(image, resized_up, Size(up_width, up_height), INTER_LINEAR);// Display Images and press any key to continueimshow("Resized Down by defining height and width", resized_down);waitKey();imshow("Resized Up image by defining height and width", resized_up);waitKey();destroyAllWindows();return 0;
}

 

§01 入图像


  先导入所需要的软件包。

  • Python
# Importing the libraries  
import cv2
import numpy as np
  • C++
#include<opencv2/opencv.hpp>
#include<iostream>
// Namespace to nullify use of cv::function(); syntax
using namespace std;
using namespace cv;

  下面这两漂亮的跑车就是下面代码测试中所使用的图片。
▲ 图1.1  用于实验的图片:一辆漂亮的跑车

▲ 图1.1 用于实验的图片:一辆漂亮的跑车

  • Python
# Reading image
image= cv2.imread('image.jpg')
  • C++
// Reading imageMat image = imread("image.jpg");

  请注意在上面的C++代码片段中,你需要先创先一个图像的矩阵实例,然后通过 imread() 函数读取图片。

  在你开始对图片进行尺寸变化之前,你需要先了解他的原始尺寸。通过以下方式方式可以获得图片的尺寸:

  • 使用 python中的 shape方法;
  • 在C++中通过 rows 和 cols 获得;

  image.shape是在Python中可以 获得对应的图像的高、宽以及颜色通道的数量。

  在C++中:

  • image.rows给出的图片的高;
  • image.columns 给出了图片的宽度;

  也可通过size()函数获得上述结果:

  • image.size().width:返回宽度;

  • image.size().height返回高度是数值。

  • Python

# Get original height and width
h,w,c = image.shape
print("Original Height and Width:", h,"x", w)
  • C++
// Get height and width
cout << "Original Height and Width :" << image.rows << "x" << image.cols << endl;

  一个重要事情需要记住,在OpenCV中输出的图片的形状为:heightwidthchannels的格式,但一些其他的上T片处理库则使用 width*height的格式。因此需要注意这方面的逻辑差异。

  OpenCV读取图片之后,在内存使用NumPy矩阵存储图片数据,所以一般情况下,你总可以通过矩阵的形状来确定图片的尺寸,也就是通过 rowscolumns(rows代表图片的高度,columns代表图片的宽度)。 因此,计时通过OpenCV过得他们的 形状,NumpPy矩阵法则在此也起作用。你所得到的图片数据形状为 heightwidth*channels。

 

§02 寸变化


  面让我们看看 OpenCV中的尺寸变化函数 resize() 的调用语法。 可以注意到它只要两个必须输入参数,其他参数都可以省略。

  1. 源图像;
  2. 所需要变化后的图像尺寸, dsize

  下面是resize的调用格式,后面给出了参数定义。

resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])
  • rc: It is the required input image, it could be a string with the path of the input image (eg: ‘test_image.png’).
  • dsize: It is the desired size of the output image, it can be a new height and width.
  • fx: Scale factor along the horizontal axis.
  • fy: Scale factor along the vertical axis.
  • interpolation: It gives us the option of different methods of resizing the image.

 

§03 定宽高


  面的例子是通过指定新的图像的宽高来对图像进行缩小。在下面的代码中:

  • 我们设置结果图像的宽为300, 高为200;

  • 这两个数字使用2D向量表示,这是resize() 函数要求的;

  • 我们同样指明插值的方法,这也是缺省的参数;

  • Python

# Set rows and columns 
# lets downsize the image using new  width and height
down_width = 300
down_height = 200
down_points = (down_width, down_height)
resize_down = cv2.resize(image, down_points, interpolation= cv2.INTER_LINEAR)
  • C++
// Set rows and columns 
// lets downsize the image using new width and heightint down_width = 300;int down_height = 200;Mat resize_down;// resize downresize(image, resize_down, Size(down_width, down_height), INTER_LINEAR);

  下面我们使用另外的尺寸来变换图像。

  • Python
# Set rows and columns
up_width = 600
up_height = 400
up_points = (up_width, up_height)
# resize the image
resized_up = cv2.resize(image, up_points, interpolation = cv2.INTER_LINEAR)
  • C++
// Set rows and columns
int up_width = 600;
int up_height = 400;
Mat resized_up;
//resize up
resize(image, resized_up, Size(up_width, up_height), INTER_LINEAR);

  在上面Python代码片段中,我们通过定义型的宽、高来拉伸原始图像,这都是通过 resize() 这个函数,处理过程与前面缩小图像的过程是一样的。

  在C++的代码片段中:

  • 我们通过定出了新的宽、高整形数来拉伸图像;
  • 获得了输出图的矩阵;
  • 使用相同的 resize() 函数进行上述操作;

  现在,我们通过OpenCV中的imshow()来显示变化后的图像。

  • Python
# Display images
cv2.imshow('Resized Down by defining height and width', resized_down)
cv2.waitKey()
cv2.imshow('Resized Up image by defining height and width', resized_up)
cv2.waitKey()
cv2.destroyAllWindows()
  • C++
// Display Images and press any key to continue
imshow("Resized Down by defining height and width", resized_down);
waitKey();
imshow("Resized Up image by defining height and width", resized_up);
waitKey();
destroyAllWindows();

▲ 图3.1  尺寸变化后的两个图像:左:缩小尺寸;右:拉伸尺寸

▲ 图3.1 尺寸变化后的两个图像:左:缩小尺寸;右:拉伸尺寸

  上面图像中,左边的图像是缩小的图片,右边的图像是拉伸后的图片。

  正如我们期望的那样,我们通过resize改变了图像的尺寸,图像可以增大,也可以缩小,这都是根据给定的高和宽参数来决定的。

  但我们可以感觉得,通过这样指明高和宽参数来改变图像的大小,对于图像来说好像出现了变形,也就是图像的宽高比发生了改变,也就是图像的纵横比例发生的改变。

  怎么纠正这个问题呢。好的,下面我们可以通过指定比例因子来进行尺寸变换。

 

§04 定比例


  OK,下面我们通过指定比例因子来改变图片的尺寸。不过首先需要了解什么事比例因子。

  比例因子,也称尺度因子也就是一个数字,用于乘以,或者按比例改变某些数值。在我们对图片处理中,也就是将该数字乘以图像的宽、高。这样可以保持图像的本身的纵横比例不发生改变,进而保持图像的质量。因此图像在你进行拉伸或者压缩的过程中也不会显得发生了变形。

  • Python
# Scaling Up the image 1.2 times by specifying both scaling factors
scale_up_x = 1.2
scale_up_y = 1.2
# Scaling Down the image 0.6 times specifying a single scale factor.
scale_down = 0.6scaled_f_down = cv2.resize(image, None, fx= scale_down, fy= scale_down, interpolation= cv2.INTER_LINEAR)
scaled_f_up = cv2.resize(image, None, fx= scale_up_x, fy= scale_up_y, interpolation= cv2.INTER_LINEAR)
  • C++
// Scaling Up the image 1.2 times by specifying both scaling factors
double scale_up_x = 1.2;
double scale_up_y = 1.2;
// Scaling Down the image 0.6 times specifying a single scale factor.
double scale_down = 0.6;
Mat scaled_f_up, scaled_f_down;
//resize 
resize(image,scaled_f_down, Size(), scale_down, scale_down, INTER_LINEAR);
resize(image, scaled_f_up, Size(), scale_up_x, scale_up_y, INTER_LINEAR);

  在上面的Python代码片段中:

  • 我们定义了新的沿着水平和垂直方向上的比例因子;
  • 通过比例因子,省略了指明宽和高的像素个数,所以对应的dsize为 None;

  在上面的C++代码片段中:

  • 通过指明型的比例因子来改变图像数据矩阵;
  • 所以也不需要额外指明矩阵的高和宽,对应的Size()是一个空向量;

  下面通过显示结果图像可以更好地理解变换的结果。

  • Python
# Display images and press any key to check next image
cv2.imshow('Resized Down by defining scaling factor', scaled_f_down)
cv2.waitKey()
cv2.imshow('Resized Up image by defining scaling factor', scaled_f_up)
cv2.waitKey()
  • C++
// Display images and Press any key to continue check next image
imshow("Resized Down by defining scaling factor", scaled_f_down);
waitKey();
imshow("Resized Up by defining scaling factor", scaled_f_up);
waitKey();

▲ 图4.1  通过指明比例因子对图像进行拉伸和缩小的结果

▲ 图4.1 通过指明比例因子对图像进行拉伸和缩小的结果

  左边的图像是缩小的图片,右边则是拉伸的图片。

 

§05 值方法


  面讨论一下不同的插值方法用于图片的尺寸变化。

  下面给出了不同的插值方法选项所对应的变化方法。

  • INTER_AREA: INTER_AREA uses pixel area relation for resampling. This is best suited for reducing the size of an image (shrinking). When used for zooming into the image, it uses the INTER_NEAREST method.
  • INTER_CUBIC: This uses bicubic interpolation for resizing the image. While resizing and interpolating new pixels, this method acts on the 4×4 neighboring pixels of the image. It then takes the weights average of the 16 pixels to create the new interpolated pixel.
  • INTER_LINEAR: This method is somewhat similar to the INTER_CUBIC interpolation. But unlike INTER_CUBIC, this uses 2×2 neighboring pixels to get the weighted average for the interpolated pixel.
  • INTER_NEAREST: The INTER_NEAREST method uses the nearest neighbor concept for interpolation. This is one of the simplest methods, using only one neighboring pixel from the image for interpolation.

  不易担心,如果你不完全理解上述方法的函数,后面还会通过不同的博文来进行展示。

  • Python
# Scaling Down the image 0.6 times using different Interpolation Method
res_inter_nearest = cv2.resize(image, None, fx= scale_down, fy= scale_down, interpolation= cv2.INTER_NEAREST)
res_inter_linear = cv2.resize(image, None, fx= scale_down, fy= scale_down, interpolation= cv2.INTER_LINEAR)
res_inter_area = cv2.resize(image, None, fx= scale_down, fy= scale_down, interpolation= cv2.INTER_AREA)
  • C++
# Scaling Down the image 0.6 using different Interpolation Method
Mat res_inter_linear, res_inter_nearest, res_inter_area;
resize(image, res_inter_linear, Size(), scale_down, scale_down, INTER_LINEAR);
resize(image, res_inter_nearest, Size(), scale_down, scale_down, INTER_NEAREST);
resize(image, res_inter_area, Size(), scale_down, scale_down, INTER_AREA);

  上面Python代码片段中,我们使用了不同的插值方法。类似在C++ d代码中,我们首先定义了输出图片的数据矩阵,让后通过不同的插值方法进行尺度变化。

  下面让我们看看对于的图片结果有什么不同。

  • Python
# Concatenate images in horizontal axis for comparison
vertical= np.concatenate((res_inter_nearest, res_inter_linear, res_inter_area), axis = 0)
# Display the image Press any key to continue
cv2.imshow('Inter Nearest :: Inter Linear :: Inter Area', vertical)
  • C++
Mat a,b,c;
vconcat(res_inter_linear, res_inter_nearest, a);
vconcat(res_inter_area, res_inter_area, b);
vconcat(a, b, c);
// Display the image Press any key to continue
imshow("Inter Linear :: Inter Nearest :: Inter Area :: Inter Area", c);

▲ 图5.1  不同的插值方法对应的图片尺寸变化结果

▲ 图5.1 不同的插值方法对应的图片尺寸变化结果

  在上述图片结果中,左边是通过 INTER_LINEAR进行插值的; 中间是通过 INTER_NEAREST 进行插值的;右边是通过 INTER_AREA进行插值的。

  希望到现在为止你已经对于OpenCV中的 resize() 函数有所了解,我们也展示了不同的方法来改变图像的尺寸。

  下面的动图显示了执行图片尺寸变化过程,通过指明接过图片的高、宽,或者比例因子,以及不同的插值方法来获得相应的尺寸变化的结果。

▲ 图5.2  图相尺寸变化操作过程

▲ 图5.2 图相尺寸变化操作过程

 

  结 ※


  博文给你展示了如何通过指定输出结果的宽高来对图像进行尺寸变化。你也了解如何根据比例因子来保持图像的纵横比不发生变化,从而在改变图像尺寸的过程中图像不发生形变。最后也讨论了不同的插值方法如何改变尺寸变化的结果的。

6.1 图片尺寸变化网络演示程序

  现在你已经充分了解了resize 函数的功能,那么可以在web app中进行测试,看看改变图像的尺寸的实际效果。 我们开发了一个小的演示应用程序来展示 resize()DSE功能gsju uiys Streamlit。 你可以通过这个 链接 来访问这个应用程序,利用提供的图片进行操作或者上载你自己的选择的图像。

▲ 图6.1.1 图片尺寸变化网络演示程序

▲ 图6.1.1 图片尺寸变化网络演示程序


■ 相关文献链接:

  • Image Resizing with OpenCV
  • 链接

● 相关图表链接:

  • 图1.1 用于实验的图片:一辆漂亮的跑车
  • 图3.1 尺寸变化后的两个图像:左:缩小尺寸;右:拉伸尺寸
  • 图4.1 通过指明比例因子对图像进行拉伸和缩小的结果
  • 图5.1 不同的插值方法对应的图片尺寸变化结果
  • 图5.2 图相尺寸变化操作过程
  • 图6.1.1 图片尺寸变化网络演示程序

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

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

相关文章

跳跃游戏 II【贪心算法】

跳跃游戏 II class Solution {public int jump(int[] nums) {int cur 0;//当前最大覆盖路径int next 0;//下一步的最大覆盖路径int res 0;//存放结果&#xff0c;到达终点时最少的跳跃步数for (int i 0; i < nums.length; i) {//遍历数组&#xff0c;以给出数组以一个…

【JAVA】实现API 接口参数签名

使用sa-tokenSpringBoot拦截器实现API 接口参数签名 在涉及跨系统接口调用时&#xff0c;我们容易碰到以下安全问题&#xff1a; 1.请求身份被伪造。 2.请求参数被篡改。 3.请求被抓包&#xff0c;然后重放攻击。 1.引入 sa-token sa-token官方文档:https://sa-token.cc/doc.ht…

LeetCode-406-根据身高重建队列

题目描述&#xff1a; 假设有打乱顺序的一群人站成一个队列&#xff0c;数组 people 表示队列中一些人的属性&#xff08;不一定按顺序&#xff09;。每个 people[i] [hi, ki] 表示第 i 个人的身高为 hi &#xff0c;前面 正好 有 ki 个身高大于或等于 hi 的人。 请你重新构造…

【其他】小红伞Avira,扫描压缩文件

1. 命令行执行小红伞Avira扫描指定文件 命令和参数如下 "小红伞扫描软件路径" /CFG"小红伞扫描辅助scan.avp路径" /PATH"待扫描文件路径" 举例:"C:\Program Files (x86)\Avira\Antivirus\avscan.exe" /CFG"C:\Program Files…

sql语句中的ddl和dml

操作数据库&#xff1a;CRUD C&#xff08;create&#xff09; 创建 *数据库创建出来默认字符集为utf8 如果要更改字符集就 Create database 名称 character set gbk&#xff08;字符集&#xff09; *创建数据库&#xff1a;create database 名称 *先检查是否有该数据库在…

字节律动之*你太美, emm 其实是个字符画雪花视频-哈哈哈-将视频转成一张张字符画图片

效果 整体效果 局部图片放大效果 视频转换后带雪花特效,凑合看吧, 视频地址 准备工作 安装FFmpeg 电脑上安装ffpeg处理视频并设置环境变量, windows可以参考FFmpeg的安装教程这篇博客安装 mac可以直接执行brew install ffmpeg安装 安装python依赖包 执行pip3 install -…

.NET 操作 TDengine .NET ORM

TDengine 是国内比较流的时序库之一&#xff0c;支持群集并且免费&#xff0c;在.NET中资料比较少&#xff0c;这篇文章主要介绍SqlSugar ORM来操作TDengine 优点&#xff1a; 1、SqlSugar支持ADO.NET操作来实现TDengine&#xff0c;并且支持了常用的时间函数、支持联表、分…

如何注册一个免费的网站空间和域名

https://www.jianshu.com/p/016c83f70d43 前几天想搞个网站玩玩&#xff0c;于是就上网搜哪里可以注册免费的网站空间和域名&#xff0c;折腾了好几天都没注册成&#xff0c;国内好像已经没有免费的了。只好用英文去搜国外的网站&#xff0c;才找到了一个能注册成功的&#xff…

MybatisPlus 项目中使用

大家好 , 我是苏麟 , 今天带来 MybatisPlus 的简单使用 . 官方网站 : MyBatis-Plus (baomidou.com) 开始使用 初步体验 引入依赖 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version…

探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法

探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法 2011年09月18日 ⁄ 移动开发 ⁄ 评论数 38 ⁄ 被围观 8,791 前言 相信这样一个问题&#xff0c;大家都不会陌生&#xff0c; “有什么的方法可以使Android的程序APK不用安装&#xff0c;而能够直接启动”。 发现最后的…

群玩小游戏sdk一键接入

群玩提供第三方用户互动内容服务&#xff0c;拥有“你画我猜”、“谁是卧底”、“豆腐王国”、“猜歌名” 等多款互动竞猜类游戏、智能机器人接入服务&#xff0c;适合直播、社交、社群行业&#xff0c;可以自定义设计玩法&#xff0c;页面精美有趣&#xff0c;接入方便快捷&am…

职业成长面对面交流会

职业成长面对面交流会 ——微软高级主管欧琼老师讲座2009年4月12日星期日上午十点半由电子工业出版社博文视点资讯有限公司隆重举办一场“职业成长面对面交流会”&#xff0c;主讲老师是《微软360度-成功和成长》主要作者 微软总部高级主管 欧琼老师&#xff0c;精彩的讲座在开…

游戏客户端面试(Unity)

推荐阅读&#xff1a; 我的CSDN 我的博客园 QQ群&#xff1a;704621321 我的个人博客 一。最开始的两家公司笔试面试题目 一家公司是学校聘请研究教育方面VR课件的公司&#xff0c;面试没几天&#xff0c;就收到了面试通过的消息&#xff0c;后面因为通过了另一家游戏公司而拒绝…

Unity - 微信小游戏

总参考&#xff1a;Unity WebGL 微信小游戏适配方案(公测) 安装与使用 下载 Unity插件&#xff0c;并导入至游戏项目中&#xff0c;版本更新请查看更新日志 请查阅推荐引擎版本&#xff0c;安装时选择WebGL组件 最终选择Unity2021.2.5f1c1InstantGame前往Node官网安装长期稳定…

聊天群内组局互动小游戏

“找我61”互动小游戏嵌入到聊天群内&#xff0c;会给社交应用&#xff08;产品&#xff09;增加不少人气&#xff0c;带来更多活力。 新颖社区社交产品“知多视广”架构构思设想

活动预告 | 与大神面对面,移动游戏开发者必须掌握的十大技巧

上半年&#xff0c;国内游戏下载量对比2019年下半年上涨将近50%&#xff0c;在用户旺盛的需求下&#xff0c;游戏行业迎来了绝佳的发展机遇。在市场火爆的背后&#xff0c;随着用户需求的多样化、时间的碎片化&#xff0c;一些因开发繁琐、资源不足的问题频频出现&#xff0c;让…

游戏大厅 从基础开始(1)——最简单的关系,用户与房间

游戏大厅 从基础开始&#xff08;1&#xff09; ——最简单的关系&#xff0c;用户与房间。 做游戏 就好像写一篇简单的记叙文 作为小学语文大纲要求 记叙文需要完整地叙述&#xff1a; 时间&#xff0c;地点&#xff0c;人物&#xff0c;事件 也就是 WHEN &#xff0c; WH…

RK3399平台开发系列讲解(存储篇)Linux 存储系统的 I/O 栈

平台内核版本安卓版本RK3399Linux4.4Android7.1🚀返回专栏总目录 文章目录 一、Linux 存储系统全景二、Linux 存储系统的缓存沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍 Linux 存储系统的 I/O 原理。 一、Linux 存储系统全景 我们可以把 Linux 存储系…

解决MASM32代码汇编出错: error A2181: initializer must be a string or single item

最近用MASM32编程更新SysInfo&#xff0c;增加对IPv6连接信息的收集&#xff0c;使用到了 typedef struct _MIB_TCP6ROW_OWNER_MODULE {UCHAR ucLocalAddr[16];DWORD dwLocalScopeId;DWORD dwLocalPort;UCHAR ucRemoteAddr[16];DWORD …