第九章 OpenGL ES 基础-高斯模糊原理

第九章 OpenGL ES 基础-高斯模糊原理

第一章 OpenGL ES 基础-屏幕、纹理、顶点坐标
第二章 OpenGL ES 基础-GLSL语法简单总结
第三章 OpenGL ES 基础-GLSL渲染纹理
第四章 OpenGL ES 基础-位移、缩放、旋转原理
第五章 OpenGL ES 基础-透视投影矩阵与正交投影矩阵
第六章 OpenGL ES 基础-FBO、VBO理解与运用
第七章 OpenGL ES 基础-输入输出框架思维
第八章 OpenGL ES 基础-MVP矩阵理解
第九章 OpenGL ES 基础-高斯模糊原理
第十章 OpenGL ES 基础-图像USM锐化
第十一章 OpenGL ES 基础-基础光照
第十二章 OpenGL ES 基础-色温、色调、亮度、对比度、饱和度、高光
第十三章 OpenGL ES-RGB、HSV、HSL模型介绍
第十四章 OpenGL ES-方框模糊(均值模糊)
第十五章 OpenGL ES-VR 全景模式原理
第十六章 OpenGL ES-桶形畸变算法-常用VR

正态分布

在这里插入图片描述
上图人类的智商分布比例,大多数人的智商集中在85-115,超高和超低智商的人只占很小的比例,柱状图可用一条曲线拟合,如图中红色曲线所示. 这个钟形曲线就是正态分布曲线. 正态分布曲线体现了宇宙中很多事物的分布规律,比如全国身高的分布,年级考试成绩的分布,气体分子运动速度的分布,抛10个硬币1000次正面向上的次数分布,等等都符合正态分布.

正态分布试验

在这里插入图片描述
正态分布,可描述某事件大量发生时的分布规律,或某事件单独发生的可能性,也就是概率. 事件发生后,可用统计解释,发生前可用概率预测. 图2-2的装置叫做高尔顿钉板,可验证大量重复试验的结果符合正态分布. 小球从顶部落下,会经过很多钉子,每碰到一个钉子,小球弹向左边或右边的概率都是1/2,落在最左边或者最右边的概率非常低,落在中间的概率最高,所以可以用正态分布描述小球落入区间的分布.

正态分布的数学公式

在这里插入图片描述

数学公式:

在这里插入图片描述
曲线表示概率密度变化,x轴数值表示试验结果,函数值是这个结果对应的概率, 比如某人智商是x=130的概率是f(x),或者说人类中智商是x=130的所占的比例是f(x). 曲线积分(曲线和x轴围成的面积)等于1,即所有可能的情况(x的取值值)的概率和(求积分)是1,比如某人的智商是x∈[0-150](全部可能性)的概率是1.

x=μ,对应钟形曲线最高点,μ是x的概率加权平均值,叫期望E(X),期望就是平均值,比如智商统计的曲线中μ=100,那么人类的平均智商就是100. μ=0时,平均值就是0,如图.小明和小红的智商是90和110,平均值是:(90+110)/2=100

σ2的平方是方差,即Var(X)=E[(X-μ)2 ],即所有x与平均值的差,平方,求和,最后平均. 方差表示样本的平均波动大小,比如小明和小红的智商是90和110,平均值是100,方差是[(90-100)2+(110-100)2 ]/2=100,再比如小明和小红的智商是50和150,平均值也是100,但是方差(波动性)要大得多, [(50-100)2+(150-100)2 ]/2=2500

从正态分布到高斯模糊

**均值模糊:**将中心像素和周围像素颜色数值加起来求平均,作为中心像素的模糊结果

**中值模糊:**把中心像素和周围像素的颜色排个顺序,取中间像素的颜色数值作为模糊结果

