双线性插值计算手动实现以及原理

news2024/12/26 0:07:14

双线性插值计算手动实现以及原理

  • 代码
  • 原理

代码

先贴代码吧,原理其实也比较简单,看代码基本也就理解了,时间太晚了,原理后续再补吧。

import torch
from torch.nn import functional as F
import numpy as np
from itertools import product
import warnings
warnings.filterwarnings('ignore')
def data_gen(in_wh,out_wh):
    in_w,in_h = in_wh
    out_w,out_h = out_wh
    inp = torch.range(0,in_h*in_w-1,1).reshape(1,1,in_h, in_w)
    new_h = torch.linspace(-1, 1, out_h).view(-1, 1).repeat(1, out_w)
    new_w = torch.linspace(-1, 1, out_w).repeat(out_h, 1)
    grid = torch.cat((new_w.unsqueeze(2), new_h.unsqueeze(2)), dim=2)#+2/5
    # print(grid.shape)
    grid = grid.unsqueeze(0).clip(-1,1)
    return inp,grid
def torch_interp(in_wh,out_wh):
    '''torch 插值'''
    inp,grid = data_gen(in_wh,out_wh)
    print(inp)
    outp = F.grid_sample(inp, grid=grid, align_corners=True)
    # print(outp)
    return outp
def my_interp(in_wh,out_wh):
	'''手动实现的插值计算'''
    inp,grid = data_gen(in_wh,out_wh)
    in_w,in_h = in_wh
    p_h = 2/(in_h-1)#计算h方向上每一份的长度
    p_w = 2/(in_w-1)#计算w方向上每一份的长度
    p_ = np.array([p_w,p_h])#合并
    inp = inp[0,0,:,:]
    grid = grid[0]
    out = np.zeros((grid.shape[0],grid.shape[1]))#初始化输出模板
    for (_i,_j) in product(range(grid.shape[0]),range(grid.shape[1])):
        maps = (grid[_i,_j]).cpu().numpy()
        interp_start = (maps+1)//p_#计算插值的起始点
        offset = (maps+1)%p_#计算距离起始点的偏移量
        interp_start = interp_start.astype(np.int32)
        # print(interp_start)
        w, pix = [], []
        for j,i in [(0,0),(0,1),(1,0),(1,1)]:
            w.append(abs((i*p_[0]-offset[0])*(p_[1]*j-offset[1]))/(p_[0]*p_[1]))#双线性插值的面积计算
            interp_start_ = interp_start+np.array([i,j])#计算插值的四个点中的某一个
            interp_start_[0]=interp_start_[0].clip(0,in_w-1)#控制不超出原图像边界
            interp_start_[1]=interp_start_[1].clip(0,in_h-1)
            pix.append(inp[interp_start_[1]][interp_start_[0]])
        w = np.array(w)
        pix = np.array(pix[::-1])
        interp_val = round((w*pix).sum(),3)
        out[_i,_j]=interp_val
    return out
#原始输入
in_wh = 9, 9
#目标输出
out_wh =5, 2
a = torch_interp(in_wh,out_wh)
b = my_interp(in_wh,out_wh)
print(a,b)

结果:

tensor([[[[ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.],
          [ 9., 10., 11., 12., 13., 14., 15., 16., 17.],
          [18., 19., 20., 21., 22., 23., 24., 25., 26.],
          [27., 28., 29., 30., 31., 32., 33., 34., 35.],
          [36., 37., 38., 39., 40., 41., 42., 43., 44.],
          [45., 46., 47., 48., 49., 50., 51., 52., 53.],
          [54., 55., 56., 57., 58., 59., 60., 61., 62.],
          [63., 64., 65., 66., 67., 68., 69., 70., 71.],
          [72., 73., 74., 75., 76., 77., 78., 79., 80.]]]])
(tensor([[[[ 0.,  2.,  4.,  6.,  8.],
           [72., 74., 76., 78., 80.]]]]),
 array([[ 0.,  2.,  4.,  6.,  8.],
        [72., 74., 76., 78., 80.]]))

