Gaussian blur returning value more than 255

350 views Asked by At

I'm trying to make a gaussian blur without using library. When I change the σ to 5, it results in error because the value is more than 255. I use this as reference. I know the equation is wrong, but I only see the values for reference. I use the equation from wiki.

when I use the same σ with the reference which is 5.5, I get the same result as the values on that link. But when I try to change it to 5, value got more than 255. maybe it's not just 5. I re-read my code over and over again. or maybe I messed up with the formula ? It should be below 255 right? s here's my code for the formula

 Public Function standard_deviation(sigma As Double)
    Dim standard_deviasi As Double = 1 / (2 * Math.PI * (sigma ^ 2))
    Return standard_deviasi
End Function

Public Function hitung_exponen(x As Integer, y As Integer, sigma As Double)
    'Dim exp_den As Double = 2 * (sigma ^ 2)
    'Dim a45roote2 As Double = Math.Pow(Math.Exp(x ^ 2 + y ^ 2), 1 / exp_den)
    'Dim exponen As Double = 1 / a45roote2
    Dim exponen As Double = Math.Exp(-((x ^ 2) + (y ^ 2) / 2 * sigma ^ 2))
    Return exponen
End Function

and here is the main func

        Dim standar_deviasi As Double = standard_deviation(sigma)
        kernelGauss(0, 0) = standar_deviasi * hitung_exponen(2, 2, sigma)
        kernelGauss(0, 1) = standar_deviasi * hitung_exponen(1, 2, sigma)
        kernelGauss(0, 2) = standar_deviasi * hitung_exponen(0, 2, sigma)
        kernelGauss(0, 3) = standar_deviasi * hitung_exponen(1, 2, sigma)
        kernelGauss(0, 4) = standar_deviasi * hitung_exponen(2, 2, sigma)

        kernelGauss(1, 0) = standar_deviasi * hitung_exponen(2, 1, sigma)
        kernelGauss(1, 1) = standar_deviasi * hitung_exponen(1, 1, sigma)
        kernelGauss(1, 2) = standar_deviasi * hitung_exponen(0, 1, sigma)
        kernelGauss(1, 3) = standar_deviasi * hitung_exponen(1, 1, sigma)
        kernelGauss(1, 4) = standar_deviasi * hitung_exponen(2, 1, sigma)

        kernelGauss(2, 0) = standar_deviasi * hitung_exponen(2, 0, sigma)
        kernelGauss(2, 1) = standar_deviasi * hitung_exponen(1, 0, sigma)
        kernelGauss(2, 2) = standar_deviasi * hitung_exponen(0, 0, sigma)
        kernelGauss(2, 3) = standar_deviasi * hitung_exponen(1, 0, sigma)
        kernelGauss(2, 4) = standar_deviasi * hitung_exponen(2, 0, sigma)

        kernelGauss(3, 0) = standar_deviasi * hitung_exponen(2, 1, sigma)
        kernelGauss(3, 1) = standar_deviasi * hitung_exponen(1, 1, sigma)
        kernelGauss(3, 2) = standar_deviasi * hitung_exponen(0, 1, sigma)
        kernelGauss(3, 3) = standar_deviasi * hitung_exponen(1, 1, sigma)
        kernelGauss(3, 4) = standar_deviasi * hitung_exponen(2, 1, sigma)

        kernelGauss(4, 0) = standar_deviasi * hitung_exponen(2, 2, sigma)
        kernelGauss(4, 1) = standar_deviasi * hitung_exponen(1, 2, sigma)
        kernelGauss(4, 2) = standar_deviasi * hitung_exponen(0, 2, sigma)
        kernelGauss(4, 3) = standar_deviasi * hitung_exponen(1, 2, sigma)
        kernelGauss(4, 4) = standar_deviasi * hitung_exponen(2, 2, sigma)


        'sums kernel
        Dim sums_kernel As Double = 0
        For rowkernel As Integer = 0 To kernelGauss.GetUpperBound(0)
            For columnkernel As Integer = 0 To kernelGauss.GetUpperBound(1)

                sums_kernel += kernelGauss(rowkernel , columnkernel )
            Next
        Next


        For rowkernel As Integer = 0 To kernelGauss.GetUpperBound(0)
            For columnkernel As Integer = 0 To kernelGauss.GetUpperBound(1)

                kernelGauss(rowkernel , kolomkernel) = kernelGauss(rowkernel , columnkernel ) / sums_kernel

            Next
        Next



        'start gauss
        For x As Integer = 2 To w_gambar - 2
            For y As Integer = 2 To h_gambar - 2



