Friday 20 November 2015

Pengolahan Citra 5: Kontras & Histogram

Pada pembahasan pertemuan 5 ini akan dibahas mengenai bagaimana cara melakukan kontras dan histogram. Pembahasan mengenai kontras dan histogram akan dibahas satu per satu.

Kontras:
Kontras merupakan tingkat penyebaran piksel-piksel ke dalam intensitas warna. Kontras yang rendah dikarenakan kurangnya pencahayaan mengakibatkan intensitas warna berkumpul di tengah skala intensitas. Sedangkan kontras tinggi dikarenakan terlalu banyak pencahayaan mengakibatkan intensitas warna berkumpul di awal dan akhir skala intensitas, sedangkan di tengah sangat kecil frekuensinya.

Suatu kontras dikatakan normal (tidak tinggi dan tidak rendah) apabila penyebaran piksel tidak terlalu ekstrem. Operasi kontras dilakukan dengan cara stretching pada histogram.


Fungsi kontras yang kita gunakan adalah sebagai berikut:


Histogram:
Proses histogram dilakukan untuk menunjukkan frekuensi kemunculan setiap gradasi warna. Pada histogram, terdapat dua buah sumbu yang perlu diperhatikan yaitu sumbu x dan sumbu y. berikut ini keterangan yang menunjukkan sumbu x dan sumbu y:

Sumbu X: Menunjukkan nilai intensitas
Sumbu Y: Frekuensi kemunculan(banyaknya piksel dengan intensitas x) pada citra atau kebalikannya tergantung kebutuhan.

Semakin besar bit pada sistem yang digunakan, semakin banyak variasi intensitasnya, semakin panjang pula sumbu yang mewakili intensitas nya. Pada citra grayscale, yang digunakan adalah derajat keabu-abuannya. Sedangkan pada citra RGB yang dipergunakan adalah intensitas masing-masing channel.

Manfaat dari histogram yang kita pelajari ini adalah sebagai berikut:
  • Indikasi visual untuk menentukan skala intensitas yang tepat, sehingga diperoleh kualitas citra yang diinginkan.
  • Pemilihan batas ambang (tresshold). Tresshold merupakan nilai piksel yang memenuhi syarat ambang batas yang dipetakan ke suatu nilai yang dikehendaki.
  • Pada computer vision dapat dimanfaatkan sebagai feature.


Sekian penjelasan singkat mengenai kontras dan histogram. Berikutnya akan dibahas mengenai penerapan konsep kontras dan histogram pada pembuatan program pengolahan citra.

Pada pembahasan kali ini akan sedikit berbeda dari pembahasn-pembahasan sebelumnya. Perbedaan yang dimaksud adalah cara mengambil citra yang biasa kita lakukan di awal penulisan program. Pada pembahasan ini akan dijelaskan bagaimana mengambil suatu citra menggunakan parameter. Bagaimana cara penerapan parameter tersebut, akan dijelaskan pada pembahasan ini. Berikut ini adalah source code program kontras dan histogram serta penjelasan mengenai pengambilan citra menggunakan parameter:

Penggunaan parameter:

<html>
<head>
<title>Contrast</title>
</head>
<body>
<applet code=Kontras.class width=1500 height=500>
<PARAM NAME = filegambar VALUE="gambar.jpg">
<PARAM NAME = parp VALUE=190>
<PARAM NAME = parg VALUE=3>
</applet>
</body>
</html>

Dari contoh format html di atas, untuk pembahasan ini digunakan tetapan untuk pembuatan program nantinya dengan nilai P=190 dan nilai G=3. Setelah kita membuat tampilan html seperti di atas, pada bagian pengambilan citra kita ganti juga cara pengambilannya menjadi seperti ini:
Untuk pengambilan parameter, gunakan methot getParameter();

img=this.getImage(this.getDocumentBase(),getParameter("filegambar"));
parG = Integer.parseInt(getParameter("parg"));
parP = Integer.parseInt(getParameter("parp"));

kita sudah mendapatkan cara membuat parameter dan cara mengambil citra dengan parameter tersebut. Berikut ini adalah keseluruhan source code program kontras dan histogram:


Tampilan web:


Proses compile:


Memanggil appletviewer:


Hasil Tampilannya adalah sebagai berikut:


Demikian pembahasan mengenai kontras dan histogram pada pembahasan ke-5 dari pengolahan citra.






Pengolahan Citra 4: Brightness, Invers, Kuantisasi Biner