自己试了几组数据,结果均与torch一致。
在这里插入图片描述

原理

先简要说一下原理吧
在线性插值的情况下:
在这里插入图片描述

假设AB=AD/2,那么B的坐标等于(1-0.5)×A+0.5×D= 3.5
那么C点坐标等于(1-0.6)×A+0.6×D=3.8
那么在双线性插值的情况下,
增加了一个维度
在这里插入图片描述

E的像素值等于e = (D×a+B×c+A×d+C×b)/(A+B+C+D)
其中ABCD表示对应区域的面积

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

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

相关文章

苍穹外卖开发笔记(6.缓存商品,购物车)

目录 一、缓存商品2、缓存菜品(redis)1.问题说明2.实现思路3.代码开发 2、缓存套餐(spring cache)1.实现思路2.代码实现 3、测试 二、购物车功能1、添加购物车1.需求分析设计2.代码开发3.测试 2、查看购物车1.需求分析设计2.代码开…

基于TSM模块的打架斗殴识别技术

目 录 1 引言.... 4 1.1 研究背景与意义.... 4 1.2 研究现状综述.... 5 1.3 研究内容.... 6 1.3.1 图像预处理的优化.... 6 1.3.2 TSM模块的应用.... 6 1.3.3 视频分类的设计与实现.... 6 2 关键技术与方法.... 8 2.1 TSM算法与模型选择.... 8 2.1.1 TSM算法原理.... 8 2.1.2 …

用python做傅里叶变换和系统辨识

一、原始信号 1、理想数据 (1)系统参数 参数类型数值J0.5 k g ∗ m 2 kg*m^2 kg∗m2K0.2b5 (2)激励曲线 import matplotlib.pyplot as plt import numpy as np# 生成数据 x np.linspace(0, 10, 1000) # 生成0到10之间的100…

下列程序定义了NxN的二维数组,并在主函数中自动赋值。请编写函数fun(int a[][N],int n),该函数的功能是:使数组右上半三角元素中的值乘以m。

本文收录于专栏:算法之翼 https://blog.csdn.net/weixin_52908342/category_10943144.html 订阅后本专栏全部文章可见。 本文含有题目的题干、解题思路、解题思路、解题代码、代码解析。本文分别包含C语言、C++、Java、Python四种语言的解法完整代码和详细的解析。 题干 下列…

从0到1:社区论坛小程序开发笔记

背景 论坛小程序:为用户提供了一个社交互动的平台,使用户可以分享经验、交流观点、解决问题,促进社区成员之间的互动和交流。 用户可以在论坛小程序上发布有关各种话题的帖子,分享自己的知识、经验和见解,帮助其他用户…

mysql基础14——视图

视图 视图是一种虚拟表 可以把一段查询语句作为视图存储在数据库中 需要的时候把视图看作一个表,对里面的数据进行查询 视图并没有真正存储数据 避免了数据存储过程中可能产生的冗余 提高了存储的效率 子查询 嵌套在另一个查询中的查询 派生表 如果在查询中…

【MySQL 数据宝典】【内存结构】- 003 Change Buffer 详解

一、 Change Buffer基本概念 Change Buffer:写缓冲区,是针对二级索引(辅助索引) 页的更新优化措施。 作用: 在进行DML操作时,如果请求的是 辅助索引(非唯一键索引)没有在缓冲池 中时,并不会立刻将磁盘页加载到缓冲池…

游戏AI智能体模仿学习技术方案揭秘(二)(附方案详情),沉浸式玩家体验秘诀,看《梦三国2》游戏AI智能体!

接上篇内容,小智发现内容非常受游戏开发者们的欢迎,今天给大家带来方案(二)内容,没看过第一篇的伙伴可以戳以下链接查看~~码住! 游戏AI智能体模仿学习技术方案(附方案详情),沉浸式玩…

AQS(AbstractQueuedSynchronizer)队列同步器源码解读

