VB圖像處理之幾個常用濾鏡的實現(xiàn)

字號:

前面講到了二次線性插值的應(yīng)用。這一篇來給大家講一下關(guān)于銳化、柔化、擴(kuò)散、雕刻這幾個濾鏡的實現(xiàn)。
    一、銳化
     銳化的算法很簡單,就是比較相鄰的幾個像素,把當(dāng)前像素加上和周圍的像素的差就可以了。這里我給出一個示例:
    A B C D
    E F G H
    I J K L
    M N O P
     假設(shè)有一個圖片,4*4,共16個像素,分別用A--L來代表。我們先觀察這個圖片,只有中間的F,G,J,K這四個像素的“鄰居”是全的。
     為了簡便起見,我們只處理這4個像素,因為在實際的圖片中由于圖片的大小都很多像素組成,所以周圍的一圈像素不做處理不會影響到最終的效果。
     先計算差值:
    Delta= F - (A+B+C+E+G+I+J+K) / 8
    (A+B+C+E+G+I+J+K) / 8就是F周圍的像素的平均值,
     將這個平均值乘以一個系數(shù)再加到F上,就得到了一個新的F值:
    F=F + Delta * Alpha
     這個系數(shù)Alpha就是銳化度,改變這個系數(shù)就能得到不同的銳化效果。不過一般都是取得比較小的,如:0.3
     于是,我們只要使用兩個循環(huán)來遍歷整個圖片的像素值(去除邊界)就能得到一個銳化的效果了。
     但是大家或許會發(fā)現(xiàn)在處理后面幾個點的時候,前面的點的值已經(jīng)不是原來的值了,比如處理G的時候,需要用到F的值,而F則已經(jīng)被改變,并且F的改變又和G的值有關(guān)系,這樣就會變成一種循環(huán)引用。為了避免整個問題,這里給出一個改良的方法:
    A B C D
    E F G H
    I J K L
    M N O P
     我們從A點開始做,將差值計算方法改成:
    Delta= A - (B+E+F) / 3
    F=F + Delta * Alpha
     按照從左到右,從上到下的順序來掃描所有像素,這時在計算中就不會遇到已經(jīng)被處理過的像素了,并且因為減少了參與運算的像素,整個處理過程也得以加快。
     按照我們在《 VB圖像處理之像素的獲取和輸出 》中已經(jīng)得到的像素數(shù)組。我們可以這樣寫:
    Public Sub Sharp(Optional ByVal SharpDgree As Single = 0.3)
     Dim X As Long
     Dim Y As Long
     Dim Ix As Long
     Dim Iy As Long
     Dim Diff As Long
     Dim Diff1 As Long
     Dim Div1 As Single
     Dim Div2 As Single
     Dim Max As Long
     On Error GoTo ErrLine
     Max = 255
     Done = False
     TimeFilter = timeGetTime
     TemplateSize = 1
     Sensitivity = Sensitivity * 9
     Div1 = 1 + SharpDgree
     Div2 = -SharpDgree / 3
     For X = 0 To OutPutWid - 1
     For Y = 0 To OutPutHei -1
     RR = ColOut(0, X, Y) * Div1
     GG = ColOut(1, X, Y) * Div1
     BB = ColOut(2, X, Y) * Div1
     Ix = X + 1
     Iy = Y + 1
     R = ColOut(0, Ix, Iy)
     R = R + ColOut(0, X, Iy) + ColOut(0, Ix, Y)
     G = ColOut(1, Ix, Iy)
     G = G + ColOut(1, X, Iy) + ColOut(1, Ix, Y)
     B = ColOut(2, Ix, Iy)
     B = B + ColOut(2, X, Iy) + ColOut(2, Ix, Y)
     R = R * Div2
     G = G * Div2
     B = B * Div2
     RR = RR + R
     GG = GG + G
     BB = BB + B
     If RR < 0 Then RR = 0
     If RR > Max Then RR = Max
     If GG < 0 Then GG = 0
     If GG > Max Then GG = Max
     If BB < 0 Then BB = 0
     If BB > Max Then BB = Max
     ColOut(0, X, Y) = RR
     ColOut(1, X, Y) = GG
     ColOut(2, X, Y) = BB
     Next
     Next
     Done = True
     TimeFilter = timeGetTime - TimeFilter
     Exit Sub
    ErrLine:
     Done = True
     MsgBox Err.Description
    End Sub
     因為在計算新的像素的過程中會出現(xiàn)新的值大于255或小于0的情況,因此必須在計算完成后判斷。
     所用到的全局變量:
    Public TimeFilter As Long '用于記錄濾鏡處理所花費的時間
    Dim RR As Long '用于保存紅色分量
    Dim GG As Long '用于保存綠色分量
    Dim BB As Long '用于保存藍(lán)色分量
     原圖:
     銳化效果:
    二、柔化
     柔化的算法和銳化相近似,不過作用正好相反,就是把當(dāng)前點用周圍幾個點的平均值來代替。
    A B C D
    E F G H
    I J K L
    M N O P
     計算方法:
    F=(A+B+C+E+F+G+I+J+K) / 9
    G=(B+C+D+F+G+H+J+K+L) / 9
    ...
    ...
     具體的程序,我這里就不羅嗦了,大家只要把上面的程序小小改動一下就可以了。
     原圖:
     柔化效果:
    三、擴(kuò)散
     產(chǎn)生一種類似水彩畫的效果。
     算法很簡單,就是將當(dāng)前點用周圍的隨即的點來代替。
    A B C D
    E F G H
    I J K L
    M N O P
     F點可以從它周圍的A,B,C,E,G,I,J,K中任意選一點代替。
     G點可以從它周圍的B,C,D,F,H,J,K,L中任意選一點代替。
     J點可以從它周圍的E,F,G,I,K,M,N,O中任意選一點代替。
     K點可以從它周圍的F,G,H,J,L,N,O,P中任意選一點代替。
     至于選哪一點,可以用一個隨即數(shù)來選定。
     原圖:
     擴(kuò)散效果:
    四、雕刻
     將相鄰的兩個像素相減,得到的差加上127作為新的值
    A B C D
    E F G H
    I J K L
    M N O P
     如果我們按照從左向右的方向來“雕刻”
    A=B-A+127
    B=C-B+127
    C=D-C+127
    ...
     如果我們按照從上向下的方向來“雕刻”
    A=E-A+127
    B=F-B+127
    C=G-C+127
    ...
     當(dāng)然我們還可以從更多的方向來“雕刻”比如:向左下、右上、左上、右下...等等,一共8個可以選擇的方向。
     另外這個127,就是“雕刻”效果后的亮度。我們可以把雕刻方向和亮度都作為參數(shù)寫到過程中
    Public Sub Emboss(Optional EmbossDirection As Integer , Optional Lighteness As Integer)
    ...
     原圖:
     柔化效果:
     這幾個濾鏡的算法都比較簡單,很容易用VB來實現(xiàn)。