OpenGL高斯模糊
高斯模糊
- 簡介
- 描述
- 高斯分布
- 高斯函數
- 模糊半徑
- 卷積運算
- 卷積核
- 原圖像
- 卷積結果
- 細節
- 高斯函數卷積核
- 實現
- Python計算卷積核
- OpenGL卷積核實現
- OpenGL高斯模糊優化
簡介
描述
高斯模糊:使用高斯函數求出的值來作為卷積核進行圖像的卷積運算。
卷積核總結:
高斯分布
f(x)=12πσ2e?(x?μ)22σ2f(x)=\frac{1}{\sqrt{2\pi\sigma^2}} {e^{-\frac{(x-\mu)^2}{2\sigma^2}}} f(x)=2πσ2?1?e?2σ2(x?μ)2?
高斯函數
G(r)=12πσ2Ne?r22σ2G(r)=\frac{1}{\sqrt{2\pi\sigma^2}^{N}} {e^{-\frac{r^2}{2\sigma^2}}} G(r)=2πσ2?N1?e?2σ2r2?
σ\sigmaσ是正態函數的標準差, rrr代表模板中元素到模板中心的距離,又稱為模糊半徑, NNN代表處于NNN維空間。
模糊半徑
定義:歐式距離(N維向量的模)。
歐幾里得度量(euclidean metric)也稱歐氏距離,是一個通常采用的距離定義,指在m維空間中兩個點之間的真實距離,或者向量的自然長度(即該點到原點的距離)。
卷積運算
卷積核
原圖像
卷積結果
從原圖像中提取與卷積同等大小的矩陣與卷積核進行矩陣相乘運算。
6=(0?2+0)+(?2+20?8)+(0?2+0)6=(0-2+0)+(-2+20-8)+(0-2+0) 6=(0?2+0)+(?2+20?8)+(0?2+0)
細節
卷積處理后,圖像的每條邊少了一個像素。
解決:將已有的點拷貝到另一面的對應位置,也就是填充邊。
高斯函數卷積核
假設σ=1.5\sigma=1.5σ=1.5,高斯卷積核如下。
實現
Python計算卷積核
import mathpi = 3.1415926 sigma = 1.5 e = 2.7182804def G(r):return (1 / pow(math.sqrt(2 * pi * pow(sigma, 2)), 2)) * pow(e, -((r*r) / (2 * pow(sigma, 2))))print("G(2) = %.7f" % G(2)) # G(2) = 0.0290803 print("G(1) = %.7f" % G(1)) # G(1) = 0.0566406 print("G(0) = %.7f" % G(0)) # G(0) = 0.0707355OpenGL卷積核實現
#iChannel0 "file://images/img.jpg" // 與shader腳本文件在同級目錄下// 高斯函數用到的常量 const float pi = 3.1415926; const float sigma = 1.5; const float e = 2.7182804;// 高斯函數, r為歐式距離 float G(float r) {return (1.0 / pow(sqrt(2.0 * pi * pow(sigma, 2.0)), 2.0)) * pow(e, -((r*r) / (2.0 * pow(sigma, 2.0)))); }// 主函數 void mainImage(out vec4 fragColor, in vec2 fragCoord) {// 計算uv, iResolution.xy是screen大小vec2 uv = fragCoord.xy / iResolution.xy;// 模擬像素vec2 pixed = 2.0 / iResolution.xy;// 相鄰像素的uvvec2 texcoords[9];texcoords[0] = uv + vec2(-1.0, -1.0) * pixed;texcoords[1] = uv + vec2(0.0, -1.0) * pixed;texcoords[2] = uv + vec2(1.0, -1.0) * pixed;texcoords[3] = uv + vec2(-1.0, 0.0) * pixed;texcoords[4] = uv + vec2(0.0, 0.0) * pixed;texcoords[5] = uv + vec2(1.0, 0.0) * pixed;texcoords[6] = uv + vec2(-1.0, 1.0) * pixed;texcoords[7] = uv + vec2(0.0, 1.0) * pixed;texcoords[8] = uv + vec2(1.0, 1.0) * pixed;// 相鄰像素對應的權重, 卷積核float w[9];w[0] = w[2] = w[6] = w[8] = G(2.0);w[1] = w[3] = w[5] = w[7] = G(1.0);w[4] = G(0.0);// 權重總和, 用來歸一化卷積核float totalWeight = w[0] * 4.0 + w[1] * 4.0 + w[4];// 卷積運算vec4 gaussColor = vec4(0.0);for (int i = 0; i < 9; i++) {gaussColor += texture2D(iChannel0, texcoords[i]) * w[i] / totalWeight;}// 原圖vec4 originalColor = texture2D(iChannel0, uv);// sin + time動態變化float normalTime = abs(sin(iTime));// mix輸出顏色fragColor = mix(originalColor, gaussColor, normalTime); }OpenGL高斯模糊優化
優化點:
- 在片元著色器會重復計算卷積核,比較耗時;可以放在CPU計算,傳給shader。
- 3×33 \times 33×3卷積就需要在片元中紋理采樣9次,可以降低為6次。
- 先進行橫向模糊,采樣3次,存儲橫向結果texture。
- 橫向結果texture再進行縱向模糊,采樣3次。
總結
以上是生活随笔為你收集整理的OpenGL高斯模糊的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 防止电脑自动休眠小妙招
- 下一篇: 数据产品经理:6大数据分析平台的“世界观