'1st row
                'channel R
                Dim barisPertamaKolom1_R As Double
                barisPertamaKolom1_R = map_pikselR(x - 2, y + 2) * kernelGauss(0, 0)
                Dim barisPertamaKolom2_R As Double
                barisPertamaKolom2_R = map_pikselR(x - 1, y + 2) * kernelGauss(0, 1)
                Dim barisPertamaKolom3_R As Double
                barisPertamaKolom3_R = map_pikselR(x, y + 2) * kernelGauss(0, 2)
                Dim barisPertamaKolom4_R As Double
                barisPertamaKolom4_R = map_pikselR(x + 1, y + 2) * kernelGauss(0, 3)
                Dim barisPertamaKolom5_R As Double
                barisPertamaKolom5_R = map_pikselR(x + 2, y + 2) * kernelGauss(0, 4)
                Dim barisPertama_R As Double
                barisPertama_R = barisPertamaKolom1_R + barisPertamaKolom2_R + barisPertamaKolom3_R + barisPertamaKolom4_R + barisPertamaKolom5_R

                'channel G
                Dim barisPertamaKolom1_G As Double
                barisPertamaKolom1_G = map_pikselR(x - 2, y + 2) * kernelGauss(0, 0)
                Dim barisPertamaKolom2_G As Double
                barisPertamaKolom2_G = map_pikselR(x - 1, y + 2) * kernelGauss(0, 1)
                Dim barisPertamaKolom3_G As Double
                barisPertamaKolom3_G = map_pikselR(x, y + 2) * kernelGauss(0, 2)
                Dim barisPertamaKolom4_G As Double
                barisPertamaKolom4_G = map_pikselR(x + 1, y + 2) * kernelGauss(0, 3)
                Dim barisPertamaKolom5_G As Double
                barisPertamaKolom5_G = map_pikselR(x + 2, y + 2) * kernelGauss(0, 4)
                Dim barisPertama_G As Double
                barisPertama_G = barisPertamaKolom1_G + barisPertamaKolom2_G + barisPertamaKolom3_G + barisPertamaKolom4_G + barisPertamaKolom5_G

                'channel B
                Dim barisPertamaKolom1_B As Double
                barisPertamaKolom1_B = map_pikselR(x - 2, y + 2) * kernelGauss(0, 0)
                Dim barisPertamaKolom2_B As Double
                barisPertamaKolom2_B = map_pikselR(x - 1, y + 2) * kernelGauss(0, 1)
                Dim barisPertamaKolom3_B As Double
                barisPertamaKolom3_B = map_pikselR(x, y + 2) * kernelGauss(0, 2)
                Dim barisPertamaKolom4_B As Double
                barisPertamaKolom4_B = map_pikselR(x + 1, y + 2) * kernelGauss(0, 3)
                Dim barisPertamaKolom5_B As Double
                barisPertamaKolom5_B = map_pikselR(x + 2, y + 2) * kernelGauss(0, 4)
                Dim barisPertama_B As Double
                barisPertama_B = barisPertamaKolom1_B + barisPertamaKolom2_B + barisPertamaKolom3_B + barisPertamaKolom4_B + barisPertamaKolom5_B