**高斯模糊:**中间像素和周围像素对模糊的权重(重要性)不一样,且权重遵循正态分布,进行加权平均. 换句话说,高斯模糊就是参与模糊的像素(中间像素和周围像素)的重要性,符合正态分布,所以按照正态分布的规律加权平均就是最后的模糊数值,中间像素权重(百分比)最大,越往边上,权重(百分比)越小,且所有的权重(百分比)的和应该是1,即100%. 正态分布又叫做高斯分布,所以这种模糊又叫高斯模糊. 中间像素的权重最大,对应钟形曲线最高点,左右像素的权重对称相等,所以μ=0 ,曲线关于y轴对称;σ决定了曲线的陡峭程度,σ=1的曲线相对平滑,那么模糊也会相对平滑. 高斯模糊的像素权重分布,采用的正态分布函数如下:
在这里插入图片描述
在这里插入图片描述
正态分布是连续的,纹理采样点是离散问题有限的,对于每个纹素,不可能采样整张图像,按照正态分布加权平均,最后生成该纹素点的模糊值. 出于效率考虑,假设在目标纹素左右,以Δx为间隔,各采样2个点,包括中心的目标纹素共5个点,如图2-5. 那么应该将这5个点,映射在正态分布多大的范围内,来取得权重呢?正态分布的样本空间是[-∞,+∞], 在 图2-5中,当 x∈[μ-2σ,μ+2σ] 时,概率(权重)总和已经达到95%, 接近100%,再靠边缘的样本对最后结果的贡献非常非常小, 所以仅需要在正态分布的[μ-2σ,μ+2σ]区间中计算权重即可.

当分布函数为f(x)=1/√2π e(-x2/2),即μ=0,σ=1时,区间[-2,+2]权重占到95%. 那么5个纹理采样点,映射到正态分布的区间[-2,+2]上,得到正态分布曲线的x值为-2,-1,0,1,2,得到5个纹理采样点对应的5个权重值,或者说这5个纹素对于目标纹素点模糊的贡献比例为:

f(0)=“0.3989”, f(1)=“0.2420”, f(2)=“0.0540”,f(-1)=“0.2420”, f(-2)=“0.0540”,

但这些权重加起来不是1,而是

∑_(i=1)^5▒〖f(i)=0.0540+0.2420+0.3989+0.2420+0.0540=〗 0.9909
在[-2,+2]区间,权重总和不是应该占95%吗,怎么是99%呢?这是因为,这个95%是积分计算的结果,而此处的结果是离散数据计算的.如图2-5-2

在这里插入图片描述
在这里插入图片描述

二维高斯模糊

图像是二维的,那么模糊权重也应该是二维的,所以将正态分布从一维扩展到二维,公式为:
在这里插入图片描述
二维的高斯算子,是x,y两个参数共同决定的, 离远点越近,权重值越大. 如果在目标纹素周围5*5的范围采样,需要把这25个纹素采样点映射到x∈[-2,+2],y∈[-2,+2]的区间内的25个(x,y)坐标,计算得到25个权重,再对25个纹理采样颜色分别乘以权重,得到加权求平均值,即最终的高斯模糊颜色,如图所示.
在这里插入图片描述

在这里插入图片描述

横竖高斯模糊处理

在这里插入图片描述
按上面的知识进行水平模糊后再进行竖直模糊得到下图
在这里插入图片描述

上面知识采用该文章原文

上面知识点总结

1、正态分布原理,对应公式
2、高斯模糊,取任意点上下左右对称点位置像素进行正态分布处理,权重相加约等于1,标准高斯模糊,权重中间像素权重(百分比)最大,越往边上,权重(百分比)越小。
3、高斯模糊分横竖方向两部,按一纬高斯模糊分别进行处理
在这里插入图片描述

GLSL代码部分

具体的说明我已经,在代码进行注解,按的标准高斯模糊,weight是权重,权重值的设定可能是根据特定需求或者视觉效果来调整的。虽然标准情况下权重是随着距离增大而减小的(如正常的高斯分布),但在实际应用中可能会根据具体情况进行微调。正常调整不一样靠中间的值越大,需要自己注意和理解

