双三次插值算法的OpenGL实现

说明

最近写一个图像缩放的接口,考虑到自己有现成的OpenGL图像处理引擎,还是直接写shader用GPU实现方便。为了效果好一些,采用了双三次插值算法。
算法相关公式可参考这篇文章:
http://blog.csdn.net/lichengyu/article/details/8526629

代码

详细实现代码见:
https://github.com/jxt1234/Simple3D/blob/master/src/GL/GLBicubicWork.cpp
测试代码见:
https://github.com/jxt1234/Simple3D/blob/master/gltest/GLBitmapWorkTest.cpp

要集成到其他项目中,只需要 vertex shader 和 fragment shader 两部分的代码,毕竟不同的图像引擎在如何加载shader,如何传参数,如何上传纹理的逻辑都是不同的。

bicubic.vex

attribute vec4 pos;
attribute vec2 tex;
varying vec2 vTex;
void main(void)
{gl_Position = pos;vTex = tex;
}

生成的 fragment shader:
bicubic.fra

#ifdef GL_ES
precision mediump float;//用于手机上时需要添加此句
#endif
varying vec2 vTex;//纹理坐标,注意与 vertex shader 中的变量对应
uniform sampler2D buffer;
uniform float uUnit;//传入原图的宽
uniform float vUnit;//传入原图的高float BiCubicPoly1(float x, float a)
{x = abs(x);float res = (a+float(2))*x*x*x - (a+float(3))*x*x + float(1);return res;
}
float BiCubicPoly2(float x, float a)
{x = abs(x);float res = a*x*x*x - float(5)*a*x*x + float(8)*a*x - float(4)*a;return res;
}
void main()
{
vec2 basic;
vec2 det;
basic = vTex*vec2(uUnit, vUnit) - vec2(0.5,0.5);
det = fract(basic);
gl_FragColor = vec4(0.0,0.0,0.0,0.0)
+BiCubicPoly2(det.x-float(-1), float(-0.5))*BiCubicPoly2(det.y-float(-1), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(-1), float(-1)))/vec2(uUnit, vUnit))
+BiCubicPoly2(det.x-float(-1), float(-0.5))*BiCubicPoly1(det.y-float(0), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(-1), float(0)))/vec2(uUnit, vUnit))
+BiCubicPoly2(det.x-float(-1), float(-0.5))*BiCubicPoly1(det.y-float(1), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(-1), float(1)))/vec2(uUnit, vUnit))
+BiCubicPoly2(det.x-float(-1), float(-0.5))*BiCubicPoly2(det.y-float(2), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(-1), float(2)))/vec2(uUnit, vUnit))
+BiCubicPoly1(det.x-float(0), float(-0.5))*BiCubicPoly2(det.y-float(-1), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(0), float(-1)))/vec2(uUnit, vUnit))
+BiCubicPoly1(det.x-float(0), float(-0.5))*BiCubicPoly1(det.y-float(0), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(0), float(0)))/vec2(uUnit, vUnit))
+BiCubicPoly1(det.x-float(0), float(-0.5))*BiCubicPoly1(det.y-float(1), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(0), float(1)))/vec2(uUnit, vUnit))
+BiCubicPoly1(det.x-float(0), float(-0.5))*BiCubicPoly2(det.y-float(2), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(0), float(2)))/vec2(uUnit, vUnit))
+BiCubicPoly1(det.x-float(1), float(-0.5))*BiCubicPoly2(det.y-float(-1), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(1), float(-1)))/vec2(uUnit, vUnit))
+BiCubicPoly1(det.x-float(1), float(-0.5))*BiCubicPoly1(det.y-float(0), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(1), float(0)))/vec2(uUnit, vUnit))
+BiCubicPoly1(det.x-float(1), float(-0.5))*BiCubicPoly1(det.y-float(1), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(1), float(1)))/vec2(uUnit, vUnit))
+BiCubicPoly1(det.x-float(1), float(-0.5))*BiCubicPoly2(det.y-float(2), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(1), float(2)))/vec2(uUnit, vUnit))
+BiCubicPoly2(det.x-float(2), float(-0.5))*BiCubicPoly2(det.y-float(-1), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(2), float(-1)))/vec2(uUnit, vUnit))
+BiCubicPoly2(det.x-float(2), float(-0.5))*BiCubicPoly1(det.y-float(0), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(2), float(0)))/vec2(uUnit, vUnit))
+BiCubicPoly2(det.x-float(2), float(-0.5))*BiCubicPoly1(det.y-float(1), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(2), float(1)))/vec2(uUnit, vUnit))
+BiCubicPoly2(det.x-float(2), float(-0.5))*BiCubicPoly2(det.y-float(2), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(2), float(2)))/vec2(uUnit, vUnit))
;
}

