利用GPU实现IDW(反距离加权插值)

IDW的实现比较简单,已知插值点位比较少的情况下,可以直接遍历所有插值点,来获取临近的几个点,进行插值运算。插值点较多时,需要可以使用kd-tree来加速临近点的查找。本次仅对小数据量情况进行讨论,将IDW算法在shader中实现,可以方便的使用webgl的裁剪面和强大的并行计算。具体计算流程如下:

插值点位提交到GPU

数据提交,我使用了uniform数组变量来存储,在渲染过程中,直接提交插值点位的数据,数据类型为vec3,webgl我使用了twgl第三方库(为了偷懒), twgl可以减少编写原生webgl代码量。测试用的数据直接使用Math.random()生成。

//points为math.random生成的测试数据
const uniforms = {points: points
};
twgl.setUniforms(programInfo, uniforms);

需要注意,shader中声明的数据类型为vec3,使用x,y,z依次来存储位置,观测值。生成测试数据时,如果需要模拟300个点位,则需要生成的数组长度为300*3。即提交到uniform中的变量为:定点数的三倍。

Shader中实现IDW算法

IDW算法的生成需要用到,屏幕的像素坐标,所以应选用Fragment Shader,实现思路比较简单,插值点位的数据传入后,通过计算最近的两个点位的距离,来计算,该像素位置的观测值。webgl中内置的gl_FragCoord,可以方便的获取屏幕像素坐标。shader中的代码如下:

#version 300 es
precision mediump float;
uniform vec3 points[300];//存储最近的点的索引,和距离
struct interpoPoint {int idx;float dist;
};interpoPoint queues[2];out vec4 outcolor;//更新队列,
void updatequeue(int idx,float dist){if(dist<queues[0].dist){queues[1]=queues[0];queues[0].idx=idx;queues[0].dist=dist;}else if(dist<queues[1].dist){queues[1].idx=idx;queues[1].dist=dist;}
}float getCoorddist(vec2 coord,vec2 point){float dertx=coord.x-point.x;float derty=coord.y-point.y;return dertx*dertx+derty*derty;
}float getCoordColor(vec2 coord){//前两个点位的距离更新到queuesfloat dist0=getCoorddist(coord,points[0].xy);float dist1=getCoorddist(coord,points[1].xy);if(dist0<dist1){queues[0].idx=0;queues[0].dist=dist0;queues[1].idx=1;queues[1].dist=dist1;}else{queues[0].idx=1;queues[0].dist=dist1;queues[1].idx=0;queues[1].dist=dist0;}for(int i=2;i<300;i++){float dist=getCoorddist(coord,points[i].xy);updatequeue(i,dist);}//idwfloat denominator=(1.0/queues[0].dist)+(1.0/queues[1].dist);float numerator1=points[queues[0].idx].z*(1.0/queues[0].dist)/denominator;float numerator2=points[queues[1].idx].z*(1.0/queues[1].dist)/denominator;return numerator1+numerator2;
}void main(){float color=getCoordColor(gl_FragCoord.xy);outcolor=vec4(vec3(color),1.0);
}

效果图

效果图有些奇怪,边界特别明显,我用的指数为2,最近的点位个数为2,印象里应该是比较平滑才对,这里理论知识需要在复习一下。

现有问题

  • 最大的问题是,插值点位过多时,受限于uniform数据的个数限制,大量数据无法存放到shader的数组中

    • 可以使用生成texture的方法,来存放插值点的数据,同样的存在大量点位中查找最近的k个临近点的效率问题,暂时考虑使用kdtree来实现快速查找,但是需要在shader中实现对kdtree树的查找,这个断断续续看了两个月了,还没有实现,有大神一起做的话,欢迎讨论
  • idw的指数,固定为2,想要直接使用的小伙伴,可以自行修改

  • idw中,临近点的个数,shader中固定为2,这里需要实现一个有序的队列,来实现大于2的点位查找。

PS: 代码已提交,github地址,有在做相关内容的小伙伴,欢迎一起讨论

