高斯模糊 理論

2021-06-26 17:32:44 字數 3387 閱讀 2185

高斯分布函式可表示為乙個一維的函式g(x)

或者乙個二維的函式g(x,y)

在這些函式中, x和y代表了相對於原始中心點(center tap)畫素的偏移(pixel offsets)值。也就是說,他們距離中心多少畫素。這裡的center tap,通常翻譯為「中心抽頭」,它在電學中的概念是:在整個次級線圈的中心拉出的一段導線上,它相對於另外兩邊的抽頭電壓居中,而為0,兩邊的電壓就是 一正一負。在這裡,我們也可以做相似的理解。即,它表示,以某個畫素為中心進行取樣,假設它的座標為(x,y),那麼周圍四個點的座標就是(x-1,y) (x+1,y)(x,y-1)(x,y+1)。對於整個分布來說,我們也可以用乙個平均引數來實施位移,從而取代center tap的作用。但這樣的模糊不符合我們的要求,我們希望我們的分布是基於中心的。

函式中的σ,即「西格瑪」。在統計學中,它常用來表示「標準差」。高斯模糊的標準差,表示模糊的延伸距離。它的預設值一般設為1,你可以提高它,來獲得更強的效果。

函式中的e是尤拉數(euler's number),它的值一般取2.7。你可以到看看精確到小數點後10000位的e。

這個函式的結果,就是以x(在乙個方向上),或者(x,y)(在兩個方向上),為中心的加權(weight)值,或者說該點在多大程度上影響模糊後的畫素。

那麼,它能獲得什麼樣的結果呢?當σ 值取1時,我們可以得到:

g(0) = 0.3989422804

g(1) = g(-1) = 0.2419707245

g(2) = g(-2) = 0.0539909665

g(3) = g(-3) = 0.0044318484

......

這些結果有什麼意義呢?

當x = 0時,表示這一點就是原始中心點(center tap), 這個點需要保留0.39(39%)的顏色

當x = 1以及x = -1時, 即有乙個畫素的位移時, 這一點需要保留0.24的顏色值

當x = 2以及x = -2時, 即有兩個畫素的位移時, 這一點需要保留0.05的顏色值

......

我們可以進行任意次這樣的計算。 取樣越高,精度越高。

相信現在你已經大致了解高斯模糊的原理了。

- 實際應用 -

當然,理論只是基於理想環境下的計算。在一次bloom shader的測試中,我發現了兩個問題:

1、模糊後的畫面,其發光度和亮度大都比原始影象要低,畫面顯得很暗

2、上述的取樣點(tap)的標準差是隨意的嗎?或者說,它有什麼要求(或限制)?

以下各段,我將以一維高斯分布為例

首先解決明度問題。假設你有乙個全白的單通道取樣貼圖,那麼它所有的畫素值都為1。經過第一次(水平方向)的高斯模糊運算之後,每個畫素的值的總和,是所有高斯取樣的加權總合。對於乙個5 × 5的分布,標準差為1時,有:

σhblur = g(0) + g(-1) + g(1) + g(-2) + g(2)

即σhblur = 0.9908656625

看起來似乎是正確的,其實不然。為了使明度不變,這個結果必須絕對是1。

基於此結果,在第二次運算後,它的值進一步下降為:σhvblur = 0.9818147611

這就是說,我們必須增強加權值,通過確定的乙個商,以取得正確的結果。答案非常簡單,缺少了這個商,我們當然不能得到1:σhblur^-1.

augfactor = 1 / σhblur

augfactor = 1.009218543

如果我們再用這個增量,乘以該點的加權以及兩個方向(水平、垂直)的運算,σhvblur的值就是1了!

其次是標準差的問題。我使用的解決方案並不太「官方」,但是它確實有效。我們假設乙個5 × 5的模糊必須有乙個其值為1的標準差。現在我們知道,在乙個5 × 5的分布中,距離中心最遠的取樣點,其加權值最小。其它尺寸的取樣分布(比如7× 7),計算出各點的加權值也有這一規律(函式已經有了,你可以簡單證明一下)。

要做的是,只調整標準差,以獲取最後的取樣點加權值,該值越接近這一結果越好。

σ = 1 -> g(2)aug = 0.054488685

σ = 1.745 -> g(3)aug = 0.054441945

σ = 2.7 -> g(4)aug = 0.054409483

這些都是我反覆除錯出的最接近的結果。所有這些權重增加,他們的和總是1。因此,尋找最佳標準差,最主要的是:盡可能多提取出模糊的取樣數,而不產生偏差。

- 一維復合運算 | 二維單一運算 -

為什麼會有一維和二維這兩個函式呢?因為我們有兩種選擇:

1、使用一維函式的兩次;一次橫向,然後(以橫向模糊的結果)再做一次垂直運算 ;

2、用二維函式,只需要一步就能完成。

你也許會問,既然有了二維函式,用它不就行了,何必要用一維函式進行兩次計算,那多麻煩呀!我的第一反應是,這也許是因為早期shader模型施加的一些限制。在做了更多的研究之後,我發現有乙個更好的解釋,來說明為什麼要分開運算。

假設n是模糊的線性尺寸(或者說在水平/垂直方向的取樣點數量),而p是整個畫面的畫素總數,那麼:

在一維函式中,你要做2np次紋理取樣

在二維函式中,你要做n²p次紋理取樣

這意味著,如果你對乙個512×512尺寸的影象做7×7取樣的模糊,一位維函式需要做367萬次搜尋,而如果用二維函式,那麼要完成這幅影象需要1284萬次,是前者的3.5倍!

把乙個二維座標的點分解為兩個一維的線性向量是完全可能的,因為高斯模糊是乙個可分割的卷積運算。具體的內容你可以到這裡看 看: /020874.html

所以,為了追求更快的速度、更高的效率,我寧可放棄二維函式。

- 執行!-

在hlsl中,執行一維高斯模糊最有效的方式是:

1、在頂點著色器(vertex shader)中,預先為不同的取樣點計算出紋理的座標偏移(coordinate offsets)。每個座標佔據乙個float2 ,所以我能夠用尺寸為4的float4陣列來實現9taps(x/y用乙個座標,z/w用另乙個),而原始中心點在乙個單獨的float2裡。

因為所有畫素取樣點的總和是奇數,所以最好的方法就是,讓中心點作為乙個單獨的座標,然後兩個陣列為正負兩個方向取樣點。

使用的「 w 」座標的免費資料,在ps_1_4及更早的版本中是不允許的,但無論如何,我已經放棄了這些舊版本的shader。

2、在畫素著色器(pixel shader)中,使用矩陣的累積樣本。如果需要,可以有乙個矩陣為正向取樣,另乙個負向取樣,雖然這在5 × 5的情況下是沒有必要的。這些矩陣有i行和j列,假設i表示我們正在累加的取樣數目,而j是目前我們正在處理的通道數目(通常是4:r,g,b,a,即 紅、綠、藍和透明通道)。一旦獲取了取樣,矩陣乘法之間的權向量和取樣矩陣將給予加權平均…就這麼簡單!使用乙個或兩個矩陣,經過運算,得到乙個或兩個向 量,這時需要把它們加在一起,然後新增到已經加權的原始中心點。

希望你沒被我弄暈。

還有不清楚的自己研究**吧,一竅不通的話也沒關係,我把這個shader放出來,只管用就行了

shader例項如下,希望它對你有幫助:

opencv學習(十) 高斯模糊理論知識

對photoshop高斯模糊濾鏡的演算法總結 python計算機視覺3 模糊,平滑,去噪 影象的模糊和平滑是同乙個層面的意思,平滑的過程就是乙個模糊的過程。而影象的去噪可以通過影象的模糊 平滑來實現 影象去噪還有其他的方法 那麼怎麼才能對一幅影象進行模糊平滑呢?影象的模糊平滑是對影象矩陣進行平均的過...

android高斯模糊

高斯模糊演算法介紹 高斯模糊就是將指定畫素變換為其與周邊畫素加權平均後的值,權重就是高斯分布函式計算出來的值。演算法介紹 一 通過自身的寫演算法 public static void gaussblur int data,int width,int height,int radius,float s...

高斯模糊演算法

正太分布,又稱高斯分布 正態分佈的前世今生 上 正態分佈的前世今生 下 通常,影象處理軟體會提供 模糊 blur 濾鏡,使產生模糊的效果。模糊 的演算法有很多種,其中有一種叫做 高斯模糊 gaussian blur 它將正態分佈 又名 高斯分布 用於影象處理。本文介紹 高斯模糊 的演算法,你會看到這...