OpenGL-高斯模糊原理

news2024/11/25 20:43:09

OpenGL-高斯模糊原理

正态分布

在这里插入图片描述
上图人类的智商分布比例,大多数人的智商集中在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"
                                          "";

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

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

相关文章

针对BSV区块链新推出的网络访问规则NAR和警报系统AS的解释与问答

​​发表时间:2024年2月22日 BSV区块链社区团队最近开设了一个Twitter(X)话题空间,讨论BSV区块链协会最新推出的网络访问规则和警报系统的相关问题。 本次讨论由BSV区块链社区负责人Brett Banfe主持,以便社区成员更好…

JAVA八股--基础--下

JAVA八股--基础--下 从字节码层面看try-catch-finally的实现机制为什么要用泛型? | 泛型方法、通配符该如何使用 | Java中的泛型知识反射 何为反射 反射优缺点 应用场景(需要先学习相关基础知识)SPI机制I/O 流为什么要分为字节流和字符流呢?…

如何利用IP地址分析风险和保障网络安全

随着网络攻击的不断增加和演变,保障网络安全已经成为了企业和组织不可忽视的重要任务。在这样的背景下,利用IP地址分析风险和建立IP风险画像标签成为了一种有效的手段。本文将深入探讨IP风险画像标签的作用以及如何利用它来保障网络安全。 IP风险画像查…

用Compute Shader处理图像数据后在安卓机上不能正常显示渲染纹理

1)用Compute Shader处理图像数据后在安卓机上不能正常显示渲染纹理 2)折叠屏适配问题 3)Prefab对DLL中脚本的引用丢失 4)如何优化Unity VolumeManager中的ReplaceData 这是第378篇UWA技术知识分享的推送,精选了UWA社区…

数据库基本介绍及编译安装mysql

目录 数据库介绍 数据库类型 数据库管理系统(DBMS) 数据库系统 DBMS的工作模式 关系型数据库的优缺点 编译安装mysql 数据库介绍 数据:描述事物的的符号纪录称为数据(Data) 表:以行和列的形式组成…

个人商城系统开源(配置支付宝支付2)

原文地址:个人商城系统开源(配置支付宝支付2) - Pleasure的博客 下面是正文内容: 前言 在上一篇文章中我曾提到过关于网站支付宝支付的方法,接下来我们来介绍第二种。 个人博客地址:个人商城系统开源&…

奶牛均分

解法&#xff1a; 假设编号从左到右递增&#xff0c;奶牛每次只能去往左边的牛圈。因此等分最大奶牛数小于等于最右边牛圈奶牛数&#xff0c;不妨设数为k&#xff0c;那么a[i]>k&#xff0c;a[i-1]>2k。。。 做后缀和二分答案就可找到k #include<iostream> #inc…

利用Android studio 查看模拟器中数据文件

打开Android studio &#xff0c;然后按照下图选择 然后会在右侧打开一个这样子的管理弹窗 找到 data/data/your project file 你的缓存跟下载的文件就都在里面了

如何利用RunnerGo简化性能测试流程

在软件开发过程中&#xff0c;测试是一个重要的环节&#xff0c;需要投入大量时间和精力来确保应用程序或网站的质量和稳定性。但是&#xff0c;随着应用程序变得更加复杂和庞大&#xff0c;传统的测试工具在面对比较繁琐的项目时非常费时费力。这时&#xff0c;一些自动化测试…

UE4_官方动画内容示例1.1_使用动画资产

对一个SkeletalMeshActor进行设置&#xff0c;设置好之后&#xff0c;可以通过该Actor的细节&#xff08;Details&#xff09;面板播放指定的动画序列&#xff08;AnimationSequence&#xff09;资产&#xff08;例如让Actor翻跟斗并做开合跳&#xff09;。 骨架网格体定义&am…

相机与激光雷达是怎么标定的?一览行业所有主流的标定工具

相机与激光雷达是怎么标定的&#xff1f;一览行业所有主流的标定工具 相机与激光雷达的标定是很多任务的基础工作&#xff0c;标定精度决定了下游方案融合的上限&#xff0c;因为许多自动驾驶与机器人公司投入了较大的人力物力不断提升&#xff0c;今天也为大家盘点下常见的Ca…

幼儿教育管理系统|基于jsp 技术+ Mysql+Java的幼儿教育管理系统设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java&#xff0c;ssm&#xff0c;springboot的平台设计与实现项目系统开发资源&#xff08;可…

【PHP + 代码审计】函数详解2.0

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收…

matlab 基于小波变换的油气管道泄露信号检测

1、内容简介 略 71-可以交流、咨询、答疑 基于小波变换的油气管道泄露信号检测 去噪、小波变换、油气管道泄露、信号检测 2、内容说明 摘 要&#xff1a; 油气管道泄漏会造成严重危害&#xff0c;因此&#xff0c;亟需寻找一种能快速检测油气管道信号的技术。传统的 傅里…

Gif动态闪图如何制作?教你1分钟快速制作

动态文字闪图是一种独特而有趣的图像效果&#xff0c;通过将文字以闪烁、跳动或变换的方式呈现&#xff0c;给人一种动态感和视觉冲击力。如果你想制作自己的动态文字闪图&#xff0c;下面是一些简单的方法来帮助你完成这个任务。使用在线闪图制作网站-GIF5工具网&#xff0c;无…

Ubuntu虚拟机的IP总频繁变化,导致Xshell断开连接

文章目录 一、IP变化的原因二、解决方法&#xff1a;固定IP三、参考文章 一、IP变化的原因 1.DHCP协议 虚拟机系统(Ubuntu、CentOS、UOS等Linux系统)启动后&#xff0c;加入本地局域网网络时&#xff0c;会向本地网络申请租约一个IP地址&#xff0c;租约时长不定。我这里租约时…

程序员下班以后做什么副业合适?

我就是一个最普通的网络安全工程师&#xff0c;出道快10年了&#xff0c;不出意外地遭遇到瓶颈期&#xff0c;但是凭技术在各大平台挖漏洞副业&#xff0c;硬是妥妥扛过来了。 因为对于程序员来讲&#xff0c;这是个试错成本很低、事半功倍的选择。编程技能是一种强大生产力&a…

RocketMQ tag不匹配

问题现象 消费组消费消息显示tag不匹配&#xff0c;但检查配置是一样的tag 消费端配置 原因分析 订阅组订阅一致性 订阅一致性是指同一个订阅组&#xff08;ConsumerGroup&#xff09;下所有的 Consumer 实例订阅&#xff0c;Topic 与 Tag 必须完全一致&#xff0c;否则可能…

首页效果炫酷的wordpress免费主题模板

视频背景免费WP主题 简洁大气的视频背景wordpress主题&#xff0c;找大视频背景的主题可以看看这个。 https://www.wpniu.com/themes/193.html 红色全屏大图WP主题 非常经典的一款免费wordpress主题&#xff0c;红色全屏大图满足多行业使用。 https://www.wpniu.com/themes…

代码随想录算法训练营第29天| 491.递增子序列、46.全排列、47.全排列 II

491.递增子序列 题目链接&#xff1a;复原IP地址 题目描述&#xff1a;给你一个整数数组 nums &#xff0c;找出并返回所有该数组中不同的递增子序列&#xff0c;递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素&#xff0c;如出现两个整数…