图像缩放操作

news2024/9/25 15:25:46

图像缩放操作

微信公众号:幼儿园的学霸

在图像处理过程中,有时需要把图像调整到同样大小,便于处理,这时需要用到图像resize(),该函数比较简单,此处对函数中涉及的各种插值方法进行分析。

目录

文章目录

  • 图像缩放操作
    • 目录
    • 函数介绍
    • 插值方法分析
      • INTER_NEAREST最近邻插值
      • INTER_LINEAR | 双线性插值法(默认)
      • CV_INTER_AREA:区域插值
      • INTER_CUBIC 三次样条插值
      • INTER_LANCZOS4 Lanczos插值
    • OpenCV图像缩放代码示例

函数介绍

函数原型如下:

void resize(InputArray src, //输入图像
            OutputArray dst, //输出图像
            Size dsize, //输出图尺寸
            double fx=0, //沿x轴缩系数(宽度方向)
            double fy=0, //沿y轴缩放系(高度方)
            int interpolation=INTER_LINEAR //插值方式
            )
  • dsize表示输出图像的大小,如果为0,则输出图像大小按下式计:

d s i z = S i z e ( r o u n d ( f x ∗ s r c . c o l s ) , r o u n d ( f y ∗ s r c . r o w s ) ) dsiz = Size(round(fx*src.cols),round(fy*src.rows)) dsiz=Size(round(fxsrc.cols),round(fysrc.rows))

  • dsize和fx、fy不能同时为0。fx、fy是沿x轴和y轴的缩放系数;默认取0时,计算如下:

f x = ( d o u b l e ) d s t . c o l s s r c . c o l s − − f y = ( d o u b l e ) d s t . r o w s s r c . r o w s fx = (double)\frac{dst.cols}{src.cols} -- fy = (double)\frac{dst.rows}{src.rows} fx=(double)src.colsdst.colsfy=(double)src.rowsdst.rows

  • nterpolation:这个是指定插值的方式,图像缩放之后,肯定像素要进行重新计算的,就靠这个参数来指定重新计算像素的方式,有以下几种:

  • opencv中的5种插值方式支持的数据类型有uchar,ushort,short,float,double。

INTER_NEAREST - 最邻近插值
INTER_LINEAR - 双线性插值,如果最后一个参数你不指定,默认使用这种方法
INTER_AREA - 区域插值.
INTER_CUBIC - 4x4像素邻域内的双立方插值
INTER_LANCZOS4 - 8x8像素邻域内的Lanczos插值

下面对基本的插补策略做进一步研究,here,只讨论前两种插值方法

插值方法分析

INTER_NEAREST最近邻插值

目标图像的像素点为对应的最近的原图像的像素点已知原图像为src,目标图像为dst,那么高度和宽度的缩放比例为:
h _ r a t i o = s r c . r o w s d s t . r o w s = 1 f y , w _ r a t i o = s r c . r o w s d s t . r o w s = 1 f x h\_ratio = \frac{src.rows}{dst.rows} = \frac{1}{fy}, w\_ratio = \frac{src.rows}{dst.rows} = \frac{1}{fx} h_ratio=dst.rowssrc.rows=fy1,w_ratio=dst.rowssrc.rows=fx1

对面目标图像dst上像素:(dstX, dstX)其值等于原图像(x * w_ration, y * h_ration)处的值,由此可以得到图像和目标图像的坐标点对应关系,即:

d s t X = x ∗ w _ r a t i o = x f x , d s t Y = y ∗ h _ r a t i o = x f y dstX = x*w\_ratio = \frac{x}{fx} , dstY = y*h\_ratio = \frac{x}{fy} dstX=xw_ratio=fxx,dstY=yh_ratio=fyx
原图像和目标图像的长度和宽度是对应成比例变化的。
举个例子,假设原图像src如下:

s r c = [ 234 38 22 67 44 12 89 65 63 ] src = \left[ \begin{matrix} 234 & 38 & 22 \\ 67 & 44 & 12 \\ 89 & 65 & 63 \end{matrix} \right] src= 2346789384465221263
目标图像dst大为4x4,则fx=fy=4.0/3=1.333,目标图像(2,3)处对应原图像的坐标为(2/fx,3/fy)=(1.5,2.25).结果发现,得到的坐标里面竟然有小数,这可怎么办?计算机里的图像可是数字图像,像素就是最小单位了,像素的坐标都是整数,从来没有小数坐标。这时候采用的一种策略就是四舍五入的方法(也可以采用直接舍掉小数位的方法),把非整数坐标转换成整数,那么得到其对应原图坐标为(2,2),那么相应的其像素值为65,依次计算,可以得到放大后的图像像素矩阵如下所示:

d s t = [ 234 38 22 22 67 44 12 12 89 65 63 63 89 65 63 63 ] dst = \left[ \begin{matrix} 234 & 38 & 22 &22 \\ 67 & 44 & 12 & 12 \\ 89 & 65 & 63 & 63 \\ 89 & 65 & 63 & 63 \end{matrix} \right] dst= 234678989384465652212636322126363

这种放大图像的方法叫做最临近插值算法,这是一种最基本、最简单的图像缩放算法,效果也是最不好的,放大后的图像有很严重的马赛克,缩小后的图像有很严重的失真;效果不好的根源就是其简单的最临近插值方法引入了严重的图像失真,比如,当由目标图的坐标反推得到的源图的的坐标是一个浮点数的时候,采用了四舍五入的方法,直接采用了和这个浮点数最接近的象素的值,这种方法是很不科学的。
最临近插值算法计算量较小,但可能会造成插值生成的图像灰度上的不连续,在灰度变化的地方可能出现明显的锯齿状。

INTER_LINEAR | 双线性插值法(默认)

双线型内插值算法就是一种比较好的图像缩放算法,它充分的利用了源图中虚拟点四周的四个真实存在的像素值来共同决定目标图中的一个像素值,因此缩放效果比简单的最邻近插值要好很多。

在推得坐标值为 0.75的时候,不应该就简单的取为1,既然是0.75,比1要小0.25 ,比0要大0.75 ,那么目标象素值其实应该根据这个源图中虚拟的点四周的四个真实的点来按照一定的规律计算出来的,这样才能达到更好的缩放效果。