/**
 * 对texelWidthOffset和texelHeightOffset是1.5f / videoWidth.5f / videoHeight,横向高斯模糊texelWidthOffset,为0,竖直方向高斯模糊texelWidthOffset为0
 *singleStepOffset对应乘1-5分别,为了取像素点vTexCoord(x,y)横向时候取左右5个像素点,竖直时候取上下5个像素点
 */

static const char* gauss_vertex_shader ="attribute vec4 position;\n"
                                        "attribute vec2 texCoord;\n"
                                        "\n"
                                        "uniform float texelWidthOffset;\n"
                                        "uniform float texelHeightOffset;\n"
                                        "\n"
                                        "varying vec2 vTexCoord;\n"
                                        "varying vec2 blurCoordinates[11];\n"
                                        "\n"
                                        "void main()\n"
                                        "{\n"
                                        "    gl_Position = position;\n"
                                        "    vTexCoord = texCoord.xy;\n"
                                        "\n"
                                        "    vec2 singleStepOffset = vec2(texelWidthOffset, texelHeightOffset);\n"
                                        "    blurCoordinates[0] = texCoord.xy;\n"
                                        "    blurCoordinates[1] = texCoord.xy + singleStepOffset * 1.0;\n"
                                        "    blurCoordinates[2] = texCoord.xy - singleStepOffset * 1.0;\n"
                                        "    blurCoordinates[3] = texCoord.xy + singleStepOffset * 2.0;\n"
                                        "    blurCoordinates[4] = texCoord.xy - singleStepOffset * 2.0;\n"
                                        "    blurCoordinates[5] = texCoord.xy + singleStepOffset * 3.0;\n"
                                        "    blurCoordinates[6] = texCoord.xy - singleStepOffset * 3.0;\n"
                                        "    blurCoordinates[7] = texCoord.xy + singleStepOffset * 4.0;\n"
                                        "    blurCoordinates[8] = texCoord.xy - singleStepOffset * 4.0;\n"
                                        "    blurCoordinates[9] = texCoord.xy + singleStepOffset * 5.0;\n"
                                        "    blurCoordinates[10] = texCoord.xy - singleStepOffset * 5.0;\n"
                                        " }";
/**
 * blurCoordinates对应像素点,进行 sum += texture2D(texture, blurCoordinates[0]) * weight;
 * weight是权重,权重之和要约等于1,
 *
 */