🏷️个人主页:牵着猫散步的鼠鼠 🏷️系列专栏:Java全栈-专栏 🏷️个人学习笔记,若有缺误,欢迎评论区指正 目录 1. 前言 2. AOS、AQS、AQLS的区别 3. AQS的底层原理 3.1. 核心思想 3.2. 数…

PyQt介绍——动画使用详解之QPropertyAnimation

一、继承关系 PyQt5的动画框架是QAbstractAnimation,它是一个抽象类,不能直接使用,需要使用它的子类。它的类结构如下: QAbstractAnimation:抽象动画,是所有动画的基类,不能直接使用。 QVariant…

基于postCSS手写postcss-px-to-vewiport插件实现移动端适配

🌟前言 目前前端实现移动端适配方案千千万,眼花缭乱各有有缺,但目前来说postcss-px-to-vewiport是一种非常合适的实现方案,postcss-px-to-vewiport是一个基于postCss开发的插件,其原理就是将项目中的px单位转换为vw(视…

【极速前进】20240422:预训练RHO-1、合成数据CodecLM、网页到HTML数据集、MLLM消融实验MM1、Branch-Train-Mix

一、RHO-1:不是所有的token都是必须的 论文地址:https://arxiv.org/pdf/2404.07965.pdf 1. 不是所有token均相等:token损失值的训练动态。 ​ 使用来自OpenWebMath的15B token来持续预训练Tinyllama-1B,每1B token保存一个che…

配置nodejs的俩小脚本

介绍:共两个脚本。 脚本1,用来配置环境变量,生成环境变量所需的配置信息,然后自己添加到系统环境变量里去 特别注意:该脚本需要放到nodejs目录下面,如果不是,则无法生成环境变量配置文本内容 另…

【STL概念】

STL STL(Standard Template Library),即标准模板库从根本上说,STL是一些“容器”的集合,这些“容器”有list,vector,set,map等,STL也是算法和其他一些组件的集合。这里的“容器”和算法的集合指的是世界上很多聪明人很多年的杰作。STL的目的是标准化组件&#xff0…

找不到msvcp140dll,无法继续执行代码的详细解决方法

在我们日常使用计算机进行各类工作任务的过程中,时常会遭遇一些突发的技术问题。比如,有时在运行某个重要程序或应用软件时,系统会突然弹出一个令人困扰的错误提示:“电脑提示找不到msvcp140.dll文件,因此无法继续执行…

Linux CPU 占用率 100% 排查

其他层面要考虑到的地方 mysql,有执行时间特别长的sql、死锁redis雪崩等相关问题并发导出数据量大Java定时器服务业务复杂,比如像每天要更新电商的统计表,每天发送优惠券等业务需要提前计算才能保证业务使用时的流畅性,我这个原因…

【快速上手ESP32(基于ESP-IDFVSCode)】09-Flash存储

ESP32中的Flash 关于ESP32中的Flash,我们需要再回顾一下命名规则。 我用的是立创开发板设计的板子,芯片型号是ESP32S3R8N8,因此可以知道我这块板子有8MB的Flash,大家可以参照着命名规则看看自己有多大的Flash容量。 操作Flash …

学习STM32第十七天

备份域详解 一、简介 在参考手册的电源控制章节,提到了备份域,BKPR是在RTC外设中用到,包含20个备份数据寄存器(80字节),备份域包括4KB的备份SRAM,以32位、16位或8位模式寻址,在VBAT…

0.什么是C++(专栏前言)

目录 1.什么是C 2.C的发展史 3.C的重要性 应用: 4.如何学习C 5.关于本专栏 1.什么是C 20世纪80年代,计算机界提出oop(object oriented programming:面向对象)思想,支持面向对象的程序设计应运而生。 1982年,本…

去雾笔记-知识蒸馏

知识蒸馏(Knowledge distillation)是一种模型压缩技术,旨在将一个复杂的模型(通常称为“教师模型”)的知识转移给一个较简单的模型(通常称为“学生模型”),以降低模型的计算复杂度和…