'2nd row

                'channel R
                Dim barisKeduaKolom1_R As Double
                barisKeduaKolom1_R = map_pikselR(x - 2, y + 1) * kernelGauss(1, 0)
                Dim barisKeduaKolom2_R As Double
                barisKeduaKolom2_R = map_pikselR(x - 1, y + 1) * kernelGauss(1, 1)
                Dim barisKeduaKolom3_R As Double
                barisKeduaKolom3_R = map_pikselR(x, y + 1) * kernelGauss(1, 2)
                Dim barisKeduaKolom4_R As Double
                barisKeduaKolom4_R = map_pikselR(x + 1, y + 1) * kernelGauss(1, 3)
                Dim barisKeduaKolom5_R As Double
                barisKeduaKolom5_R = map_pikselR(x + 2, y + 1) * kernelGauss(1, 4)
                Dim barisKedua_R As Double
                barisKedua_R = barisKeduaKolom1_R + barisKeduaKolom2_R + barisKeduaKolom3_R + barisKeduaKolom4_R + barisKeduaKolom5_R

                'channel G
                Dim barisKeduaKolom1_G As Double
                barisKeduaKolom1_G = map_pikselR(x - 2, y + 1) * kernelGauss(1, 0)
                Dim barisKeduaKolom2_G As Double
                barisKeduaKolom2_G = map_pikselR(x - 1, y + 1) * kernelGauss(1, 1)
                Dim barisKeduaKolom3_G As Double
                barisKeduaKolom3_G = map_pikselR(x, y + 1) * kernelGauss(1, 2)
                Dim barisKeduaKolom4_G As Double
                barisKeduaKolom4_G = map_pikselR(x + 1, y + 1) * kernelGauss(1, 3)
                Dim barisKeduaKolom5_G As Double
                barisKeduaKolom5_G = map_pikselR(x + 2, y + 1) * kernelGauss(1, 4)
                Dim barisKedua_G As Double
                barisKedua_G = barisKeduaKolom1_G + barisKeduaKolom2_G + barisKeduaKolom3_G + barisKeduaKolom4_G + barisKeduaKolom5_G

                'channel B
                Dim barisKeduaKolom1_B As Double
                barisKeduaKolom1_B = map_pikselR(x - 2, y + 1) * kernelGauss(1, 0)
                Dim barisKeduaKolom2_B As Double
                barisKeduaKolom2_B = map_pikselR(x - 1, y + 1) * kernelGauss(1, 1)
                Dim barisKeduaKolom3_B As Double
                barisKeduaKolom3_B = map_pikselR(x, y + 1) * kernelGauss(1, 2)
                Dim barisKeduaKolom4_B As Double
                barisKeduaKolom4_B = map_pikselR(x + 1, y + 1) * kernelGauss(1, 3)
                Dim barisKeduaKolom5_B As Double
                barisKeduaKolom5_B = map_pikselR(x + 2, y + 1) * kernelGauss(1, 4)
                Dim barisKedua_B As Double
                barisKedua_B = barisKeduaKolom1_B + barisKeduaKolom2_B + barisKeduaKolom3_B + barisKeduaKolom4_B + barisKeduaKolom5_B

'3rd row

                'channel R
                Dim barisKetigaKolom1_R As Double
                barisKetigaKolom1_R = map_pikselR(x - 2, y) * kernelGauss(2, 0)
                Dim barisKetigaKolom2_R As Double
                barisKetigaKolom2_R = map_pikselR(x - 1, y) * kernelGauss(2, 1)
                Dim barisKetigaKolom3_R As Double
                barisKetigaKolom3_R = map_pikselR(x, y) * kernelGauss(2, 2)
                Dim barisKetigaKolom4_R As Double
                barisKetigaKolom4_R = map_pikselR(x + 1, y) * kernelGauss(2, 3)
                Dim barisKetigaKolom5_R As Double
                barisKetigaKolom5_R = map_pikselR(x + 2, y) * kernelGauss(2, 4)
                Dim barisKetiga_R As Double
                barisKetiga_R = barisKetigaKolom1_R + barisKetigaKolom2_R + barisKetigaKolom3_R + barisKetigaKolom4_R + barisKetigaKolom5_R

                'channel G
                Dim barisKetigaKolom1_G As Double
                barisKetigaKolom1_G = map_pikselR(x - 2, y) * kernelGauss(2, 0)
                Dim barisKetigaKolom2_G As Double
                barisKetigaKolom2_G = map_pikselR(x - 1, y) * kernelGauss(2, 1)
                Dim barisKetigaKolom3_G As Double
                barisKetigaKolom3_G = map_pikselR(x, y) * kernelGauss(2, 2)
                Dim barisKetigaKolom4_G As Double
                barisKetigaKolom4_G = map_pikselR(x + 1, y) * kernelGauss(2, 3)
                Dim barisKetigaKolom5_G As Double
                barisKetigaKolom5_G = map_pikselR(x + 2, y) * kernelGauss(2, 4)
                Dim barisKetiga_G As Double
                barisKetiga_G = barisKetigaKolom1_G + barisKetigaKolom2_G + barisKetigaKolom3_G + barisKetigaKolom4_G + barisKetigaKolom5_G

                'channel B
                Dim barisKetigaKolom1_B As Double
                barisKetigaKolom1_B = map_pikselR(x - 2, y) * kernelGauss(2, 0)
                Dim barisKetigaKolom2_B As Double
                barisKetigaKolom2_B = map_pikselR(x - 1, y) * kernelGauss(2, 1)
                Dim barisKetigaKolom3_B As Double
                barisKetigaKolom3_B = map_pikselR(x, y) * kernelGauss(2, 2)
                Dim barisKetigaKolom4_B As Double
                barisKetigaKolom4_B = map_pikselR(x + 1, y) * kernelGauss(2, 3)
                Dim barisKetigaKolom5_B As Double
                barisKetigaKolom5_B = map_pikselR(x + 2, y) * kernelGauss(2, 4)
                Dim barisKetiga_B As Double
                barisKetiga_B = barisKetigaKolom1_B + barisKetigaKolom2_B + barisKetigaKolom3_B + barisKetigaKolom4_B + barisKetigaKolom5_B

