高斯座標自然值計算 高斯模糊

2021-10-13 15:49:55 字數 2955 閱讀 5609

之前看馮樂樂女神的《unity shader入門精要》高斯模糊這一節只是大概略過,昨晚重新看了一下,感受頗深,隨即搞了乙個效果試一下。

老規矩先上圖:

原圖:

高斯模糊:(毛玻璃的既視感)

「清晰的,各個畫素之間會有明顯的過渡,而如果各個畫素之間的差距不是很大,那麼影象就會模糊了」。鑑於這個定義,我們就可以通過**來實現模糊的效果。

什麼是高斯模糊:

高斯模糊(gaussian blur),又叫做高斯平滑。高斯模糊主要的功能是對進行加權平均的過程,與均值模糊中周圍畫素取平均值不同,高斯模糊進行的是乙個加權平均操作,每個畫素的顏色值都是由其本身和相鄰畫素的顏色值進行加權平均得到的,越靠近畫素本身,權值越高,越偏離畫素的,權值越低。

而這種權值符合我們比較熟悉的一種數學分布-正態分佈,又叫高斯分布,所以這種模糊就是高斯模糊。

高斯模糊和均值模糊一樣,也是取每個畫素以及周邊畫素的平均值,只不過高斯模糊在取值是離原畫素越遠的畫素權重越低,而均值模糊則所有畫素的權重相等,因此從計算量上來說,採用相同階數的高斯模糊計算量要比均值模糊要大,但是模糊效果要更好,由於沒有明顯的邊界,不會出現均值模糊會出現的方塊化效果。

高斯模糊利用了卷積計算,它使用的卷積核名為高斯核。高斯核是乙個正方形大小的濾波核,其中每個元素的計算都是基於下面的高斯方程:

其中σ 是標準方差(一般取值為1),x和y分別對應了當前位置到卷積核中心的整數距離。要構建乙個高斯核,我們只需要計算高斯核中各個位置對應的高斯值。為了保證濾波後的影象不會變暗,我們需要對高斯核中的權重進行歸一化,即讓每個權重除以所有權重的和,這樣可以保證所有權重的和為1。因此,高斯函式中e的前面的係數實際不會對結果又任何影響。下圖顯示了乙個標準方差為1的5×5大小的高斯核。

高斯方程很好地模擬了鄰域每個畫素對當前處理畫素的影響程度——距離越近,影響越大。高斯核的維數越高,模糊程度越大。使用乙個n×n的高斯核對影象進行卷積濾波,就需要n×n×w×h(w和h分別是影象的寬和高)次紋理取樣。當n的大小不斷增加時,取樣次數會變得非常巨大。幸運的是,我們可以把這個二維高斯函式拆分成兩個一維函式。也就是說,我們可以使用兩個一維的高斯核(上圖中的右圖)先後對影象進行濾波,它們得到的結果和直接使用二維高斯核是一樣的,但取樣次數只需要2×n×w×h.我們可以進一步觀察到,兩個一維高斯核中包含了很多重複的權重,對弈乙個大小為5的一維高斯核,我們實際只需要記錄3個權重即可。

我們將會使用上述5×5的高斯核對原影象進行高斯模糊。我們將先後呼叫兩個pass,第乙個pass將會使用豎直方向的一維高斯核對影象進行濾波,第二個pass再使用水平方向的一維高斯核對影象進行濾波,得到最紅的目標影象。在實現中,我們還將利用影象縮放來進一步提高效能,並通過調整高斯濾波的應用次數來控制模糊程度。

shader**:

因為是雙pass進行渲染,可使用cginclude ....endcg來組織**,使**看起來更加整潔

//高斯模糊shader

shader "cangmu/common/posteffect/gauss blur"

// 宣告偏移的的距離

_blursize("blursize",float) = 1

}subshader

;struct v2f

;// 計算垂直y方向vertblurvertical的uv偏移

// 計算水平x方向vertblurhorizontal的uv偏移

fixed4 frag (v2f i) : sv_target

;// 當前畫素取樣乘以權重

fixed3 sum = tex2d(_maintex,i.uv[0]).rgb*weight[0];

for(int it = 1;it<3;it++)

return fixed4(sum,1);

}endcg

cull off zwrite off ztest always

pass

pass}}

由於高斯核的對稱性,只需要記錄三個權重,也就是**中的weight變數,首先宣告了各個鄰域畫素對應的權重weight,然後對中間的畫素進行取樣,並且乘以它的權重,根據它的對稱性在for語句中進行兩次迭代,每次迭代包括兩次紋理取樣,也就是五個畫素的取樣,並且把畫素值和權重相乘後的結果疊加到sum中。

c#指令碼部分:

using system.collections;

using system.collections.generic;

using unityengine;

public class cangmugaussblur : postprocessingbase

graphics.blit(bufferrt0, dest);

//釋放快取

rendertexture.releasetemporary(bufferrt0);}}

在for語句中進行迭代,在迭代開始前,首先獲得臨時渲染紋理bufferrt0,並且將其設定成雙線性,並且把把src複製到bufferrt0,迭代過程中獲得臨時渲染紋理bufferrt1,執行第乙個pass時,輸入bufferrt0,輸出bufferrt1,然後把bufferrt0釋放出去,再把bufferrt1賦予bufferrt0,執行第二個pass,重複上面過程,迭代完成後將bufferrt0儲存成最終影象dest,顯示到螢幕上,並且將釋放快取。

高斯投影座標轉換正算引數

三個座標系是 大地座標系 空間直角座標系 平面直角座標系 經緯度轉到橢球面上再轉到平面上。轉換的方式 精確一點的有投影等 不同地區採用不同的橢球引數 高斯投影計算公式可以有多種 橢球引數 橢球長半徑 a 橢球短半徑 b 扁率 a b a,也有用f表示的習慣。第一偏心率 第二偏心率 為方便計算,很多公...

自然數拆分(計蒜客)

這題是一道遍歷 陣列的組合題。特點就是將可以組合的數存到陣列中,最後依次輸出其中的數。這題很用這種方法很巧,我一開始的想法是沒找到乙個就輸出乙個,但是那樣子沒法進行,因為如果某一條線路是錯的,最終無法得到那個數,之前的結果已經被輸出了。所以,這種用陣列保留結果的方法就很靈活。每次相加得得到得數將會保...

計蒜客一維座標的移動

在乙個長度為 nn 的座標軸上,蒜頭君想從 aa 點 移動到 bb 點。他的移動規則如下 向前一步,座標增加 11。向後一步,座標減少 11。跳躍一步,使得座標乘 22。蒜頭君不能移動到座標小於 00 或大於 nn 的位置。蒜頭想知道從 aa 點移動到 bb 點的最少步數是多少,你能幫他計算出來麼?...