Mari berbagi

Image Processing dengan vb.NET

February 25, 2008 · 2 Comments

“VB? Mo bikin virus yah”

Sungguh disayangkan dengan berkembangnya pandangan negatif masyarakat lokal terhadap bahasa Basic. Padahal, virus tidak lain hanya sebuah program dengan tujuan merusak -tidak perlu mengkaitkan dengan bahasa pemograman apa yg digunakan. Mungkin salah satu efek negatif dari kampanye “Mari menulis virus lewat vb, gampang koq” oleh programmer lokal.

Terlepas dari pandangan negatif masyarakat, vb dapat digunakan dalam memenuhi kebutuhan positif, salah satunya image processing. Image processing banyak digunakan dalam fotografi professional (koreksi warna), medis (filtering pada pencitraan X-Ray) maupun visual arts.

Salah satu contoh image processing yg populer adalah Adobe Photoshop. Meskipun kinerja program yg ditulis lewat vb.net tidak se-bagus Photoshop (penulis saat ini tetap menggunakan Photoshop sebagai primary image processor), vb.net menawarkan class image yg [mungkin] gampang digunakan dibandingkan bhasa pemograman lainnya. Smua efek dan filter dapat diciptakan lewat vb.net. Yang membatasi mungkin adalah pengetahuan aplikasi matematika diskrit pada image processing (mata kuliah kah)

Berikut contoh listing dari function PengaturanGamma


Private
Sub ImgGamma()
        frmParent.PictureBox1.Image = bmpSrc

Dim tmp2 As
New Bitmap(bmpSrc)

Dim tmdata As BitmapData = tmp2.LockBits(New Rectangle(0, 0, tmp2.Width, tmp2.Height), ImageLockMode.ReadWrite, tmp2.PixelFormat)

Me.Cursor = Cursors.AppStarting

Dim offset, y, x As
Integer
        frmParent.PictureBox1.Invalidate()

Dim red, green, blue, avg, dif As
Integer

Dim redGamma(256), greenGamma(256), blueGamma(256) As
Byte
        offset = tmdata.Stride - tmdata.Width * 4

If greenV < 1 Then greenV = 2

If redV < 2 Then redV = 2

If blueV < 2 Then blueV = 2
        x = 0

For x = 0 To 255
            redGamma(x) = CByte(Math.Min(255, CInt((255 * Math.Pow(x / 255, 10 / redV)) + 0.5)))
            greenGamma(x) = CByte(Math.Min(255, CInt((255 * Math.Pow(x / 255, 10 / greenV)) + 0.5)))
            blueGamma(x) = CByte(Math.Min(255, CInt((255 * Math.Pow(x / 255, 10 / blueV)) + 0.5)))

Next
        x = 0

For y = 0 To tmp2.Height - 1

For x = 0 To tmp2.Width - 1
                blue = Marshal.ReadByte(tmdata.Scan0, (tmdata.Stride * y) + (4 * x))
                green = Marshal.ReadByte(tmdata.Scan0, (tmdata.Stride * y) + (4 * x) + 1)
                red = Marshal.ReadByte(tmdata.Scan0, (tmdata.Stride * y) + (4 * x) + 2)
                red = redGamma(red)
                green = greenGamma(green)
                blue = blueGamma(blue)
                Marshal.WriteByte(tmdata.Scan0, offset, CByte(blue))
                Marshal.WriteByte(tmdata.Scan0, offset + 1, CByte(green))
                Marshal.WriteByte(tmdata.Scan0, offset + 2, CByte(red))
                Marshal.WriteByte(tmdata.Scan0, offset + 3, CByte(255))
                offset += 4

Next

Next
        tmp2.UnlockBits(tmdata)
        frmParent.PictureBox1.Image = tmp2
        frmParent.PictureBox1.Update()

Me.Cursor = Cursors.Default

End
Sub

Bingung? Begitu juga saya ketika menulisnya 3 tahun silam. Kode ini masih belum di optimasi, jadi masih dapat dipahami secara sekilas.

Berikut Penjelasannya (diusahakan sederhana mungkin)

Sebagaimana diketahui, gambar merupakan kumpulan dari pixel2 yg disusun seperi matriks (dari sisi geometri ruang manusia), namun ketika di memory, piksel2 tersebut disusun secara sequential (berurutan) layaknya datastream agar dapat diakses dengan cepat.

