0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

三种图像插值方式对比

新机器视觉 来源:简书-梧桐光影 2023-06-01 17:16 次阅读

在播放视频时,常遇到视频尺寸与画布尺寸不一致的情况。为了让视频按比例填充画布,需要对视频中的每一帧图像做缩放处理。

缩放就是在原图的基础上做插值计算,从而增加或减少像素点的数量。常见的插值方式有最近点插值,线性插值,兰索斯插值

下面简要介绍,并对比三种插值方式的结果。

最近点插值

在一维空间中,最近点插值就相当于四舍五入取整。在二维图像中,像素点的坐标都是整数,该方法就是选取离目标点最近的点。计算方式如下:

假设原图为A[aw,ah],宽度为aw,高度为ah。目标图为B[bw,bh],宽度为bw,高度为bh。已知A[aw,ah]的宽度,高度及其中每个点的颜色值,B[bw,bh]中每个点像素值的计算方式如下:

for(int i=0; i

最近点插值

线性插值

线性插值是以距离为权重的一种插值方式。在一维空间中,假设有点A,B,其距离为LAB。A,B之间任意一点C的值为A*LBC/LAB+B*LAC/LAB。在二维空间中,需要在两个方向上做插值。如下图所示:

6483caf8-eca5-11ed-90ce-dac502259ad0.jpg

线性插值

已知Q11,Q21,Q12,Q22,计算P点的值时,需要先由Q11和Q21插值得到R1,由Q12和Q22插值得到R2,再由R1和R2插值得到P。

该方法生成的图像比较平滑。

线性插值

兰索斯插值(lanczos)

一维的线性插值,是在目标点的左边和右边各取一个点做插值,这两个点的权重是由线性函数计算得到。而一维的兰索斯插值是在目标点的左边和右边各取四个点做插值,这八个点的权重是由高阶函数计算得到

二维的兰索斯插值在x,y方向分别对相邻的八个点进行插值,也就是计算加权和,所以它是一个8x8的描述子。

网上目前可找到兰索斯算法有两份:GPUImage和OpenCV。其中GPUImage中是用GLSL实现,其算法有误,并不能得到正确的结果。OpenCV中是用C++实现的CPU端代码。


我参考OpenCV中的实现方式,实现了一份GPU上的兰索斯插值算法,该算法在GPU上运行,并不额外消耗CPU资源。其对应的GLSL为

uniform int ssize;
uniform int tsize;
uniform int flag;
uniform float scale;
uniform sampler2D inputImageTexture;
void interpolateLanczos4(in float fx, inout float rate[8]) {
    const float s45 = 0.70710678118654752440084436210485;
    const float PI = 3.1415926535897932384626433832795;
    float cs[] = float[16]( ,1.0, 0.0, -s45, -s45, 0.0, 1.0, s45, -s45, -1.0, 0.0, s45, s45, 0.0, -1.0, -s45, s45);
    if( fx < 0.0000000001 ) {
        for( int i = 0; i < 8; i++ ) {
            rate[i] = 0.0;
        }
        rate[3] = 1.0;
        return;
    }
    float sum = 0.0;
    float y0 = -(fx+3.0)*PI*0.25;
    float s0 = sin(y0);
    float c0 = cos(y0);
    for(int i = 0; i < 8; i++ ) {
        float y = -(fx+float(3-i))*PI*0.25;
        int index = i*2;
        rate[i] = (cs[index]*s0 + cs[index+1]*c0) g (y*y);
        sum += rate[i];
    }
    sum = 1.0gsum;
    for(int i = 0; i < 8; i++ ) {
        rate[i] *= sum;
    }
}
void main() {
    vec4 fragmentColor = vec4(0);
    float curPos = float(tsize);
    if( flag == 0 ) {
        curPos = fragTexCoord.x * float(tsize);
    } else {
        curPos = fragTexCoord.y * float(tsize);
    }
    float fx = (curPos + 0.5) * scale - 0.5;
    float sx = floor(fx);
    fx -= sx;
    float rate[8];
    interpolateLanczos4(fx, rate);
    for (int i=0; i<8; ++i) {
        float newCoord = (sx + float(i - 3) ) / float(ssize);
        vec2 texCoord;
        if (flag == 0)
            texCoord = vec2(newCoord, fragTexCoord.y);
        else
            texCoord = vec2(fragTexCoord.x, newCoord);
        fragmentColor += texture2D(inputImageTexture, texCoord) * rate[i];
    }
    gl_FragColor = fragmentColor;
}

上述代码需要执行两遍:

第一遍的输入为原图,缩放宽度方向。ssize为原图宽度,tsize为目标图宽度。执行完毕后,把结果存到纹理中,作为第二遍的输入;

第二遍缩放高度方向,ssize为原图高度,tsize为目标图高度。执行完毕后,把结果显示到屏幕上。

结果对比

将上面的对比图放大后可以发现,线性插值的结果较最近点插值更平滑,兰索斯插值的结果较线性插值更清晰。

性能对比

运行环境:iphone5s,ios8.3

运行程序:自研播放器demo

以上三种插值算法渲染每帧图像时,占用CPU时间都是40ms左右。由于这三种算法都是在GPU上实现,其对应的CPU代码相同,结果与预期相符。

占用GPU时间如下所示:

插值方式 最近点插值 线性插值 兰索斯插值
每帧图像平均占用的GPU时间(ms) 6 6 12

兰索斯插值算法占用GPU的平均时间为12ms,是其它两种算法的两倍,由于该算法中shader代码执行了两遍,结果也与预期相符。

由于GPU与CPU是异步执行,大部分视频帧率不超过30,因此GPU上多出的6ms不会造成性能瓶颈。

注:GPUImage中的兰索斯插值实现有误,本文是参考OpenCV实现的。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 视频
    +关注

    关注

    6

    文章

    1942

    浏览量

    72884
  • gpu
    gpu
    +关注

    关注

    28

    文章

    4729

    浏览量

    128890
  • 图像
    +关注

    关注

    2

    文章

    1083

    浏览量

    40449
  • 线性插值
    +关注

    关注

    0

    文章

    6

    浏览量

    6675
  • 二维空间
    +关注

    关注

    0

    文章

    2

    浏览量

    1590

原文标题:三种图像插值方式对比

文章出处:【微信号:vision263com,微信公众号:新机器视觉】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    伺服电机的三种控制方式

    伺服电机控制方式有脉冲、模拟量和通讯这三种,在不同的应用场景下,我们该如何选择伺服电机的控制方式呢?
    发表于 08-17 11:01 7097次阅读

    步进电机的三种驱动方式

    步进电机的三种驱动方式
    发表于 01-12 17:03

    三种基本放大电路对比

    三种基本放大电路对比1.输入阻抗、输出阻抗从几十欧姆到几百千欧姆,这个是由什么造成的?如何根据输入、输出阻抗进行应用场合的选型?2.电压放大倍数、电流放大倍数都不一样。共射是既有电压放大能力也有电流
    发表于 09-09 16:14

    基于B样条图像边缘检测实现

    为了能高速、高质量地进行图像边缘检测,提出了一新的基于B 样条的边缘检测方法。该方法采用了次B 样条
    发表于 05-14 15:27 40次下载
    基于B样条<b class='flag-5'>插</b><b class='flag-5'>值</b>的<b class='flag-5'>图像</b>边缘检测实现

    图像处理中的和缩放研究

    本文围绕图像处理领域中两类重要处理手法――图像图像缩放技术展开了深入的研究.在分析目前现有的
    发表于 09-28 14:00 38次下载
    <b class='flag-5'>图像</b>处理中的<b class='flag-5'>插</b><b class='flag-5'>值</b>和缩放研究

    改进的线性图像算法

    针对传统的双线性插值法在对图像进行后会不可避免的产生边缘模糊的问题,提出了一改进的线性插值
    发表于 08-20 12:01 29次下载

    局部多项式的方法对图像进行

    本文运用局部多项式的方法对图像进行。文中我们从一幅高分辨率图像通过下采样得到一张低分辨率图像,然后对其进行
    发表于 12-20 10:02 1次下载

    实时图像算法

    针对现有彩色图像算法的实时性及可靠性不能兼备的问题,提出了一高效的实时彩色图像缩放算法,算法基于Lanczos核生成可应用于整个目标
    发表于 01-17 11:48 0次下载
    实时<b class='flag-5'>图像</b><b class='flag-5'>插</b><b class='flag-5'>值</b>算法

    伺服电机的三种控制方式该如何应用

    一般伺服都有三种控制方式:速度控制方式,转矩控制方式,位置控制方式。大多数人想知道的就是这三种
    的头像 发表于 12-14 23:12 5350次阅读

    如何应用伺服电机的三种控制方式

    一般伺服都有三种控制方式:速度控制方式,转矩控制方式,位置控制方式。大多数人想知道的就是这三种
    发表于 01-22 06:30 7次下载
    如何应用伺服电机的<b class='flag-5'>三种</b>控制<b class='flag-5'>方式</b>

    视频图像方式的结果

    方式有 最近点,线性插值,兰索斯 。   下面简要介绍,并
    的头像 发表于 11-09 15:39 1865次阅读

    Redis实现限流的三种方式分享

    当然,限流有许多种实现的方式,Redis具有很强大的功能,我用Redis实践了三种的实现方式,可以较为简单的实现其方式
    的头像 发表于 02-22 09:52 1073次阅读

    三种近场通信技术技术对比

    Android开发——近场通信技术特点分析及对比三种近场通信技术特点 NFC 主要技术特点 Blue Tooth 主要技术特点 WIFI 主要技术特点 三种技术对比
    发表于 05-19 17:44 0次下载
    <b class='flag-5'>三种</b>近场通信技术技术<b class='flag-5'>对比</b>

    什么是电池化成?电池化成的三种方式 三种电池化成对比

    什么是电池化成?电池化成的三种方式 三种电池化成对比  电池化成是指将物体或设备改造为可以使用电池供电的过程。在电池化成过程中,常见的电源例如燃油、电线甚至是替换掉,以便更高效、便捷地
    的头像 发表于 11-10 14:49 2316次阅读

    图像理论研究之双三次插值

    三次插值又叫双立方,用于在图像中“”(Interpolating)或增加“像素”(Pi
    的头像 发表于 12-14 14:35 1139次阅读
    <b class='flag-5'>图像</b><b class='flag-5'>插</b><b class='flag-5'>值</b>理论研究之双<b class='flag-5'>三次插值</b>