GPU中实现反距离加权插值(IDW)相关推荐

  1. 离散点插值反距离加权法IDW C#实现

    看了很多插值方法,总体来看写的都太复杂,简单应用的时候效率提不上去,数学不太好,只能套公式 1.反距离权重 (IDW) 插值介绍 反距离权重 (IDW) 插值是一种常用而简便的空间插值方法,它以插值点 ...

  2. 反距离加权法IDW C#实现

    public class PointXYZ{public double X;public double Y;public double Z;}public class Interpolation{// ...

  3. 反距离加权法高程_GIS中的反距离加权法插值算法

    在GIS的应用中,很多都是离散的数据,通常情况下我们需要根据离散的数据来评估整体的数据分布情况,这时候往往我们需要用到一些插值算法,例如克里金插值法,线性插值三 角网法以及本文中介绍的反距离加权法插值 ...

  4. python实现反距离权重插值(IDW)

    原文:https://mp.weixin.qq.com/s/2y13vGtqj55Fae-72YXY6g 1 什么叫反距离权重插值? 反距离权重:距离未知点最近的点分配的权重较大,且权重作为距离的函数 ...

  5. 反距离加权matlab算法,ImageWarping变形算法研究---反距离加权插值(IDW)

    参考论文:Image Warping with Scattered Data Interpolation Inverse distance weighted interpolation算法(IDW)实 ...

  6. ImageWarping变形算法研究---反距离加权插值(IDW)

    参考论文:Image Warping with Scattered Data Interpolation Inverse distance weighted interpolation算法(IDW)实 ...

  7. Python中ArcPy实现Excel时序数据读取、反距离加权IDW插值与批量掩膜

    1 任务需求   首先,我们来明确一下本文所需实现的需求.   现有一个记录有北京市部分PM2.5浓度监测站点在2019年05月18日00时至23时(其中不含19时)等23个逐小时PM2.5浓度数据的 ...

  8. ImageWarping--反距离加权插值(IDW)方法实现及报告

    反距离加权插值(IDW) 根据给定的控制点对和控制点的位移矢量(方向和距离),实现图像每一个像素点的位移.反距离加权插值的方法是通过得到每一个像素点和选定控制点对的逼近关系,以及相对应的权重关系,求得 ...

  9. 基于MATLAB的全局多项式插值法(趋势面法)与逆距离加权(IDW)法插值与结果分析

    基于MATLAB的全局多项式插值法(趋势面法)与逆距离加权(IDW)法插值与结果分析 1 背景知识 2 实际操作部分 2.1 空间数据读取 2.2 异常数据剔除 2.3 验证集筛选 2.4 最小二乘法 ...

最新文章

  1. Buffer和Cache的区别
  2. Dev c++工具将C代码生成dll文件以及如何调用dll文件
  3. jquery 表单重置通用方法
  4. 安卓手机状态栏 定位服务自动关闭_【科普知识】手机多久关机一次?看完才知道白用那么多年手机了!...
  5. IntelliJ IDEA最新版官方支持汉化
  6. 俺的web课设大作业
  7. 机器人庄园作文_赛尔号作文
  8. PHP 微信公众号发送红包
  9. 手机账本软件哪些可以实现随手记录
  10. 欧姆龙 PLC 程序NJ ST语言EtherCat总线控制24个伺服轴大型程序电池生产线 包括PLC NJ-1400和威纶通触摸屏程序
  11. win10安装docker,启动后提示WSL 2 installation is incomplete.
  12. android TV 焦点选中放大效果
  13. 大数据权限管理组件Apache Ranger简介和原理
  14. Cache与Scratch-pad-memory(spm)的区别
  15. 无法安装64位office,因为已有32位版本的完美解决方法
  16. 超简单的通用Mapper快速入门
  17. K-近邻算法介绍与代码实现
  18. 计算与数据结构篇 - 哈希算法 (Hash)
  19. 鸿蒙支持哪10款机型,鸿蒙2.0支持哪些手机 鸿蒙2.0支持机型列表大全
  20. 2020年电力电缆新版试题及电力电缆模拟试题

热门文章

  1. Linux-4.20.8内核桥收包源码解析(一)----------sk_buff(详细)
  2. error: cannot lock ref ‘refs/remotes/origin/douyin/open‘: ‘refs/remotes/origin/douyin‘ exists;
  3. php 模拟百度蜘蛛
  4. Eclipse 提示内存不足
  5. reactos操作系统实现(39)
  6. 什么是入侵检测系统?有哪些分类?
  7. C# WPF 快捷键的实现 极简教程
  8. 图像的模式(RGB和CMYK)、通道(8位、16位、32位)分别有什么作用
  9. 关于linux中socket阻塞与非阻塞
  10. IE hasLayout详解