Secara matriks

ketika di memory (RAM)

(0,0)

(0,1)

(0,2)

1

2

3

(1,0)

(1,1)

(1,2)

4

5

6

(2,0)

(2,1)

(2,2)

7

8

9

Setiap piksel merupakan hasil pencampuran 3 warna primer (RGB). Dengan demikian, kita dapat mengasumsikan kL piksel merupakan array 1 dimensi dengan informasi 3 warna primer. Pada .Net, setiap piksel berisi informasi Blue, Green, Red dan Alpha (transparansi). Jadi, untuk mendapatkan satu piksel dari gambar, setidaknya ada 3 informasi yg musti diperoleh (Blue, Green dan Red).

Sebelumnya, data gambar di lock dulu di RAM supaya tidak diakses oleh proses lain.

Dim tmdata As BitmapData = tmp2.LockBits(New Rectangle(0, 0, tmp2.Width, tmp2.Height), ImageLockMode.ReadWrite, tmp2.PixelFormat)

Berikut fungsi membaca data (piksel yang ingin diolah) sebagai berikut:

For y = 0 To tmp2.Height - 1
For x = 0 To tmp2.Width - 1
blue = Marshal.ReadByte(tmdata.Scan0, (tmdata.Stride * y) + (4 * x))
green = Marshal.ReadByte(tmdata.Scan0, (tmdata.Stride * y) + (4 * x) + 1)
red = Marshal.ReadByte(tmdata.Scan0, (tmdata.Stride * y) + (4 * x) + 2)
Next
Next

Keyword “marshal” merupakan salah satu fitur baru vb.net (g ada d vb 6.0), dimana fungsinya sama dengan pointer pada C#. Dengan demikian, salah satu fitur yg dulu dibanggakan C (pointer, krn dapat menulis data langsung ke RAM) juga dimiliki oleh vb.net

Piksel yg telah didapatkan, ingin diolah bukan? Disinilah pengetahuan image processing (matematika diskrit) anda dibutuhkan.

Karena pada contoh merupakan koreksi gamma secara manual, maka scriptnya:

For x = 0 To 255
redGamma(x) = CByte(Math.Min(255, CInt((255 * Math.Pow(x / 255, 10 / redV)) + 0.5)))
greenGamma(x) = CByte(Math.Min(255, CInt((255 * Math.Pow(x / 255, 10 / greenV)) + 0.5)))
blueGamma(x) = CByte(Math.Min(255, CInt((255 * Math.Pow(x / 255, 10 / blueV)) + 0.5)))
Next
For y = 0 To tmp2.Height - 1
For x = 0 To tmp2.Width - 1
red = redGamma(red)
green = greenGamma(green)
blue = blueGamma(blue)
Next
Next

Setelah diolah, piksel tersebut dikirim lagi ke memory (RAM):

For y = 0 To tmp2.Height - 1
For x = 0 To tmp2.Width - 1
Marshal.WriteByte(tmdata.Scan0, offset, CByte(blue))
Marshal.WriteByte(tmdata.Scan0, offset + 1, CByte(green))
Marshal.WriteByte(tmdata.Scan0, offset + 2, CByte(red))
Marshal.WriteByte(tmdata.Scan0, offset + 3, CByte(255))
offset += 4
Next
Next

Setelah itu, gambarnya di unlock supaya dapat digunakan:

 

tmp2.UnlockBits(tmdata)

 

Demikian sedikit penjelasan ttg image processing dengan vb.net. Thread ini memang masih belum mencakup image processing secara keseluruhan, setidaknya menginspirasi kita untuk menulis aplikasi2 yg bermanfaat dan konstruktif.

Semoga bermanfaat;

Categories: Komputer · Programming

2 responses so far ↓

  • asaria // February 18, 2009 at 5:37 pm |

    Blog dan tulisan yang menarik pak.
    saya salah satu yang pernah memanfaatkan VB untuk image processing.

    salam kenal ya Pak.

    thanks.

    -ichee-

  • tata50 // February 22, 2009 at 1:31 pm |

    Makasi, Mbak :)

    Sekarang juga banyak tersedia class library (berisi filtering sederhana atau lebih) yg ditulis untuk C# dan VB.NET. Jadi ga perlu repot2 coding untuk hal2 simpel

    Salam kenal juga, mbak :)

You must be logged in to post a comment.