双线性内插值算法描述如下:
对于一个目的像素,假设坐标通过反向变换得到的浮点坐标为 ( i + u , j + v ) (i+u,j+v) (i+u,j+v)`(其中i、j均为浮点坐标的整数部分,u、v为浮点坐标的小数部分,是取值[0,1)区间的浮点数),则这个像素的值 f ( i + u , j + v ) f(i+u,j+v) f(i+u,j+v) 可由原图像中坐标为 ( i , j ) , ( i + 1 , j ) , ( i , j + 1 ) , ( i + 1 , j + 1 ) (i,j),(i+1,j),(i,j+1),(i+1,j+1) (i,j),(i+1,j),(i,j+1),(i+1,j+1)所对应的周围四个像素的值决定,即:

f ( i + u , j + v ) = ( 1 − u ) ( 1 − v ) f ( i , j ) + ( 1 − u ) v f ( i , j + 1 ) + u ( 1 − v ) f ( i + 1 , j ) + u v f ( i + 1 , j + 1 ) f(i+u,j+v) = (1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1) f(i+u,j+v)=(1u)(1v)f(i,j)+(1u)vf(i,j+1)+u(1v)f(i+1,j)+uvf(i+1,j+1)

其中f(i,j)表示源图像(i,j)处的的像素值,以此类推。

比如,像刚才的例子,现在假如目标图的象素坐标为(1,1),那么反推得到的对应于源图的坐标是(0.75 , 0.75), 这其实只是一个概念上的虚拟象素,实际在源图中并不存在这样一个象素,那么目标图的象素(1,1)的取值不能够由这个虚拟象素来决定,而只能由源图的这四个象素共同决定:(0,0)(0,1)(1,0)(1,1),而由于(0.75,0.75)离(1,1)要更近一些,那么(1,1)所起的决定作用更大一些,这从公式1中的系数uv=0.75×0.75就可以体现出来,而(0.75,0.75)离(0,0)最远,所以(0,0)所起的决定作用就要小一些,公式中系数为(1-u)(1-v)=0.25×0.25也体现出了这一特点。

双线性内插法的计算比最邻近点法复杂,计算量较大,但没有灰度不连续的缺点,结果基本令人满意。它具有低通滤波性质,使高频分量受损,图像轮廓可能会有一点模糊。

CV_INTER_AREA:区域插值

区域插值分为3种情况。图像放大时类似于线性插值,图像缩小时可以避免波纹出现。

INTER_CUBIC 三次样条插值

使用4x4邻域内的像素双3次插值,公式类似于双线性.三次曲线插值方法计算量较大,但插值后的图像效果最好

INTER_LANCZOS4 Lanczos插值

使用8×8像素邻域的Lanczos插值,公式类似于双线性

OpenCV中resize默认采用C++ Concurrency进行优化加速,你也可以采用TBB、OpenMP等进行优化加速

OpenCV图像缩放代码示例

如下代码分别展示最近邻插值和三样条插值进行图像缩放的效:

//====================================================================//
// Created by liheng on 19-3-2.
//Program:图像缩放操作
//Data:2019.3.2
//Author:liheng
//Version:V1.0
//====================================================================//

#include <opencv2/opencv.hpp>

int main()
{
    cv::Mat srcMat = (cv::Mat_<char>(3,3) <<
            234, 38, 22,
            67, 44, 12,
            89, 65, 63);

    //std::cout<<srcMat<<std::endl;
    cv::Mat dstMat;

    srcMat = cv::imread("../pictures/000177.png",cv::IMREAD_GRAYSCALE);
    cv::imshow("src",srcMat);

    cv::resize(srcMat,dstMat,cv::Size(640,480),0,0,cv::INTER_NEAREST);

    cv::cvtColor(dstMat,dstMat,cv::COLOR_GRAY2BGR);
    cv::putText(dstMat,"INTER_NEAREST",cv::Point(0,30),cv::FONT_HERSHEY_SIMPLEX,1.2,cv::Scalar(0,255,0),2);


    cv::Mat dst1 = dstMat.clone();
    cv::resize(srcMat,dstMat,cv::Size(640,480),0,0,cv::INTER_CUBIC);

    cv::cvtColor(dstMat,dstMat,cv::COLOR_GRAY2BGR);
    cv::putText(dstMat,"INTER_CUBIC",cv::Point(0,30),cv::FONT_HERSHEY_SIMPLEX,1.2,cv::Scalar(0,255,0),2);

    cv::hconcat(dst1,dstMat,dstMat);

    cv::imshow("INTER_CUBIC",dstMat);

    cv::imwrite("src.jpg",srcMat);

    cv::waitKey(0);
    
    return 0;
}

原图像:
原图像
结果图像:
结果图像

注意观察结果图像中圈出来的部分,可以明显看到三次样条插值的效果比最近邻插值效果要好。

最后在opencv中,也可以采用ocl和cuda接口的resize函数来实现图像缩放的加速。

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

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

相关文章

利用Python解析json生成PPT、xmind思维导图教程

文章目录 背景部分json样例PPT生成思维导图生成 背景 通过调用阿里通义听悟接口&#xff0c;对视频进行了语音转写、智能总结等&#xff0c;现在需要解析返回的PPT和思维导图json文件&#xff0c;以可视化的形式进行呈现。关键点在于&#xff1a; PPT生成时&#xff0c;注意用…

【电池专题】软包电池封装工序

铝塑膜成型工序冲坑 铝塑膜成型工序,软包电芯可以根据客户的需求设计成不同的尺寸,当外形尺寸设计好后,就需要开具相应的模具,使铝塑膜成型。 成型工序也叫作冲坑,顾名思义,就是用成型模具在加热的情况下,在铝塑膜上冲出一个能够装卷芯的坑,具体的见下图。 …

推荐4个一键生成 PPT的AI工具,让你畅享智能办公!

对于职场人士来说&#xff0c;ai PPT 工具已经成为了高效办公的一大得力助手 。它可以让你从繁琐的 PPT 制作中解脱出来&#xff0c;把更多的时间放在其他的工作准备上面。并且它们有极大的设计能力&#xff0c;会让我们的PPT变的设计感十足&#xff0c;如果大家正在为PPT制作烦…

【Linux】进程周边:进程概念

&#x1f337;相关专栏&#xff1a;《c学习》《Linux进阶之路》&#x1f337; 全片内容总览&#xff1a; 目录 1.进程基本概念 2.进程的本质&#xff1f;为什么要有进程控制块PCB&#xff1f; 1&#xff09;为什么要有进程控制块PCB&#xff1f; 2&#xff09;进程的本质 …

sqli-labs靶场通关攻略(41-60)

第四十一关 联合查询爆出数据库 但这关考察的时堆叠注入 &#xff0c;我们给他注入一条数据 输入id50即可查到我们注入的数据 第四十二关 看页面似曾相识&#xff0c;上次我们是用注册新用户然后对其他账户进行登录从而造成注入&#xff0c;但这次不能注册新用户了 存在堆叠注…

leetcode 1645 Hopper公司查询2(postgresql)

需求 表: Drivers -------------------- | Column Name | Type | -------------------- | driver_id | int | | join_date | date | -------------------- driver_id是该表的主键。 该表的每一行均包含驾驶员的ID以及他们加入Hopper公司的日期。 表: Rides ---------------…

【JAVA入门】Day27 - 单列集合体系结构综述

【JAVA入门】Day27 - 单列集合体系结构 文章目录 【JAVA入门】Day27 - 单列集合体系结构1.1 Collection 集合的基本方法1.2 Collection 集合的遍历方式1.2.1 迭代器遍历1.2.2 增强 for 遍历1.2.3 利用 Lambda 表达式进行遍历 1.3 List 集合的基本方法1.4 List 集合的遍历方式 J…

云手机怎样简化海外社媒平台运营

随着越来越多的卖家希望拓展海外市场&#xff0c;运营TikTok、Facebook等社交媒体平台已经成为吸引流量和促进销售的重要手段。然而&#xff0c;在管理海外社媒账号的过程中&#xff0c;许多人会面临网络连接的问题。这时&#xff0c;使用一款高效便捷的云手机工具就显得尤为便…

企业财税自动化解决方案案例分享与经验总结

数字经济时代&#xff0c;企业在财税管理方面面临着越来越多的挑战&#xff0c;作为企业运营的核心部分&#xff0c;其效率和准确性直接关系到企业的财务健康和决策效率。为全面提升财务管理工作的效率和质量&#xff0c;推动业财融合&#xff0c;许多企业开始探索&#xff0c;…

ML17_变分推断01:KL散度、ELBO

1. KL散度 KL散度&#xff08;Kullback-Leibler divergence&#xff09;&#xff0c;也称为相对熵&#xff08;relative entropy&#xff09;&#xff0c;是由Solomon Kullback和Richard Leibler在1951年引入的一种衡量两个概率分布之间差异的方法。KL散度不是一种距离度量&am…

Flutter的升级和降级步骤

升级 1.版本升级 // 升级到指定版本 flutter upgrade 版本号 // 升级到最新版本 flutter upgrade 2. 更新开发配置 启动 Android Studio。 打开 Settings 对话框&#xff0c;查看 SDK Manager。 如果你已经打开了一个项目&#xff0c;请打开 Tools > SDK Manager。 如果…

设置Virtualbox虚拟机共享文件夹

由于工作环境的原因&#xff0c;选择Virtualbox的方式安装虚拟操作系统&#xff0c;常用的操作系统为ubuntu&#xff0c;不知道道友是否也曾遇到这样的问题&#xff0c;就是虚拟机和主机进行文件拖拽的时候&#xff0c;会因为手抖造成拖拽失败&#xff0c;虚拟机界面显示大个的…

CCSI: 用于无数据类别增量学习的持续类别特定印象|文献速递--基于深度学习的医学影像病灶分割

Title 题目 CCSI: Continual Class-Specific Impression for data-free class incremental learning CCSI: 用于无数据类别增量学习的持续类别特定印象 01 文献速递介绍 当前用于医学图像分类任务的深度学习模型表现出了令人鼓舞的性能。然而&#xff0c;这些模型大多要求…

python 怎样计算字符串的长度

python 计算字符串长度&#xff0c;一个中文算两个字符&#xff0c;先转换成utf8&#xff0c;然后通过计算utf8的长度和len函数取得的长度&#xff0c;进行对比即可知道字符串内中文字符的数量&#xff0c;自然就可以计算出字符串的长度了。 valueu脚本12 length len(value) u…

电车买不了保险?就该车企负责

文 | AUTO芯球 作者 | 雷慢 买电车的真是太糟心了&#xff0c; 来看这个车主&#xff0c;去年保费4200&#xff0c;今年保险公司拒保了&#xff0c; 车主说要投诉&#xff0c;保险公司就扔过来一张1万5的报价单。 你不是要保险吗&#xff0c;买吧&#xff01; 我告诉你们&…

安装破解激活pycharm

装pycharm之前先装python 激活方式版本不能过新&#xff0c;要22年1月及其之前的版本&#xff0c;下拉找到对应版本的专业版 Other Versions - PyCharmGet past releases and previous versions of PyCharm.https://www.jetbrains.com/pycharm/download/other.html 2.下载电脑…

【支付】PayPal支付通道 Java对接 (下单 付款 确认 退款 查询 回调)

使用Java 对接 PayPal 接口&#xff0c;从下单&#xff0c;支付&#xff0c;确认订单、查询、退款、退款查询、回调处理等全流程代码示例&#xff0c;以及图文说明。 PayPal接口调用时序图 #mermaid-svg-WARCfGOa6JcsCAch {font-family:"trebuchet ms",verdana,aria…

深度学习的发展历程

深度学习的起源 在机器学习中&#xff0c;我们经常使用两种方式来表示特征&#xff1a;局部表示&#xff08;Local Representation&#xff09;和分布式表示&#xff08;Distributed Representation&#xff09;。以颜色表示为例&#xff0c;见下图&#xff1a; 要学习到一种好…

探索NVIDIA RTX 4060 8G与RTX 3060 12G:性能与适用场景的深度解析

在考虑NVIDIA RTX 4060 8G和RTX 3060 12G两种配置时&#xff0c;我们需要根据具体的应用场景来做出选择。RTX 4060 8G显卡以其较快的处理速度而著称&#xff0c;适合需要快速响应的任务&#xff0c;如实时渲染、视频编辑和部分机器学习任务。而RTX 3060 12G显卡则因其较大的显存…

依托自研力量,给共享集群存储服务一个优选

YashanDB共享集群有三大关键组件&#xff0c;崖山集群服务&#xff08;YCS&#xff09;、崖山集群文件系统&#xff08;YFS&#xff09;、DB组件。上一篇共享集群系列文章《为何共享集群的高可用能力被频频称赞&#xff0c;它的机制有何不同&#xff1f;》深入解析了关键组件的…