static const char* gauss_fragment_shader ="precision highp float;\n"
                                          "uniform sampler2D texture;\n"
                                          "\n"
                                          "uniform float texelWidthOffset;\n"
                                          "uniform float texelHeightOffset;\n"
                                          "\n"
                                          "varying vec2 vTexCoord;\n"
                                          "\n"
                                          "varying highp vec2 blurCoordinates[11];\n"
                                          "\n"
                                          "void main()\n"
                                          "{\n"
                                          "    vec4 tex = texture2D(texture, vTexCoord);\n"
                                          "    vec4 sum = vec4(0.0);\n"
                                          "    sum += texture2D(texture, blurCoordinates[0]) * 0.180590;\n"
                                          "    sum += texture2D(texture, blurCoordinates[1]) * 0.146265;\n"
                                          "    sum += texture2D(texture, blurCoordinates[2]) * 0.146265;\n"
                                          "    sum += texture2D(texture, blurCoordinates[3]) * 0.136940;\n"
                                          "    sum += texture2D(texture, blurCoordinates[4]) * 0.136940;\n"
                                          "    sum += texture2D(texture, blurCoordinates[5]) * 0.078710;\n"
                                          "    sum += texture2D(texture, blurCoordinates[6]) * 0.078710;\n"
                                          "    sum += texture2D(texture, blurCoordinates[7]) * 0.035367;\n"
                                          "    sum += texture2D(texture, blurCoordinates[8]) * 0.035367;\n"
                                          "    sum += texture2D(texture, blurCoordinates[9]) * 0.012422;\n"
                                          "    sum += texture2D(texture, blurCoordinates[10]) * 0.012422;\n"
                                          "\n"
                                          "    gl_FragColor = sum;\n"
                                          "}\n"
                                          "";
  • 14
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1 课程简介:本课程详细讲解了OpenGL从入门到精通的理论+实践知识,对于每一个知识点都会带领学员通过代码来实现功能。其中涵盖了基础图元绘制,基础光照,高级过程,高级光照等内容;当前图形引擎的应用已经越来越广泛,春晚以及各大综艺节目已经开始使用XR作为主流的内容制作技术,房地产漫游及Web渲染技术已经开始茁壮发展,VR也即将突破硬件瓶颈;普遍的游戏引擎在独特的领域已经无法完全实用,且我们国家要发展自主科技技术,图形引擎以及CAD等卡脖子技术一定会蓬勃发展,所以同学们要抓住机会,趁势而上,熟悉底层,博取更大发展,学习OpenGL底层接口的应用以及图形学算法,将是您向纵深发展的第一步!2 课程解决优势:很多同学学习OpenGL最难的是找到路径,并且其中牵扯到的理论知识点无法完全理解透彻(比如VAO与VBO的区别,MVP矩阵变换的推导及原理,光照系统的设计及算法推导,帧缓存的灵活应用等),我们的课程可以带领大家从原理+实践的角度进行学习,每一个知识点都会:a 推导基础公式及原理 b 一行一行进行代码实践从而能够保证每位同学都学有所得,能够看得懂,学得会,用得上,并且能够培养自主研究的能力。学习课程所得:学习本课程完毕之后,学员可以全方位的完全了解OpenGL当中的必要接口,并且可以对图形学的基础知识融会贯通,可以制作中级的特效。并且对于UnrealEngine以及Unity3D的学习更加轻松,对于各类商业引擎当中的算法以及内容制作手法更加深刻理解把控。学员也可以自行进行图形引擎的设计以及研究,并且将本课程的知识点进行代码模块化编写;能够自主推导图形学管线以及应用当中的各类公式,并且理解其几何含义。 代码与PPT资源,已随课程附赠,请同学们对应课程下载 
opengles是一种用于在移动设备和嵌入式系统上实现2D和3D图形渲染的图形库。而gl-transitions是一个开源的OpenGL库,用于创建平滑过渡效果,可以应用于图像、视频等多种媒体内容。 要将gl-transitions移植到opengles上,需要进行以下步骤: 1. 确定opengles版本:gl-transitions可能使用的是OpenGL的较新版本,而opengles可能只支持较旧的版本。因此,首先需要确定opengles版本,并了解其与OpenGL之间的差异。 2. 了解gl-transitions的实现:深入了解gl-transitions的实现方式和代码结构,理解其对OpenGL的使用方式和功能。 3. 理解opengles的API:熟悉opengles的API,包括顶点/片段着色器、缓冲区对象、纹理对象等。理解opengles的渲染管线和数据传递方式,以便能够正确地将gl-transitions移植到opengles上。 4. 逐步移植:根据gl-transitions的实现和opengles的API,逐步将gl-transitions的代码移植为opengles可用的代码。这可能涉及到对着色器代码的修改、纹理对象的创建和绑定、缓冲区对象的使用等。 5. 调试和测试:移植完成后,进行调试和测试以确保移植后的代码在opengles上正常工作,并且能够正确地渲染出所需的过渡效果。 需要注意的是,由于较新版本的OpenGL可能具有一些opengles不支持的功能,因此在移植过程中可能需要做一些功能的调整或替代。此外,移植过程中可能还需要考虑设备的性能和兼容性问题,确保移植后的代码能够在目标设备上流畅地运行。 总结起来,将gl-transitions移植到opengles上需要对opengles的API有很好的了解,并根据它的渲染方式和数据传递方式对gl-transitions的代码进行适当的修改和调整。这样才能确保移植后的代码能够在opengles上正常运行并呈现出所需的过渡效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

baoyu45585

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值