双三次插值算法的OpenGL实现

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

双三次插值算法的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))
;
}
目录
相关文章
|
1月前
|
编解码 算法 计算机视觉
基于FPGA的图像最近邻插值算法verilog实现,包括tb测试文件和MATLAB辅助验证
基于FPGA的图像最近邻插值算法verilog实现,包括tb测试文件和MATLAB辅助验证
|
2月前
|
算法 计算机视觉 Python
python 插值算法
最近在做时间序列预测时,在突增或者突降的变化剧烈的情况下,拟合参数的效果不好,有用到插值的算法补全一些数据来平滑剧烈变化过程。还有在图像处理中,也经常有用到插值算法来改变图像的大小,在图像超分(Image Super-Resolution)中上采样也有插值的身影【2月更文挑战第8天】
29 2
|
2月前
|
算法
MATLAB | 插值算法 | 一维interpl插值法 | 附数据和出图代码 | 直接上手
MATLAB | 插值算法 | 一维interpl插值法 | 附数据和出图代码 | 直接上手
36 0
|
2月前
|
算法
MATLAB | 插值算法 | 二维griddata插值法 | 附数据和出图代码 | 直接上手
MATLAB | 插值算法 | 二维griddata插值法 | 附数据和出图代码 | 直接上手
39 0
|
2月前
|
算法
MATLAB | 插值算法 | 一维Lagrange插值法 | 附数据和出图代码 | 直接上手
MATLAB | 插值算法 | 一维Lagrange插值法 | 附数据和出图代码 | 直接上手
21 0
|
4月前
|
算法
【MATLAB】史上最全的5种数据插值算法全家桶
【MATLAB】史上最全的5种数据插值算法全家桶
34 0
|
4月前
|
算法 数据处理
数据拟合、参数估计、插值等数据处理算法
数据拟合、参数估计、插值等数据处理算法
数据拟合、参数估计、插值等数据处理算法
|
6月前
|
算法
基于亚奈奎斯特采样和SOMP算法的平板脉冲响应空间插值matlab仿真
基于亚奈奎斯特采样和SOMP算法的平板脉冲响应空间插值matlab仿真
|
8月前
|
算法 索引
插值查找算法
插值查找算法
38 0
|
10月前
|
算法 索引
插值查找算法
插值查找算法
44 0