'4th row
                'channel R
                Dim barisKeempatKolom1_R As Double
                barisKeempatKolom1_R = map_pikselR(x - 2, y + 1) * kernelGauss(3, 0)
                Dim barisKeempatKolom2_R As Double
                barisKeempatKolom2_R = map_pikselR(x - 1, y + 1) * kernelGauss(3, 1)
                Dim barisKeempatKolom3_R As Double
                barisKeempatKolom3_R = map_pikselR(x, y + 1) * kernelGauss(3, 2)
                Dim barisKeempatKolom4_R As Double
                barisKeempatKolom4_R = map_pikselR(x + 1, y + 1) * kernelGauss(3, 3)
                Dim barisKeempatKolom5_R As Double
                barisKeempatKolom5_R = map_pikselR(x + 2, y + 1) * kernelGauss(3, 4)
                Dim barisKeempat_R As Double
                barisKeempat_R = barisKeempatKolom1_R + barisKeempatKolom2_R + barisKeempatKolom3_R + barisKeempatKolom4_R + barisKeempatKolom5_R

                'channel G
                Dim barisKeempatKolom1_G As Double
                barisKeempatKolom1_G = map_pikselR(x - 2, y + 1) * kernelGauss(3, 0)
                Dim barisKeempatKolom2_G As Double
                barisKeempatKolom2_G = map_pikselR(x - 1, y + 1) * kernelGauss(3, 1)
                Dim barisKeempatKolom3_G As Double
                barisKeempatKolom3_G = map_pikselR(x, y + 1) * kernelGauss(3, 2)
                Dim barisKeempatKolom4_G As Double
                barisKeempatKolom4_G = map_pikselR(x + 1, y + 1) * kernelGauss(3, 3)
                Dim barisKeempatKolom5_G As Double
                barisKeempatKolom5_G = map_pikselR(x + 2, y + 1) * kernelGauss(3, 4)
                Dim barisKeempat_G As Double
                barisKeempat_G = barisKeempatKolom1_G + barisKeempatKolom2_G + barisKeempatKolom3_G + barisKeempatKolom4_G + barisKeempatKolom5_G

                'channel B
                Dim barisKeempatKolom1_B As Double
                barisKeempatKolom1_B = map_pikselR(x - 2, y + 1) * kernelGauss(3, 0)
                Dim barisKeempatKolom2_B As Double
                barisKeempatKolom2_B = map_pikselR(x - 1, y + 1) * kernelGauss(3, 1)
                Dim barisKeempatKolom3_B As Double
                barisKeempatKolom3_B = map_pikselR(x, y + 1) * kernelGauss(3, 2)
                Dim barisKeempatKolom4_B As Double
                barisKeempatKolom4_B = map_pikselR(x + 1, y + 1) * kernelGauss(3, 3)
                Dim barisKeempatKolom5_B As Double
                barisKeempatKolom5_B = map_pikselR(x + 2, y + 1) * kernelGauss(3, 4)
                Dim barisKeempat_B As Double
                barisKeempat_B = barisKeempatKolom1_B + barisKeempatKolom2_B + barisKeempatKolom3_B + barisKeempatKolom4_B + barisKeempatKolom5_B

