Tuesday, June 22, 2010

Graythresh dan im2bw menggunakan CImg

Postingan saya saat ini aka mencoba menjabarkan sedikit codingan yang udah saya buat menggunakan library CImg. Dua fungsi yang akan dibahas yaitu graythresh dan im2bw. Nama kedua fungsi tersebut sama dengan nama fungsi yang ada di Matlab. Fungsinya juga dibuat persis dengan yang ada di Matlab. Seperti namanya im2bw adalah fungsi untuk mengubah image dari grayscale ke dalam bentuk biner dengan threshold tertentu. Threshold bisa ditentukan sesuka kita ataupun bisa ditentukan dengan menggunakan fungsi graythresh.
Algoritme untuk im2bw cukup sederhana yaitu jika nilai piksel (x,y) melebihi nilai threshold yang diberikan maka nilai piksel akan diubah menjadi 1, namu jika kurang dari/sama dengan threshold makan nilai piksel tersebut akan diset 0. Hasil dari im2bw ini merupakan image dengan format biner/logika. Tentunya jika kita men-display gambar hasil dari im2bw ini cuma akan terlihat gambar hitam-putih saja. Fungsi im2bw dengan bahasa C++ (CImg) kira-kira seperti berikut:
CImg<bool> Form1::im2bw(CImg<double> img, double thresh){
    double temp=255*thresh;
     cimg_forXY(img,x,y){
         if (img(x,y)>temp)
             img(x,y)=1;
         else
             img(x,y)=0;
     }
}
Parameter masukannya ada 2, yaitu:
1. CImg <double> img , ini adalah image yang mau kita ubah. Jika format image berupa float atau selain double, tinggal ganti aja formatnya didalam “<…>”.
2. thresh, ini threshold yang kita masukkan.
Parameter keluaranya tentu saja image dengan format biner. Tapi ga harus dengan format biner (bool), bisa juga format double atau float atau int.

Algoritme graythresh jika kita baca pada Help-nya Matlab, penentuan threshold-nya menggunakan metode Otsu. Threshold yang dihasilkan memiliki range 0-1. Fungsi graythresh dengan C++ yang saya buat kira-kira sebagai berikut: (ini saya otak-atik langsung dari fungsi graythresh di Matlab)
double Form1::graythresh(CImg<double> img){
    //deklarasi variable
    CImg<double> hist(256);
    double mu_t,nMax,nMean=0,level;int i;
    array<double>^ p=gcnew array <double>(256);
    array<double>^ q=gcnew array <double>(256);
    array<double>^ mu=gcnew array <double>(256);
    array<double>^ temp1=gcnew array <double>(256);
    array<double>^ omega=gcnew array <double>(256);
    array<double>^ temp2=gcnew array <double>(256);
    array<double>^ sigma=gcnew array <double>(256);

    //fungsi dari CImg untuk mendapatkan histogram dari image
    hist=img.get_histogram (256,0,255);               
    for (i=0;i<256;i++){
        p[i]=hist(i)/hist.sum();
    }
    for (i=0;i<256;i++){
        q[i]=p[i]*(i+1);
    }
    omega[0]=p[0]; mu[0]=q[0];
    for (i=1;i<256;i++){
        omega[i]=p[i]+omega[i-1];
        mu[i]=q[i]+mu[i-1];
    }
    mu_t=mu[255];
    for (i=0;i<256;i++){
        temp1[i]=square(omega[i]*mu_t-mu[i]);
        temp2[i]=omega[i]*(1-omega[i]);
        sigma[i]=temp1[i]/temp2[i];
    }
    array<double>^ posMax=gcnew array <double>(256);
    nMax=cariMax(sigma,256);     //Fungsi cariMax -> mendapatkan nilai Max dari array.
    int k=0;
    for (i=0;i<256;i++){
        if (sigma[i]==nMax){
            nMean+=(i+1);
            k++;
        }
    }
    nMean/=k;
    level = (nMean-1)/255;
    return level;
}
Parameter masukannya hanya image yang akan ditentukan global thresholdnya. Parameter keluarannya berupa sebuah angka yang merupakan threshold atau level yang bisa dipakai untuk mengkonversi image menjadi biner.
Implementasinya kira-kira sebagai berikut:
#include "stdafx.h"
#include "CImg.h"
#include "math.h"
int main(int argc,char **argv) {
    CImg<double> img1("1.jpg"), grayIm;
    CImg<bool> imgBw;
    grayIm = img1.norm().normalize(0,255); //image grayscale
    double level;
    level=graythresh(grayIm);
    imgBw=im2bw(grayIm,level);
    imgBw.display();    //menampilkan gambar biner
  return 0;
}
Gambar aslinya kira-kira seperti ini:
gambarGrayscale
Hasil konversi:
hasilBiner
Untuk fungsi-fungsi dasar pada CImg seperti cimg_forXY, get_histogram(), dll dapat dipelajari pada CImg reference yang ada pada folder CImg yang sudah didownload.
Sekian sedikit info yang mudah-mudahan berguna bagi yang lainnya..

4 comments:

ridwanf said...

bisa ya pake C..

(http://muhammadro6.student.ipb.ac.id)

(v_v) said...

Bisa donk... semua image processing bisa sih di utak-atik pake C... tapi ya mesti tau secara umum algoritme pemrosesannya

kakara said...

bukan seorang programmer.. baru lihat udah pusing.. hehe
makasih sharingnya

(v_v) said...

@kakara: sorry klo pusing, ini tutorial emang untuk programmer.. Tapi klo mw belajar pasti bisa kok...