Pembahasan Pertemuan 4

Pada pembahasan pertemuan 4 ini akan dibahas mengenai bagaimana cara brightness (mencerahkan dan menggelapkan citra), Invers (negasi), dan kuantisasi biner. Pembahasan dari ketiga jenis pengolahan citra tersebut akan dibahas satu per satu.

Brightness:
Mendengar kata brightness, yang terlintas di dalam pikiran kita akan langsung berpikiran mengenai terang dan gelap pada suatu image / citra. Dalam operasi brightness ini, kita akan membuat citra semakin terang atau pun semakin gelap. Dalam operasi brightness, ada beberapa point yang perlu kita ingat dalam membuat program untuk pengolahan citra, antara lain:
  • Intensitas:


  • Citra Grayscale:


  • Citra True Color:


  • Nilai Kecerahan (k): Nilai maksimum dan nilai minimum dari K tergantung dari jumlah bit.

Invers (Negasi):

Tujuan dari penggunaan operasi invers ini adalah untuk membuat citra negative. Seperti apa citra negative nantinya akan kita coba pada pembuatan program. Untuk membuat citra menjadi negative dibutuhkan rumus perhitungan yang diterapkan dalam pemrograman. Berikut ini adalah rumus yang diperlukan:


Dari rumus di atas ini yang dimaksud dengan fmaksimum adalah nilai tertinggi dalam bit warna. Misalnya untuk citra grayscale 8 bit, maka fmaksimumnya adalah 255, untuk citra grayscale 7 bit fmaksimumnya adalah 127




Untuk membuat citra menjadi negative, maka kita bias menggunakan teori dan rumus di atas untuk diimplementasikan ke dalam program pengolahan citra yang akan kita buat.

Kuantisasi biner:

Kuantisasi warna dalam bitmap untuk representasi citra dapat dibagi ke dalam tiga kelompok, yaitu:
  1. Citra biner
  2. Citra grayscale
  3. Citra warna

Untuk kuantisasi citra biner, setiap pixel hanya mempunyai 2 kemungkinan warna, yaitu hitam atau putih. Hitam dikuatisasi dengan 0 dan putih dikuantisasi dengan 1. Memori yang dibutuhkan untuk menyimpan satu pixel adalah satu bit. Berikut ini contoh penggambaran proses kuantisasi citra warna 8 bit ke dalam citra 2 bit:


Citra warna yang masing-masing warna red, green, dan blue memiliki 8 bit (0-255) di kuantisasi menjadi warna 1 bit (0-1), maka akan menghasilkan hanya 2 warna yaitu hitam dan putih seperti contoh analogi di atas. Pada saat kita melakukan kuantisasi dari citra warna, maka yang kita lakukan adalah membuat citra menjadi grayscale terlebih dahulu, selanjutnya baru kita lakukan kuantisasi seperti pada contoh analogi gambaran proses di atas.

Sekarang, langsung saja kita lanjut ke pembahasan pembuatan program untuk mengolah citra dan memberi efek brightness, invers, dan kuatisasi biner. Berikut ini adalah source code dari program yang dibuat:



Dari source code di atas, terlihat bahwa untuk membuat citra warna atau grayscale menjadi cerah atau gelap, kita hanya perlu menambahkan bitmap dari citra tersebut dengan nilai kecerahan (K). Namun, ada hal yang perlu diperhatikan, kita perlu menambahkan seleksi (if-else) saat menambahkan bitmap citra dengan K. hal itu harus kita lakukan untuk menjaga agar citra yang dijumlahkan dengan K tidah melebihi 255 atau kurang dari 0 untuk setiap pixel dalam bitmap citra. Jika setelah dijumlahkan dengan K menghasilkan angka yang lebih dari 255, maka pixel tersebut kita set dengan nilai tertinggi yaitu 255. Sama halnya dengan menggelapkan citra. Jika menghasilkan angka kurang dari 0 (misalnya: -50), maka pixel tersebut kita tetapkan dengan nilai 0. Untuk membuat invers/megasi dari citra, maka kita lakukan pengurangan nilai batas tertinggi dikurangi dengan bitmap citra, misalnya: 255-50 , nilai 255 adalah batas tertinggi, sedangkan nilai 50 adalah nilai pixel yang ada. Untuk membuat kuantisasi biner, diperlukan juga statement seleksi (if-else). Untuk cara melakukan kuantisasi biner, dapat kita lihat pada source code di atas. Berikut ini adalah tampilan Brightness.html untuk menampilkan citra dalam applet:


Proses compile:


Proses menampilkan dengan appletviewer:


Tampilannya adalah sebagai berikut:


Demikian pembahasan mengenai pengolahan citra untuk Brightness, Invers/Negasi, dan Kuantisasi Biner yang telah dibahas pada pembahasan ini.










Thursday 19 November 2015

Pengolahan Citra 3: Bitmap

Pada pertemuan 3 ini kita akan mempelajari mengenai Bitmap. Jika sebelumnya pada pertemuan 1 dan 2 kita mempelajari pengolahan citra dengan pixel, maka sekarang ini kita akan mempelajari yang namanya Bitmap.


Pada pertemuan yang lalu, cara kita mengolah citra adalah sebagai berikut:


Kita melakukan grab pixel dari image agar bisa kita proses dalam pemrograman dengan nilai integer. Pada saat proses, kita pisahkan antara R, G, dan B.  Hasil grab pixel tersebut ditampung dalam array integer 1 dimensi, pada pertemuan sebelumnya array itu kita beri nama pixels. Sampai pada proses ini, boleh langsung kita proses. Boleh dibuat grayscale, brightness, dibinerkan, atau yang lainnya. Setelah proses ini, kita bias tampilkan per pixel dengan fungsi drawLine, drawOval, atau drawRectangle.

Cara pada pertemuan kedua ini bisa kita gunakan namun dalam pertemuan 3 ini, kita akan menampilkan flip vertikal, flip horizontal, dan flip vertikal horizontal. Jika kita hanya menggunakan array 1 dimensi, kira-kira hal itu pasti cukup merepotkan kita karna harus mebalik-balikkan koordinat. Mengapa kita harus sibuk mengatur koordinat? Karena kita bermain dengan satu canvas, berbeda halnya jika kita menggunakan Delphi. Langsung kita bahas mengenai bitmap.

Jika kita mempunyai array 2 dimensi, kita lihat gambar yang kita miliki. Gambar/citra yang kita miliki itu sebenarnya adalah gambar 2 dimensi. Pada array 2 dimensi, harus ada pixel baris dan kolom. Dalam array 2 dimensi, diperbolehkan jika dimensi pertama kita anggap sebagai baris, dimensi kedua kita anggap sebagai kolom atau sebaliknya. Nilai pixel disimpan dalam setiap cell pada array 2 dimensi. Yang membedakan saat kita menggunakan array 1 dimensi adalah pada array 2 dimensi, setiap R, G dan B dibuatkan masing-masing satu bitmap array agar nantinya mudah saat ingin dipakai. Ambil setiap R ke dalam cell yang ada dalam bitmap R, begitu juga dengan G dan B. selama pembelajaran ini, setiap pencampuran Bitmap R, G, dan B kita siapkan array 2 dimensi untuk penampung citra warna yang dihasilkan dari pencampuran bitmap R, G, dan B. setelah kita mendapatkan ketiga bitmap dari R, G, dan B, jika kita ingin membuat citra itu jadi flip vertikal kita hanya perlu mengatur menampilkan setiap cell pada bitmap hasil yang telah disiapkan. Yang diperlukan di sini adalah teknik pemrograman untuk looping. Di sini kita menggunakan looping for di dalam looping for. Untuk lebih jelasnya, nanti akan kita bahas dalam source code praktikum pertemuan 3 ini. Berikut ini adalah gambar analogi untuk menempatkan pixel dalam cell setiap bitmap R, G, dan B ke dalam bitmap hasil:

Bitmap RGB diproses menghasilkan Bitmap Vertikal:



Bitmap RGB diproses menghasilkan Bitmap Horizontal:


Bitmap RGB diproses menghasilkan Bitmap Vertikal-Horizontal:



Dari gambaran di atas, untuk pemula, kita yang baru belajar, tidak ada salahnya sedikit lebih boros memori yaitu dengan menggunakan 12 array untuk menampung array Red, Green, dan Blue, lalu array Bitmap Vertikal Red, Green, dan Blue, array Bitmap Horizontal Red, Green, dan Blue, dan array Bitmap Vertikal-Horizontal Red, Green, dan Blue. Lebih jelasnya seperti apa kita memprogram, nanti akan dijelaskan pada saat pembuatan source program.

Berikut ini adalah source program untuk membuat Bitmap:





Pada source code di atas, pada awal penulisan program kita lihat ada bagian deklarasi aray untuk bitmap. Total kita deklarasikan 12 array 2 dimensi untuk bitmap RGB, vertikal RGB, horizontal RGB, dan vertikal-horizontal RGB. Selanjutnya di akhir penulisan program yaitu pada saat kita akan menampilkan hasil citranya, dapat kita lihat di sana terdapat cara 1 dan cara 2 yang dibuat sebagai command. Array 2 dimensi yang kita buat sebanyak 12 array akan kita gunakan jika kita ingin menggunakan cara 1. Artinya ke-12 array tersebut tidak berguna jika kita gunakan cara ke-2.

Kita bahas sedikit mengenai cara pembuatan source code di atas:

Mengambil informasi lebar dan tinggi citra:

lebar = img.getWidth(this);
tinggi = img.getHeight(this);

Selanjutnya, kita sediakan array 2 dimensi untuk bitmap dengan format seperti berikut:

int [ ][ ] bitmapR = new int[lebar][tinggi];

Untuk mengisi Bitmap:

  for(int j=0;j<tinggi;j++)
    {
      for(int i=0;i<lebar;i++)
      {
        warna = pixels[j*lebar+i];
        red = (warna >> 16) & 0xff;
        bitmapR[i][j] = red;
      }
    }

Berikutnya akan kita bahas mengenai 2 cara yang ada dalam source code di atas. 


Source code di atas ini dapat kita lihat kita menggunakan 12 array 2 dimendi yang telah kita deklarasikan di awal program. Untuk menjalankan cara 1 ini diperlukan pengisian nilai i dan nilai j. Cara pengisiannya adalah seperti berikut ini:


Jadi, sebelum kita gunakan cara 1 sebagai penampilan citra, kita harus menentukan letak pixel yang ada dalam setiap cell dari bitmap-bitmap yang ada seperti potongan source code di atas ini.

Sedangkan, untuk cara kedua kita tidak perlu mengisikan looping untuk pindah ke bitmap-bitmap vertikal, horizontal, ataupun vertikal horizontal. Kita hanya menggunakan 3 bitmap yaitu Red, Green dan Blue yang kita gunakan sebagai penampung untuk masing-masing warna. Maka dari itu, kita tidak perlu menggunakan sampai 12 array. Kita hanya perlu menggunakan 3 array yang sudah pasti harus ada. Maka looping untuk mengisi tampilan citra dengan cara kedua adalah sebagai berikut:


Dapat kita lihat bahwa baik normal, vertikal, horizontal, maupun vertikal-horizontal, kita menggunakan bitmap yang sama yaitu bitmapRed untuk warna merah, bitmapGreen untuk warna hijau, dan bitmapBlue untuk warna biru. Yang perlu diubah di sini hanya parameter i dan j saja yang menentukan di cell mana pixel akan diletakkan. Penempatan parameter i dan j ini jika kita lihat sama saja dengan cara 1 saat kita mau mengisikan nilai bitmap vertikal, horizontal, dan vertikal-horizontal dari bitmapRed, bitmapGreen, dan bitmapBlue. Pada intinya, menggunakan cara 1 atau 2 akan sama saja, tidak akan berpengaruh pada tampilan.  Hanya saja, jika kita gunakan cara ke dua maka kita akan lebih menghemat memori yang akan digunakan untuk 9 array 2 dimensi yang kita gunakan untuk cara 1.

Berikutnya adalah source code untuk tampilan, yaitu source code untuk program html:


Compile file Bitmap.java:


Melihat tampilan:


Tampilannya:


Demikian pembahasan kali ini mengenai Bitmap pada Pengolahan Citra. 










Pengolahan Citra 2: Model Warna RGB

Pada pertemuan 2 ini kita akan mempelajari model warna RGB. Model warna yang dikenal ada tiga jenis yaitu RGB, CMYK, HIS/HSV/HSL. Untuk pengolahan citra, yang kita gunakan adalah model warna RGB. Pada pertemuan 1, kita menemukan beberapa fungsi seperti source code berikut ini:
  • img=this.getImage(this.getDocumentBase(), "Mickey0.jpg"); getImage kita gunakan untuk memindahkan informasi yang ada pada gambar Mickey0.jpg ke dalam variabel img.
  • lebar = img.getWidth(this); tinggi = img.getHeight(this); getWidth dan getHeight kita gunakan untuk memindahkan informasi lebar dan tinggi image ke dalam variabel lebar dan tinggi yang sudah dideklarasikan.
  •  g.setColor(new Color(red, green, blue)); setColor kita gunakan untuk memberi warna pada image yang akan kita olah.
  • g.drawString("Normal",  lebar+100,40);  drawString kita gunakan untuk menggambar tulisan. Pada kode tersebut artinya kita akan mencetak hasil berupa tulisan “Normal” tanpa tanda kutip.
  • g.drawLine(i+lebar+100,                   j+50, i+lebar+100, j+50); drawLine kita gunakan untuk menggambar image yang telah kita oleh.
  • g.drawOval(i+lebar+100+lebar+50,          j+50, 1,1); drawOval digunakan untuk menggambar image yang telah kita olah. Sama seperti drawLine.