'5th row
                'channel R
                Dim barisKelimaKolom1_R As Double
                barisKelimaKolom1_R = map_pikselR(x - 2, y + 2) * kernelGauss(4, 0)
                Dim barisKelimaKolom2_R As Double
                barisKelimaKolom2_R = map_pikselR(x - 1, y + 2) * kernelGauss(4, 1)
                Dim barisKelimaKolom3_R As Double
                barisKelimaKolom3_R = map_pikselR(x, y + 2) * kernelGauss(4, 2)
                Dim barisKelimaKolom4_R As Double
                barisKelimaKolom4_R = map_pikselR(x + 1, y + 2) * kernelGauss(4, 3)
                Dim barisKelimaKolom5_R As Double
                barisKelimaKolom5_R = map_pikselR(x + 2, y + 2) * kernelGauss(4, 4)
                Dim barisKelima_R As Double
                barisKelima_R = barisKelimaKolom1_R + barisKelimaKolom2_R + barisKelimaKolom3_R + barisKelimaKolom4_R + barisKelimaKolom5_R

                'channel G
                Dim barisKelimaKolom1_G As Double
                barisKelimaKolom1_G = map_pikselR(x - 2, y + 2) * kernelGauss(4, 0)
                Dim barisKelimaKolom2_G As Double
                barisKelimaKolom2_G = map_pikselR(x - 1, y + 2) * kernelGauss(4, 1)
                Dim barisKelimaKolom3_G As Double
                barisKelimaKolom3_G = map_pikselR(x, y + 2) * kernelGauss(4, 2)
                Dim barisKelimaKolom4_G As Double
                barisKelimaKolom4_G = map_pikselR(x + 1, y + 2) * kernelGauss(4, 3)
                Dim barisKelimaKolom5_G As Double
                barisKelimaKolom5_G = map_pikselR(x + 2, y + 2) * kernelGauss(4, 4)
                Dim barisKelima_G As Double
                barisKelima_G = barisKelimaKolom1_G + barisKelimaKolom2_G + barisKelimaKolom3_G + barisKelimaKolom4_G + barisKelimaKolom5_G

                'channel B
                Dim barisKelimaKolom1_B As Double
                barisKelimaKolom1_B = map_pikselR(x - 2, y + 2) * kernelGauss(4, 0)
                Dim barisKelimaKolom2_B As Double
                barisKelimaKolom2_B = map_pikselR(x - 1, y + 2) * kernelGauss(4, 1)
                Dim barisKelimaKolom3_B As Double
                barisKelimaKolom3_B = map_pikselR(x, y + 2) * kernelGauss(4, 2)
                Dim barisKelimaKolom4_B As Double
                barisKelimaKolom4_B = map_pikselR(x + 1, y + 2) * kernelGauss(4, 3)
                Dim barisKelimaKolom5_B As Double
                barisKelimaKolom5_B = map_pikselR(x + 2, y + 2) * kernelGauss(4, 4)
                Dim barisKelima_B As Double
                barisKelima_B = barisKelimaKolom1_B + barisKelimaKolom2_B + barisKelimaKolom3_B + barisKelimaKolom4_B + barisKelimaKolom5_B


                'sums channel R
                Dim sums_R As Double = barisPertama_R + barisKedua_R + barisKetiga_R + barisKeempat_R + barisKelima_R
                sums_R = Round(sums_R )
                'sums channel G
                Dim sums_G As Double = barisPertama_G + barisKedua_G + barisKetiga_G + barisKeempat_G + barisKelima_G
                sums_G = Round(sums_G )
                'sums channel B
                Dim sums_B As Double = barisPertama_B + barisKedua_B + barisKetiga_B + barisKeempat_B + barisKelima_B
                sums_B = Round(sums_B )

                If sums_R > 255 Then
                    Console.WriteLine("koord " & x.ToString & "," & y.ToString & " R= " & sums_R.ToString)
                ElseIf sums_G > 255 Then
                    Console.WriteLine("koord " & x.ToString & "," & y.ToString & " G= " & sums_G.ToString)
                ElseIf sums_B > 255 Then
                    Console.WriteLine("koord " & x.ToString & "," & y.ToString & " B= " & sums_B.ToString)

                End If

                map_baruR(x, y) = sums_R
                map_baruG(x, y) = sums_G
                map_baruB(x, y) = sums_B

            Next
        Next

update : I just realize this, when I use a grayscale image, it works. but when I use a full color image on kernel 5x5 , it turns the image into a grayscale. I realize that only the red channel got more than 255.

1

There are 1 answers

3
Peter On

Well you made gausian quite complex. in its most simple form you do 1/273 times a summed image kernel where each pixel is multiplied by these values : enter image description here

If you want to you can use other numbers, but be sure that the 1/p is so that p is the total sum of multipliers.

PS i think its faster to just hardcode those multipliers instead of doing exponential math and PI