双三次插值算法的OpenGL实现相关推荐

  1. 三种常见的图像处理双三次插值算法

    三种常见的图像处理双三次插值算法 双立方插值计算涉及16像素,间(i', j')像中的包括 小数部分的像素坐标.dx表示X方向的小数坐标.dy表示Y方向的小数坐标. 详细 能够看下图: 依据上述图示与 ...

  2. 怎么用python编程实现二次差值多项式_双三次插值算法详解 含python实现

    一. 图像双三次插值算法原理: 假设源图像 A 大小为 m*n ,缩放后的目标图像 B 的大小为 M*N .那么根据比例我们可以得到 B(X,Y) 在 A 上的对应坐标为 A(x,y) = A( X* ...

  3. 图像的放大:双三次插值算法(C++实现)

    双线性插值算法的不足就是细节处理的不好,换句话说,就是曲线拟合得不够光滑,所以又有了双三次插值算法.双三次插值算法是基于周围的16个像素点,通过计算16个像素点的权重,累积得到增加点的像素值的. 简单 ...

  4. 图像常用的插值算法:最近邻插值、双线性插值和双三次插值算法

    图像常用的插值算法 最近邻插值算法 双线性插值算法 双三次插值(bicubic)算法 三种插值算法的优缺点 插值算法是图像缩放中的一项基本且重要的算法:在图像缩放中,输出图像像素点坐标可能对应输入图像 ...

  5. 计算机图形学 裁剪算法源代码,OpenGL计算机图形学梁友栋裁剪算法实验代码及运行结果.doc...

    OpenGL计算机图形学梁友栋裁剪算法实验代码及运行结果.doc (10页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 14.9 积分  .<计算 ...

  6. 圆的Bresenham算法C语言代码,圆的Bresenham算法的opengL实现

    源代码实现如下: // Bresenham_circile.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include #includ ...

  7. 基于边缘检测的磨皮算法实现——OpenGL版

    一.背景 人脸磨皮算法的本质是模糊算法,但是与模糊算法最大的区别是,磨皮算法需要考虑保边效果,需要达到"磨皮了但又保留了脸部的各种纹理细节和边缘信息"的效果.保边的思路甚至与模糊的 ...

  8. Cyrus-Beck裁剪算法及OpenGL实践

    恩..接着就是Cyrus-Beck算法.这个算法比之前的Cohen-Sutherland算法厉害,处理任意凸多边形对线段的裁剪.自然,这个算法也比Cohen-Sutherland算法复杂不少. 首先, ...

  9. Cyrus Beck(参数化)裁剪算法基于opengl实现

    Cyrus Beck裁剪算法是计算机图形学中的一个实验,这个实验的难点在于理解,而不在于实现.这个算法也是基础算法里比较有趣的一个.CB算法只针对凸多边形,对于凹多边形不适用. Cyrus Beck算 ...

最新文章

  1. 牛客华为机试第3题python
  2. 【操作系统】【C/C++开发】内存管理
  3. html代码格式化vscode,vscode 代码格式化
  4. c 语言 结构体的引用
  5. ICLR 2021 | 使用CVAE学习干扰集,增强OOD以及对抗防御的能力
  6. intellij idea -- 工程移植
  7. java读取文件方法
  8. mysql数据库维护_维护MySQL数据库表
  9. oracle nvl和coalesce,NVL与Coalesce之间的Oracle差异
  10. 毕设项目,系统搭建笔记文档
  11. SATI阅读重点有哪些?
  12. 【vtk实例】平面切割
  13. 电子通讯录(自存储)
  14. Idea输入汉字变成繁体字
  15. 2013年阿里巴巴实习生招聘笔试题目及解答
  16. Tested采访扎克伯格:揭秘四款VR原型机更多细节
  17. python实现Content-Type: multipart/form-data; boundary=xxx接口的调用
  18. WindowsXP设置自动登录
  19. ctkPlugin插件系统实现项目插件式开发
  20. EXCEL相对引用,绝对引用和混合引用的区别

热门文章

  1. 六轴机器人运动学正解
  2. 什么时候用C而不用C++?
  3. 计算机上64位数和32位数,cad中32位和64位的区别是什么?
  4. 如何给电脑硬盘分区?
  5. 情侣纪念日网站html5源码教程
  6. 定时任务实现原理详解
  7. NVIDIA Jetson: GStreamer 和 openMAX(gst-omx) 插件
  8. 一文搞懂什么是GPA
  9. cesium教程-3(显示高度,海拔,经度,纬度)
  10. 微信小程序 - 无法获取云端数据库中的数据的问题(修改云端数据库权限)