Untuk melakukan pewarnaan, dalam pemrograman pengolahan citra satu warna kita gunakan 8 bit. Jadi untuk satu warna misalnya warna merah, maka disediakan 8 bit dengan nilai 0-255. Dalam java, untuk menampung warna disediakan 32 bit integer.untuk itu dalam praktikum ini kita menggunakan 3 warna, jadi hanya menggunakan 24 bit. Bagaimana cara kita memprogram warna? Dalam source code pada pertemuan 1 kita menemukan kode seperti red = (warna >> 16) & 0xff; maka penjelasannya adalah sebagai berikut:


blue = (warna) & 0xff; Tidak ada tanda pergeseran, karena warna biru memang sudah menempati 8 bit pertama seperti gambar di bawah ini:


Karna hanya ingin mengambil warna biru, maka untuk warna lain kita lakukan operasi AND. Kita akan melakukan AND dengan 0, maka dari itu ada kode 0xff.

green = (warna >> 8) & 0xff; Kita melakukan operasi pergeseran (>>) karena untuk satu warna kita hanya perlu 8 bit, maka warna hijau yang berada setelah biru harus kita geser sebanyak 8 bit menggantikan warna biru. Berikut contoh penggambarannya:


Setelah melakukan operasi AND dengan 0 untuk warna selain warna hijau, maka di dapatlah warna hijau seperti gambar proses di atas.

red = (warna >> 16) & 0xff; Untuk mendapatkan warna merah, kita perlu menggeser 16 bit untuk menempati tempat posisi warna biru (8 bit pertama). Gambar prosesnya sebagai berikut:


Pada pertemuan 2 ini, kita akan membuat tiga tampilan. Langsung saja kita mulai pembahasan untuk membuat tampilan pertama, kita simpan dengan nama file ModelWarna.java, berikut adalah source programnya:





Source code tampilan web:


Proses compile:


Menampilkan dengan appletviewer:


Hasil tampilannya adalah sebagai berikut:


Tampilan kedua, berikut ini adalah source code untuk menampilkan tampilan kedua:




Source code tampilan web:



Proses compile:


Menampilkan dengan appletviewer:;


Hasil tampilannya adalah sebagai berikut:


Pada pengaturan tampilan kedua, kita hanya perlu memindahkan dua gambar terakhir pada tampilan pertama sehingga didapat tampilan seperti gambar di atas. Berikutnya adalah tampilan ketiga atau yang terakhir dari pertemuan kedua ini. Langsung saja kita masuk dalam pembahasan tampilan yang ketiga:

Tampilan ketiga, berikut ini source code untuk menampilkan tampilan ketiga:




Source code tampilan web:


Proses compile:


Menampilkan dengan appletviewer:


Hasil tampilannya adalah sebagai berikut:


Kita lihat dalam deretan gambar yang di atas dengan yang di bawah ada perbedaan pada warnanya, pada gambar berwarna merah terlihat jelas bahwa pada gambar di atas, kancing baju mickey tidak terlihat, tetapi di bagian yang bawah, kancing bajunya terlihat. Itulah kenapa jika kita lihat pada source code programnya kita menggunakan warna abu-abu. Jadi untuk deretan gamba yang di bawah kita isi dengan warna abu-abu di posisi setiap gambarnya, untuk grayscale, channel red, green, dan blue kita tidak menggunakan variabel red, green ataupun blue, tetapi semuanya kita gunakan variabel abuabu. Hanya untuk mengisi warna merah, maka variabel abuabu menempati posisi merah dan yang lain diisi dengan nilai 0, begitu juga halnya dengan warna green dan blue.

Sekian pembahasan pengolahan citra pada pertemuan kali ini mengenai Model Warna RGB.