Algoritma Edge Detection Pada Sebuah Gambar Berbasis Fuzzy Logic

Pada suatu hari Ali Hasyim ingin membuat sebuah aplikasi algoritma fuzzy logic untuk memenuhi tugas kuliahnya. Dia menemukan sebuah jurnal berikut ini http://oaj.unsri.ac.id/files/wwwijcaonline/journal/number22/pxc387675.pdf

Lalu dia mencoba membuat kode matlabnya. Berikut kode matlab yang telah dibuat.


clc
clear all
vid = videoinput('winvideo',1);
while true
input = getsnapshot(vid);
%input = imread('tubes.bmp');
input = imresize(input,[75 150]);

ukuran = size(input);
baris = ukuran(1);
kolom = ukuran(2);

for bar=2:baris
	for kol=2:kolom
		%===================
		%super fuzzy coming
		%===================
		p(1) = double(input(bar-1, kol-1));
		p(2) = double(input(bar-1, kol));
		p(3) = double(input(bar, kol-1));
		p(4) = double(input(bar, kol));

		for index=1:4
			nilai_black(index) = (255-p(index))/(255);
			nilai_white(index) = p(index)/255;
		end

		for index=1:4
			if nilai_black(index)>nilai_white(index)
				rule(index)=1; %black
				max_val(index) = nilai_black(index);
			else
				rule(index)=2; %white
				max_val(index) = nilai_white(index);
			end
		end

		P4Out_black=0;
		P4Out_edge=0;
		P4Out_white=0;

		if (rule(1) == 1) & (rule(2) == 1) & (rule(3) == 1) & (rule(4) == 1)
			P4Out_black= min([max_val(1) max_val(2) max_val(3) max_val(4)]); %black
		end
		if(rule(1) == 1) & (rule(2) == 1) & (rule(3) == 1) & (rule(4) == 2)
			P4Out_edge = min([max_val(1) max_val(2) max_val(3) max_val(4)]); %edge
		end
		if(rule(1) == 1) & (rule(2) == 1) & (rule(3) == 2) & (rule(4) == 1)
			buff_P4Out_edge = min([max_val(1) max_val(2) max_val(3) max_val(4)]);
			if(buff_P4Out_edge>P4Out_edge) 
				P4Out_edge = buff_P4Out_edge;
			end
			%edge
		end
		if(rule(1) == 1) & (rule(2) == 1) & (rule(3) == 2) & (rule(4) == 2)
			buff_P4Out_edge = min([max_val(1) max_val(2) max_val(3) max_val(4)]);
			if(buff_P4Out_edge>P4Out_edge) 
				P4Out_edge = buff_P4Out_edge;
			end
			%edge
		end
		if(rule(1) == 1) & (rule(2) == 2) & (rule(3) == 1) & (rule(4) == 1)
			buff_P4Out_edge = min([max_val(1) max_val(2) max_val(3) max_val(4)]);
			if(buff_P4Out_edge>P4Out_edge) 
				P4Out_edge = buff_P4Out_edge;
			end
			%edge
		end
		if(rule(1) == 1) & (rule(2) == 2) & (rule(3) == 1) & (rule(4) == 2)
			buff_P4Out_edge = min([max_val(1) max_val(2) max_val(3) max_val(4)]);
			if(buff_P4Out_edge>P4Out_edge) 
				P4Out_edge = buff_P4Out_edge;
			end
			%edge
		end
		if(rule(1) == 1) & (rule(2) == 2) & (rule(3) == 2) & (rule(4) == 1)
			buff_P4Out_edge = min([max_val(1) max_val(2) max_val(3) max_val(4)]);
			if(buff_P4Out_edge>P4Out_edge) 
				P4Out_edge = buff_P4Out_edge;
			end
			%edge
		end
		if(rule(1) == 1) & (rule(2) == 2) & (rule(3) == 2) & (rule(4) == 2)
			P4Out_white = min([max_val(1) max_val(2) max_val(3) max_val(4)]); %white
			%white
		end
		if(rule(1) == 2) & (rule(2) == 1) & (rule(3) == 1) & (rule(4) == 1)
			buff_P4Out_edge = min([max_val(1) max_val(2) max_val(3) max_val(4)]);
			if(buff_P4Out_edge>P4Out_edge) 
				P4Out_edge = buff_P4Out_edge;
			end
			%edge
		end
		if(rule(1) == 2) & (rule(2) == 1) & (rule(3) == 1) & (rule(4) == 2)
			buff_P4Out_edge = min([max_val(1) max_val(2) max_val(3) max_val(4)]);
			if(buff_P4Out_edge>P4Out_edge) 
				P4Out_edge = buff_P4Out_edge;
			end
			%edge
		end
		if(rule(1) == 2) & (rule(2) == 1) & (rule(3) == 2) & (rule(4) == 1)
			buff_P4Out_edge = min([max_val(1) max_val(2) max_val(3) max_val(4)]);
			if(buff_P4Out_edge>P4Out_edge) 
				P4Out_edge = buff_P4Out_edge;
			end
			%edge
		end
		if(rule(1) == 2) & (rule(2) == 1) & (rule(3) == 2) & (rule(4) == 2)
			buff_P4Out_edge = min([max_val(1) max_val(2) max_val(3) max_val(4)]);
			if(buff_P4Out_edge>P4Out_edge) 
				P4Out_edge = buff_P4Out_edge;
			end
			%edge
		end
		if(rule(1) == 2) & (rule(2) == 2) & (rule(3) == 1) & (rule(4) == 1)
			buff_P4Out_edge = min([max_val(1) max_val(2) max_val(3) max_val(4)]);
			if(buff_P4Out_edge>P4Out_edge) 
				P4Out_edge = buff_P4Out_edge;
			end
			%edge
		end
		if(rule(1) == 2) & (rule(2) == 2) & (rule(3) == 1) & (rule(4) == 2)
			buff_P4Out_edge = min([max_val(1) max_val(2) max_val(3) max_val(4)]);
			if(buff_P4Out_edge>P4Out_edge) 
				P4Out_edge = buff_P4Out_edge;
			end
			%edge
		end
		if(rule(1) == 2) & (rule(2) == 2) & (rule(3) == 2) & (rule(4) == 1)
			buff_P4Out_edge = min([max_val(1) max_val(2) max_val(3) max_val(4)]);
			if(buff_P4Out_edge>P4Out_edge) 
				P4Out_edge = buff_P4Out_edge;
			end
			%edge
		end
		if(rule(1) == 2) & (rule(2) == 2) & (rule(3) == 2) & (rule(4) == 2)
			buff_P4Out_white = min([max_val(1) max_val(2) max_val(3) max_val(4)]);
			if(buff_P4Out_white>P4Out_white) 
				P4Out_white = buff_P4Out_white;
			end
			%white
		end

		P4Out_final_value = ((P4Out_black*3)+(P4Out_edge*133)+(P4Out_white*252))/(P4Out_black+P4Out_edge+P4Out_white);
		P4Out_final_warna = uint8(round(P4Out_final_value));
		%===================
		im_out(bar,kol) =P4Out_final_warna; 
	end
end

imshow(im_out);
end

Berikut hasilnya.

Jika kita ingin mendapatkan murni edge/tepinya saja, maka kita rekayasa kode defuzzyfikasinya pada konstanta putih= 3.

P4Out_final_value = ((P4Out_black*3)+(P4Out_edge*133)+(P4Out_white*3))/(P4Out_black+P4Out_edge+P4Out_white);

Resize Gambar Bitmap Pada Visual C#

tambahkan

Using System.Drawing.Drawing2D;

berikut kodenya:
 

Bitmap newImage = new Bitmap(newWidth, newHeight);
using (Graphics gr = Graphics.FromImage(newImage))
{
    gr.SmoothingMode = SmoothingMode.HighQuality;
    gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
    gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
    gr.DrawImage(srcImage, new Rectangle(0, 0, newWidth, newHeight));
}

 

_________________________________
DAFTAR PUSTAKA
http://stackoverflow.com/questions/87753/resizing-an-image-without-losing-any-quality

Aplikasi Normalized Sum-Squared Difference (NSSD) Untuk Klasifikasi Gambar Bendera

Beberapa waktu yang lalu saya ikut ujian mk computer vision. Saya kerjakan pada MAtlab 7.1. Berikut ceritanya….

Buatlah sebuah software untuk mengklasifikasikan jenis2 bendera berikut ini. Software yang anda buat harus memenuhi spesifikasi dibawah ini

  • Menggunakan MATLAB
  • Algoritma bebas tetapi mencakup Akuisisi Citra, Preprocessing, Ekstraksi Ciri & Klasifikasi
  • Menggunakan sistem klasifikasi NSSD
  • Lakukan analisis mengenai algoritma dan parameter – paramater perblok yang anda pilih sehingga algoritma dan parameter – parameter yang anda pilih menghasilkan output yang optimal berdasarkan akurasi


Save gambar tersebut dengan nama itali.jpg , japan.jpg, korea.jpg , argentina.jpg , india.jpg

Jawab

Keterangan :

IC(i) = intensitas frame pada pixel (i)

IB(i) = intensitas background pada pixel (i)

Q = detection region / ROI (Region of Interest)

N = jumlah pixel pada area Q

IC dan IB mempunyai cakupan nilai antara 0-255. IC sendiri adalah nilai intensitas pixel dari gambar tes. Sedangkan IB adalah intensitas pixel dari gambar asli. Q yang digunakan adalah keseluruhan area gambar.

Algoritma yang dirancang berikut ini adalah algoritma yang mencoba melakukan optimasi pada proses pengolahan data gambar sehingga proses perhitungan data semakin sedikit, maka waktu eksekusi bisa menjadi lebih cepat.

Beberapa hal yang dilakukan untuk mendukung algoritma yang dirancang adalah:

  • Dilakukan filtering menggunakan metode Gaussian dengan kernel 9×9 dan sigma=2. Hal ini dimaksudkan untuk meredam noise dan menyamarkan gambar agar bisa lebih dekat dengan kemiripan terhadap gambar asli.
  • Semua gambar yang diolah diatur ulang ukurannya menjadi 20×40 pixel (ini adalah Q).
  • Proses perhitungan NSSD menggunakan gambar grayscale sehingga yang dihitung hanya satu layer data gambar (bukan 3 layer, RGB).
  • Proses perhitungan NSSD didasarkan pada tiga pola utama dari gambar asli, yaitu:
  1. Pola ke-1, bendera Argentina dan India
  2. Pola ke-2, bendera Italia
  3. Pola ke-3, bendera Jepang dan Korea Selatan

Sehingga pada hasil akhir akan dihitung pola mana yang mempunyai nilai NSSD terkecil.

  • Untuk mengklasifikasikan  dari pola menjadi kategori bendera, digunakan perbandingan vector warna dari gambar tes dengan gambar asli. Nilai vector warna dihitung per-layer menggunakan rata-rata (mean) intensitas warna yang muncul pada tiap layer (RGB)  sehingga hasilnya adalah nilai mean dari layer R, G, dan B. Ketiga komponen tersebut kemudian akan direpresentasikan kedalam vector 3 axis mempunyai arah dan besaran. Komponen dari vector tersebut akan menghasilkan Theta_1 (sudut antara sumbu R dan B) dan  Theta_2 (sudut antara sumbu G dan vector resultan dari RB).

Untuk menghitung Theta_1 dan Theta_2 didapat dari persamaan berikut.

Nilai akurasi dihitung berdasarkan kemiripan dengan samperl pola berdasarkan nilai NSSD. Berikut persamaannya.

NSSDk adalah nilai NSSD terkecil urutan pola ke-k. Konstanta 65025 didapat dari angka maksimum intensitas pada data gambar yaitu 255 yang dikuadratkan (persamaan didapat dengan memperhatikan persamaan NSSD).

Berikut adalah gambar tes yang diujikan pada algoritma di atas.

LAMPIRAN 1: KODE MATLAB

clc

clear all

start_bar = 1;

start_kol = 1;

baris = 20;

kolom = 40;

 

im_bentuk = imread(‘argentina.jpg’);

im_bentuk = imresize(im_bentuk,[baris kolom]);

im_bentuk_array = im_bentuk;

G = fspecial(‘gaussian’,[9 9],2);

im_bentuk = imfilter(im_bentuk, G);

im_bentuk_array(:,:,1) = rgb2gray(im_bentuk);

 

%figure,imshow(im_bentuk_array(:,:,1));

 

im_bentuk = imread(‘itali.jpg’);

im_bentuk = imresize(im_bentuk,[baris kolom]);

im_bentuk = imfilter(im_bentuk, G);

im_bentuk_array(:,:,2) = rgb2gray(im_bentuk);

 

%figure,imshow(im_bentuk_array(:,:,2));

 

im_bentuk = imread(‘japan.jpg’);

im_bentuk = imresize(im_bentuk,[baris kolom]);

im_bentuk = imfilter(im_bentuk, G);

im_bentuk_array(:,:,3) = rgb2gray(im_bentuk);

 

%figure,imshow(im_bentuk_array(:,:,3));

prompt = {‘Nama file input:’};

dlg_title = ‘Masukan file input!’;

num_lines = 1;

def = {‘argentina’};

answer = inputdlg(prompt,dlg_title,num_lines,def);

jawab = [answer{1} ‘.jpg’];

 

im_input = imread(jawab());

im_input_ori = im_input;

im_input = imresize(im_input,[baris kolom]);

im_input = imfilter(im_input, G);

im_input_rgb = im_input;

im_input = rgb2gray(im_input);

 

buff_NSSD = 1000000;

for type_bentuk=1:3

    SSD = 0;

    N = baris*kolom;

    for bar=start_bar:(baris+start_bar-1)

        for kol=start_kol:(kolom+start_kol-1)

            SSD = SSD + ((double(im_input(bar,kol))-double(im_bentuk_array(bar,kol,type_bentuk)))^2);

        end

    end

    NSSD(type_bentuk) = SSD/N;

    if(NSSD(type_bentuk)<buff_NSSD)

        min_sort = type_bentuk;

        buff_NSSD = NSSD(type_bentuk);

    end

end

 

persentase_NSSD = 100-((NSSD(min_sort)/65025)*100);

 

%disp(‘bentuk:argentina,itali,japan’);

%NSSD

%min_sort

r = im_input_rgb(uint8((baris/2)-(baris/4)):uint8((baris/2)+(baris/4)),uint8((kolom/2)-(kolom/4)):uint8((kolom/2)+(kolom/4)),1);

r = mean2(r);

g = im_input_rgb(uint8((baris/2)-(baris/4)):uint8((baris/2)+(baris/4)),uint8((kolom/2)-(kolom/4)):uint8((kolom/2)+(kolom/4)),2);

g = mean2(g);

b = im_input_rgb(uint8((baris/2)-(baris/4)):uint8((baris/2)+(baris/4)),uint8((kolom/2)-(kolom/4)):uint8((kolom/2)+(kolom/4)),3);

b = mean2(b);

 

vektor_resultan_rb = sqrt((r^2)+(b^2));

vektor_sudut1 = acosd((r/vektor_resultan_rb));

vektor_resultan_rgb = sqrt((vektor_resultan_rb^2)+(g^2));

vektor_sudut2 = acosd((vektor_resultan_rb/vektor_resultan_rgb));

 

figure(‘Name’,‘Hasilnya adalah…’),

subplot(1,2,1),imshow(im_input_ori),title(  {‘gambar masukan’;

                                            [‘mean r=’ int2str(r) ‘ g=’ int2str(g) ‘ b=’ int2str(b)];

                                            [‘\Theta_{r-b} =’ int2str(vektor_sudut1) ‘^{0} \Theta_{rb-g} =’ int2str(vektor_sudut2) ‘^{0}’]})

switch(min_sort)

    case 1

        if vektor_sudut1>49

            subplot(1,2,2),imshow(‘argentina.jpg’),title([‘gambar prediksi: ‘ int2str(persentase_NSSD) ‘% ARGENTINA’])

            pause(5)

            close all

        else

            subplot(1,2,2),imshow(‘india.jpg’),title([‘gambar prediksi: ‘ int2str(persentase_NSSD) ‘% INDIA’]) 

            pause(5)

            close all

        end

    case 2

            subplot(1,2,2),imshow(‘itali.jpg’),title([‘gambar prediksi: ‘ int2str(persentase_NSSD) ‘% ITALI’])

            pause(5)

            close all

    case 3

        if vektor_sudut1<38

            subplot(1,2,2),imshow(‘japan.jpg’),title([‘gambar prediksi: ‘ int2str(persentase_NSSD) ‘% JEPANG’])

            pause(5)

            close all

        else

            subplot(1,2,2),imshow(‘korea.jpg’),title([‘gambar prediksi: ‘ int2str(persentase_NSSD) ‘% KOREA SELATAN’])     

            pause(5)

            close all

        end

end

________________________________________________

DAFTAR PUSTAKA

Click to access viewer.php

Petra Christian University Library – /jiunkpe/s1/elkt/2007/jiunkpe-ns-s1-2007-23401003-8181-sinyal_v

Click to access viewer.php

http://siddhantahuja.wordpress.com/2009/05/20/correlation-based-similarity-measure-sum-of-squared-differences-ssd/

http://siddhantahuja.wordpress.com/tag/sum-of-squared-differences/

__________________________________________________

kode lainnya yang saya kembangkan dengan pendekatan yang berbeda

____________________double.m

clc;
clear all;

baris = 180;
kolom = 360;
jum_layer = 3;
threshold_klasifikasi = 333; %persentase toleransi kemiripan
interval_scan_baris = baris/6;
interval_scan_kolom = kolom/6;
jum_lipat = 3;
input_bendera = imread(‘tes10.jpg’);
bendera_normal = imresize(input_bendera,[baris kolom]);

dir_gambar = [dir(‘itali.jpg’) dir(‘japan.jpg’)  dir(‘korea.jpg’) dir(‘argentina.jpg’) dir(‘india.jpg’)];

for i=1:5
buff_NSSD = 1000000;
i
for lipat=1:jum_lipat
N = (baris/lipat)*(kolom/lipat)*jum_layer;
bendera_source = imread(dir_gambar(i).name);
bendera_source = imresize(bendera_source,[baris/lipat kolom/lipat]);
for scan_y=1:interval_scan_baris:(baris – (baris/(2^(lipat-1))) + 1)
for scan_x=1:interval_scan_kolom:(kolom – (kolom/(2^(lipat-1))) + 1)
bendera_sum = 0;
for layer=1 : jum_layer
for n=1 : baris/lipat
for m=1 : kolom/lipat
bendera_sum = bendera_sum + ((double(bendera_normal((scan_y+n-1),(scan_x+m-1),layer)) – double(bendera_source(n,m,layer)))^2);
end
end
end
nilai_NSSD(i) = bendera_sum/N;
if nilai_NSSD(i) < buff_NSSD
buff_NSSD = nilai_NSSD(i);
end
end
end
end
nilai_NSSD(i) = buff_NSSD;
end
%================EDGE======================

bendera_source = imresize(bendera_source,[baris/lipat kolom/lipat]);
bendera_source = rgb2gray(bendera_source);
bendera_source = edge(bendera_source,’sobel’,0.009);

for i=1:5
buff_NSSD = 1000000;
i
for lipat=1:jum_lipat
N = (baris/lipat)*(kolom/lipat);
bendera_source = imread(dir_gambar(i).name);
bendera_source = imresize(bendera_source,[baris/lipat kolom/lipat]);
bendera_source = rgb2gray(bendera_source);
bendera_source = edge(bendera_source,’sobel’);
for scan_y=1:interval_scan_baris:(baris – (baris/(2^(lipat-1))) + 1)
for scan_x=1:interval_scan_kolom:(kolom – (kolom/(2^(lipat-1))) + 1)
bendera_sum = 0;
for n=1 : baris/lipat
for m=1 : kolom/lipat
bendera_sum = bendera_sum + ((double(bendera_normal((scan_y+n-1),(scan_x+m-1))) – double(bendera_source(n,m)))^2);
end
end
nilai_NSSD_edge(i) = bendera_sum/N;
if nilai_NSSD_edge(i) < buff_NSSD
buff_NSSD = nilai_NSSD_edge(i);
end
end
end
end
nilai_NSSD_edge(i) = buff_NSSD;
end
%==========================================
minimal=1;
for i=1:5
nilai_NSSD_akhir(i) = (nilai_NSSD(i)*nilai_NSSD_edge(i));
%nilai_NSSD_akhir(i) = nilai_NSSD(i) + (nilai_NSSD_edge(i)*10000);
if(nilai_NSSD_akhir(i)<nilai_NSSD_akhir(minimal))minimal=i;end
end

bendera_prediksi = minimal;
if nilai_NSSD_akhir(minimal)>threshold_klasifikasi
minimal=0;
end
switch(minimal)
case 0
disp(‘Bendera tidak ada yang cocok’)
switch(bendera_prediksi)
case 1
disp(‘Tapi kalau boleh saya tebak, ini Bendera Itali’)
case 2
disp(‘Tapi kalau boleh saya tebak, ini Bendera Jepang’)
case 3
disp(‘Tapi kalau boleh saya tebak, ini Bendera Korea Selatan’)
case 4
disp(‘Tapi kalau boleh saya tebak, ini Bendera Argentina’)
case 5
disp(‘Tapi kalau boleh saya tebak, ini Bendera India’)
end
case 1
disp(‘Ini Bendera Itali’)
case 2
disp(‘Ini Bendera Jepang’)
case 3
disp(‘Ini Bendera Korea Selatan’)
case 4
disp(‘Ini Bendera Argentina’)
case 5
disp(‘Ini Bendera India’)
end

_______________________NSSD_edge.m

clc;
clear all;

baris = 100;
kolom = 200;
threshold_klasifikasi = 2100; %persentase toleransi kemiripan

input_bendera = imread(‘japan.jpg’);
bendera_normal = imresize(input_bendera,[baris kolom]);
bendera_normal = rgb2gray(bendera_normal);
bendera_normal = edge(bendera_normal,’sobel’);

dir_gambar = [dir(‘itali.jpg’) dir(‘japan.jpg’)  dir(‘korea.jpg’) dir(‘argentina.jpg’) dir(‘india.jpg’)];
minimal= 1;

for i=1:5
buff_NSSD = 1000000;
N = baris*kolom;
bendera_source = imread(dir_gambar(i).name);
bendera_source = imresize(bendera_source,[baris kolom]);
bendera_source = rgb2gray(bendera_source);
bendera_source = edge(bendera_source,’sobel’);
bendera_sum = 0;
for n=1 : baris
for m=1 : kolom
bendera_sum = bendera_sum + ((double(bendera_normal(n,m)) – double(bendera_source(n,m)))^2);
end
end
nilai_NSSD(i) = bendera_sum/N;
if nilai_NSSD(i) < buff_NSSD
buff_NSSD = nilai_NSSD(i);
end
nilai_NSSD(i) = buff_NSSD;
if(nilai_NSSD(i)<nilai_NSSD(minimal))minimal=i;end
end
bendera_prediksi = minimal;
if nilai_NSSD(minimal)>threshold_klasifikasi
minimal=0;
end
switch(minimal)
case 0
disp(‘Bendera tidak ada yang cocok’)
switch(bendera_prediksi)
case 1
disp(‘Tapi kalau boleh saya tebak, ini Bendera Itali’)
case 2
disp(‘Tapi kalau boleh saya tebak, ini Bendera Jepang’)
case 3
disp(‘Tapi kalau boleh saya tebak, ini Bendera Korea Selatan’)
case 4
disp(‘Tapi kalau boleh saya tebak, ini Bendera Argentina’)
case 5
disp(‘Tapi kalau boleh saya tebak, ini Bendera India’)
end
case 1
disp(‘Ini Bendera Itali’)
case 2
disp(‘Ini Bendera Jepang’)
case 3
disp(‘Ini Bendera Korea Selatan’)
case 4
disp(‘Ini Bendera Argentina’)
case 5
disp(‘Ini Bendera India’)
end

_______________________ori_2.m

clc;
clear all;

baris = 100;
kolom = 200;
jum_layer = 3;
threshold_klasifikasi = 2100; %persentase toleransi kemiripan
interval_scan_baris = baris/10;
interval_scan_kolom = kolom/10;

input_bendera = imread(‘tes8.jpg’);
bendera_normal = imresize(input_bendera,[baris kolom]);
G = fspecial(‘gaussian’,[15 15],4);
bendera_normal = imfilter(bendera_normal,G,’same’);

dir_gambar = [dir(‘itali.jpg’) dir(‘japan.jpg’)  dir(‘korea.jpg’) dir(‘argentina.jpg’) dir(‘india.jpg’)];
minimal= 1;

for i=1:5
buff_NSSD = 1000000;
i
for lipat=1:2
N = (baris/lipat)*(kolom/lipat)*jum_layer;
bendera_source = imread(dir_gambar(i).name);
bendera_source = imresize(bendera_source,[baris/lipat kolom/lipat]);
bendera_source = imfilter(bendera_source,G,’same’);
for scan_y=1:interval_scan_baris:(baris – (baris/(2^(lipat-1))) + 1)
for scan_x=1:interval_scan_kolom:(kolom – (kolom/(2^(lipat-1))) + 1)
bendera_sum = 0;
for layer=1 : jum_layer
for n=1 : baris/lipat
for m=1 : kolom/lipat
bendera_sum = bendera_sum + ((double(bendera_normal((scan_y+n-1),(scan_x+m-1),layer)) – double(bendera_source(n,m,layer)))^2);
end
end
end
nilai_NSSD(i) = bendera_sum/N;
if nilai_NSSD(i) < buff_NSSD
buff_NSSD = nilai_NSSD(i);
end
end
end
end
nilai_NSSD(i) = buff_NSSD;
if(nilai_NSSD(i)<nilai_NSSD(minimal))minimal=i;end
end
bendera_prediksi = minimal;
if nilai_NSSD(minimal)>threshold_klasifikasi
minimal=0;
end
switch(minimal)
case 0
disp(‘Bendera tidak ada yang cocok’)
switch(bendera_prediksi)
case 1
disp(‘Tapi kalau boleh saya tebak, ini Bendera Itali’)
case 2
disp(‘Tapi kalau boleh saya tebak, ini Bendera Jepang’)
case 3
disp(‘Tapi kalau boleh saya tebak, ini Bendera Korea Selatan’)
case 4
disp(‘Tapi kalau boleh saya tebak, ini Bendera Argentina’)
case 5
disp(‘Tapi kalau boleh saya tebak, ini Bendera India’)
end
case 1
disp(‘Ini Bendera Itali’)
case 2
disp(‘Ini Bendera Jepang’)
case 3
disp(‘Ini Bendera Korea Selatan’)
case 4
disp(‘Ini Bendera Argentina’)
case 5
disp(‘Ini Bendera India’)
end

_____________________________ori_2_edge.m

clc;
clear all;

baris = 100;
kolom = 200;
threshold_klasifikasi = 2100; %persentase toleransi kemiripan
interval_scan_baris = baris/10;
interval_scan_kolom = kolom/10;

input_bendera = imread(‘itali.jpg’);
bendera_normal = imresize(input_bendera,[baris kolom]);
bendera_normal = rgb2gray(bendera_normal);
bendera_normal = edge(bendera_normal,’sobel’);

dir_gambar = [dir(‘itali.jpg’) dir(‘japan.jpg’)  dir(‘korea.jpg’) dir(‘argentina.jpg’) dir(‘india.jpg’)];
minimal= 1;

for i=1:5
buff_NSSD = 1000000;
for lipat=1:2
N = (baris/lipat)*(kolom/lipat);
bendera_source = imread(dir_gambar(i).name);
bendera_source = imresize(bendera_source,[baris/lipat kolom/lipat]);
bendera_source = rgb2gray(bendera_source);
bendera_source = edge(bendera_source,’sobel’);
for scan_y=1:interval_scan_baris:(baris – (baris/(2^(lipat-1))) + 1)
for scan_x=1:interval_scan_kolom:(kolom – (kolom/(2^(lipat-1))) + 1)
bendera_sum = 0;
for n=1 : baris/lipat
for m=1 : kolom/lipat
bendera_sum = bendera_sum + ((double(bendera_normal((scan_y+n-1),(scan_x+m-1))) – double(bendera_source(n,m)))^2);
end
end
nilai_NSSD(i) = bendera_sum/N;
if nilai_NSSD(i) < buff_NSSD
buff_NSSD = nilai_NSSD(i);
end
end
end
end
nilai_NSSD(i) = buff_NSSD;
if(nilai_NSSD(i)<nilai_NSSD(minimal))minimal=i;end
end
bendera_prediksi = minimal;
if nilai_NSSD(minimal)>threshold_klasifikasi
minimal=0;
end
switch(minimal)
case 0
disp(‘Bendera tidak ada yang cocok’)
switch(bendera_prediksi)
case 1
disp(‘Tapi kalau boleh saya tebak, ini Bendera Itali’)
case 2
disp(‘Tapi kalau boleh saya tebak, ini Bendera Jepang’)
case 3
disp(‘Tapi kalau boleh saya tebak, ini Bendera Korea Selatan’)
case 4
disp(‘Tapi kalau boleh saya tebak, ini Bendera Argentina’)
case 5
disp(‘Tapi kalau boleh saya tebak, ini Bendera India’)
end
case 1
disp(‘Ini Bendera Itali’)
case 2
disp(‘Ini Bendera Jepang’)
case 3
disp(‘Ini Bendera Korea Selatan’)
case 4
disp(‘Ini Bendera Argentina’)
case 5
disp(‘Ini Bendera India’)
end

____________________________ori_3.m

clc;
clear all;

baris = 100;
kolom = 200;
jum_layer = 3;
threshold_klasifikasi = 2200; %persentase toleransi kemiripan
interval_scan_baris = baris/10;
interval_scan_kolom = kolom/10;

prompt = {‘Masukan Nama file gambar:’};
dlg_title = ‘Pilih Gambar’;
num_lines = 1;
def = {‘japan.jpg’};
jawab = inputdlg(prompt,dlg_title,num_lines,def);

input_bendera = imread(jawab{1});
bendera_normal = imresize(input_bendera,[baris kolom]);
G = fspecial(‘gaussian’,[1 1],0.6);
bendera_normal = imfilter(bendera_normal,G,’same’);

dir_gambar = [dir(‘itali.jpg’) dir(‘japan.jpg’)  dir(‘korea.jpg’) dir(‘argentina.jpg’) dir(‘india.jpg’)];
for lipat=1:2
buff_NSSD = 1000000;
minimal= 1;
for i=1:5
i
N = (baris/lipat)*(kolom/lipat)*jum_layer;
bendera_source = imread(dir_gambar(i).name);
bendera_source = imresize(bendera_source,[baris/lipat kolom/lipat]);
bendera_source = imfilter(bendera_source,G,’same’);
for scan_y=1:interval_scan_baris:(baris – (baris/(2^(lipat-1))) + 1)
for scan_x=1:interval_scan_kolom:(kolom – (kolom/(2^(lipat-1))) + 1)
bendera_sum = 0;
for layer=1 : jum_layer
for n=1 : baris/lipat
for m=1 : kolom/lipat
bendera_sum = bendera_sum + ((double(bendera_normal((scan_y+n-1),(scan_x+m-1),layer)) – double(bendera_source(n,m,layer)))^2);
end
end
end
if (bendera_sum/N)<buff_NSSD
nilai_NSSD(i) = bendera_sum/N;
else
nilai_NSSD(i) = buff_NSSD;
end
if nilai_NSSD(i)<threshold_klasifikasi
minimal = i;
break;
end
buff_NSSD = bendera_sum/N;
end
if nilai_NSSD(i)<threshold_klasifikasi
break;
end
end
if nilai_NSSD(i)<threshold_klasifikasi
break;
end
if(nilai_NSSD(i)<nilai_NSSD(minimal))minimal=i;end
end
if nilai_NSSD(i)<threshold_klasifikasi
break;
end
end
bendera_prediksi = minimal;
if nilai_NSSD(minimal)>threshold_klasifikasi
minimal=0;
end

switch(minimal)
case 0
switch(bendera_prediksi)
case 1
msgbox(‘Bendera tidak ada yang cocok, tapi kalau boleh saya tebak, itu bendera Itali’, ‘Hasil’)
case 2
msgbox(‘Bendera tidak ada yang cocok, tapi kalau boleh saya tebak, itu bendera Jepang’, ‘Hasil’)
case 3
msgbox(‘Bendera tidak ada yang cocok, tapi kalau boleh saya tebak, itu bendera Korea Selatan’, ‘Hasil’)
case 4
msgbox(‘Bendera tidak ada yang cocok, tapi kalau boleh saya tebak, itu bendera Argentina’, ‘Hasil’)
case 5
msgbox(‘Bendera tidak ada yang cocok, tapi kalau boleh saya tebak, itu bendera India’, ‘Hasil’)
end
case 1
msgbox(‘Bendera Itali’, ‘Hasil’)
case 2
msgbox(‘Bendera Jepang’, ‘Hasil’)
case 3
msgbox(‘Bendera Korea Selatan’, ‘Hasil’)
case 4
msgbox(‘Bendera Argentina’, ‘Hasil’)
case 5
msgbox(‘Bendera India’, ‘Hasil’)
end

______________________________backup5_algo.m

function [ output_args ] = Untitled2( input_args )
%UNTITLED2 Summary of this function goes here
%  Detailed explanation goes here
clc
baris = 27;
kolom = 54;
konst_thr_gray = 0.75;
thr_gray = 255*konst_thr_gray;
thr_gray_kemiripan = 21100;
jum_lipat = 3;
jum_layer_rgb = 3;
konst_interval = 1;
interval_scan_baris = 3*konst_interval;
interval_scan_kolom = 6*konst_interval;
%gb input 2 gray
nama_file = [‘itali.jpg’];
gb_input = imread(nama_file);
gb_input = imresize(gb_input,[baris kolom]);
gb_input_gray = rgb2gray(gb_input);
%pertegas gb_gray
for bar=1:baris
for kol=1:kolom
if gb_input_gray(bar,kol)>thr_gray
gb_input_gray(bar,kol)=255;
else
gb_input_gray(bar,kol)=0;
end
end
end
dir_gambar = [dir(‘itali.jpg’) dir(‘japan.jpg’)  dir(‘korea.jpg’) dir(‘argentina.jpg’) dir(‘india.jpg’)];

scan_y_buff = [];
scan_x_buff = [];
lipat_buff = [];
gb_urut_buff = [];
actual_baris_buff = [];
actual_kolom_buff = [];
for i=1:5
%input gb source 2 gray
gb_source = imread(dir_gambar(i).name);
gb_source_gray = rgb2gray(gb_source);
for lipat=1:jum_lipat
actual_baris = ((baris/jum_lipat)*(jum_lipat-lipat+1));
actual_kolom = ((kolom/jum_lipat)*(jum_lipat-lipat+1));
N = actual_baris*actual_kolom;
%im resize
gb_source_gray = imresize(gb_source_gray,[actual_baris actual_kolom]);
%pertegas gb_source
for bar=1:actual_baris
for kol=1:actual_kolom
if gb_source_gray(bar,kol)>thr_gray
gb_source_gray(bar,kol)=255;
else
gb_source_gray(bar,kol)=0;
end
end
end
for scan_y=1:interval_scan_baris:(baris-actual_baris+1)
for scan_x=1:interval_scan_baris:(kolom-actual_kolom+1)
bendera_sum = 0;
for n=1 : actual_baris
for m=1 : actual_kolom
bendera_sum = bendera_sum + ((double(gb_input_gray((scan_y+n-1),(scan_x+m-1))) – double(gb_source_gray(n,m)))^2);
end
end
nilai_NSSD(i) = bendera_sum/N;
if nilai_NSSD(i)<thr_gray_kemiripan
scan_y_buff = [scan_y_buff(1:end) scan_y];
scan_x_buff = [scan_x_buff(1:end) scan_x];
lipat_buff = [lipat_buff(1:end) lipat];
actual_baris_buff = [actual_baris_buff(1:end) actual_baris];
actual_kolom_buff = [actual_kolom_buff(1:end) actual_kolom];
gb_urut_buff = [gb_urut_buff(1:end) i];
end
end
end
end
end
loop_rgb = size(gb_urut_buff);
buff_NSSD_tahap2 = 1000000;
minimal_tahap2 = 1;
for i=1:loop_rgb(2)
gb_source = imread(dir_gambar(gb_urut_buff(i)).name);
gb_source_rgb = imresize(gb_source,[actual_baris_buff(i) actual_kolom_buff(i)]);
for layer=1 : jum_layer_rgb
for n=1 : actual_baris_buff(i)
for m=1 : actual_kolom_buff(i)
bendera_sum = bendera_sum + ((double(gb_input((scan_y_buff(i)+n-1),(scan_x_buff(i)+m-1),layer)) – double(gb_source_rgb(n,m,layer)))^2);
end
end
end
nilai_NSSD_tahap2(i) = bendera_sum/N;
if nilai_NSSD_tahap2(i) < buff_NSSD_tahap2
minimal_tahap2 = i;
buff_NSSD_tahap2 = nilai_NSSD_tahap2(i);
end
end
gb_banding_asli = imread(nama_file);
banding_pixel = size(gb_banding_asli);
resize_data_scan_y = scan_y_buff(minimal_tahap2)*(banding_pixel(1)/baris)
resize_data_scan_x = scan_x_buff(minimal_tahap2)*(banding_pixel(2)/kolom)
resize_data_bar = actual_baris_buff(minimal_tahap2)*(banding_pixel(1)/baris)
resize_data_kol = actual_kolom_buff(minimal_tahap2)*(banding_pixel(2)/kolom)

lebar_bound = 1;
for n=1 : resize_data_bar
for m=1 : resize_data_kol
if (n<=lebar_bound) | (n>=(resize_data_bar-lebar_bound)) | (m<=lebar_bound) | (m>=(resize_data_kol-lebar_bound))
gb_banding_asli(ceil(resize_data_scan_y + n – 1),ceil(resize_data_scan_x + m -1),1) = 255;
gb_banding_asli(ceil(resize_data_scan_y + n – 1),ceil(resize_data_scan_x + m -1),2) = 1;
gb_banding_asli(ceil(resize_data_scan_y + n – 1),ceil(resize_data_scan_x + m -1),3) = 1;
end
end
end
figure,imshow(gb_banding_asli);
switch(minimal_tahap2)
case 1
disp(‘Ini Bendera Itali’)
case 2
disp(‘Ini Bendera Jepang’)
case 3
disp(‘Ini Bendera Korea Selatan’)
case 4
disp(‘Ini Bendera Argentina’)
case 5
disp(‘Ini Bendera India’)
end

___________________________NSSD.m

%function [ output_args ] = NSSD( input_args )
clc
clear all

row = 120;
col = 210;
layer_pic = 3;
N = row*col*layer_pic;
threshold = 0.8;
min=1;
input_flag = imread(’11.jpg’);
normal_flag = imresize(input_flag,[row col]);

pic_dir = [dir(‘itali.jpg’) dir(‘japan.jpg’)  dir(‘korea.jpg’) dir(‘argentina.jpg’) dir(‘india.jpg’)];

for i=1:5
flag_source = imread(pic_dir(i).name);
flag_source = imresize(flag_source,[row col]);
flag_sum = 0;
for layer = 1 : layer_pic
for n = 1 : row
for m = 1 : col
flag_sum = flag_sum + ((double(normal_flag(n,m,layer)) – double(flag_source(n,m,layer)))^2);
end
end
end
nilai_NSSD(i) = flag_sum/N;
if(nilai_NSSD(i)<nilai_NSSD(min))
min=i;
end
end

bendera = min;
if nilai_NSSD(min)>threshold
min=0;
end

switch(min)
case 0
disp(‘Sepertinya Ini:’)
switch(bendera)
case 1
disp(‘Bendera Itali’)
case 2
disp(‘ini Bendera Jepang’)
case 3
disp(‘ini Bendera Korea Selatan’)
case 4
disp(‘Bendera Argentina’)
case 5
disp(‘Bendera India’)
end
case 1
disp(‘Pasti Ini Bendera Itali’)
case 2
disp(‘Pasti Ini Bendera Jepang’)
case 3
disp(‘Pasti Ini Bendera Korea Selatan’)
case 4
disp(‘Pasti Ini Bendera Argentina’)
case 5
disp(‘Pasti Ini Bendera India’)
end

_________________________________________________

Download semua file project

Aplikasi Color Tracking OpenCV Pada Linux

Jangan lupa webcam-nya dipasang.

Package yang diperlukan adalah:

  • GCC 4.3 or later. In Ubuntu/Debian it can be installed with
sudo apt-get install build-essential
  • CMake 2.6 or higher
  • Subversion (SVN) client
  • GTK+ 2.x or higher, including headers (e.g. libgtk2.0-dev)
  • pkgconfig
  • libpng, zlib, libjpeg, libtiff, libjasper with development files (e.g. libjpeg-dev)
  • Python 2.3 or later with developer packages (e.g. python-dev)
  • SWIG 1.3.30 or later
  • libavcodec etc. from ffmpeg 0.4.9-pre1 or later + headers. (Video support with FFMPEG)
  • libdc1394 2.x + headers for video capturing from IEEE1394 cameras

Untuk menginstal package di atas bisa gunakan command console berikut.

sudo apt-get install build-essential
sudo apt-get install cmake
sudo apt-get install pkg-config
sudo apt-get install libpng12-0 libpng12-dev libpng++-dev libpng3
sudo apt-get install libpnglite-dev libpngwriter0-dev libpngwriter0c2
sudo apt-get install zlib1g-dbg zlib1g zlib1g-dev
sudo apt-get install libjasper-dev libjasper-runtime libjasper1
sudo apt-get install pngtools libtiff4-dev libtiff4 libtiffxx0c2 libtiff-tools
sudo apt-get install libjpeg8 libjpeg8-dev libjpeg8-dbg libjpeg-prog
sudo apt-get install ffmpeg libavcodec-dev libavcodec52 libavformat52 libavformat-dev
sudo apt-get install libgstreamer0.10-0-dbg libgstreamer0.10-0 libgstreamer0.10-dev
sudo apt-get install libxine1-ffmpeg libxine-dev libxine1-bin
sudo apt-get install libunicap2 libunicap2-dev
sudo apt-get install libdc1394-22-dev libdc1394-22 libdc1394-utils
sudo apt-get install swig
sudo apt-get install libv4l-0 libv4l-dev
sudo apt-get install python-numpy

Notes:

  • Not all those packages are necessarily needed. CMAKE will show you what you have installed.
  • For adding other features such as CUDA or a GUI (gtk+ 2.X or Qt), refer to the InstallGuide.
  • You might have to be logged in as root or use “sudo apt-get” instead of “apt-get” in all the commands mentioned above.
  • If you also want to use OpenCV from Python, add this:
    apt-get install libpython2.6 python-dev python2.6-dev  # Only if you want to use python
  • If your system has trouble with building “libjpeg.so”, you may need to build it manually, or try this:
    apt-get install libjpeg-progs libjpeg-dev
  • On Ubuntu 10.10 this apt-get was needed to recognize gstream-app and gstreamer-vid development headers
    apt-get install libgstreamer-plugins-base0.10-dev

referensi:

http://opencv.willowgarage.com/wiki/InstallGuide_Linux

http://opencv.willowgarage.com/wiki/InstallGuide%20:%20Debian

Installing OpenCV 2.2 in Ubuntu 11.04

______________________________________________________

Menginstall openCV

Untuk mengkompile kode yang dibuat diperlukan sebuah file yang bernama makefile. File makefile dapat dibuat sendiri atau dengan menggunakan bantuan aplikasi cmake yang sudah diinstall tadi.

Dengan cmake ini kita akan mengkompile dan menginstall openCV pada Linux. Download terlebih dahulu openCV -nya. Kemudian extract. Lalu ikuti langkah berikut.

Building OpenCV from source using CMake, using the command line

  1. Create a temporary directory, which we denote as <cmake_binary_dir>, where you want to put the generated Makefiles, project files as well the object files and output binaries.
  2. a. Enter the <cmake_binary_dir> and type
    •     cmake [<some optional parameters...>] <path to the OpenCV source directory>

      For example, if you downloaded the project to ~/opencv, you can do the following:

          cd ~/opencv # the directory containing INSTALL, CMakeLists.txt etc.
          mkdir release
          cd release
          cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_PYTHON_SUPPORT=ON -D BUILD_EXAMPLES=ON ..

That will generate makefiles for the Release configuration and will put them in ~/opencv/release directory. If you want tu use special features such as IPP or TBB, please refer to the InstallGuide

  1. a. Enter the created temporary directory (<cmake_binary_dir>) and run make utility. Then you can run “sudo make install” :
    •     make
          sudo make install
  2. If you did not want to run “make install”, refer to the InstallGuide

Setelah itu,

Now you have to configure OpenCV. First, open the opencv.conf file with the following code:

sudo gedit /etc/ld.so.conf.d/opencv.conf

Add the following line at the end of the file(it may be an empty file, that is ok) and then save it:

/usr/local/lib

Run the following code to configure the library:

sudo ldconfig

Now you have to open another file:

sudo gedit /etc/bash.bashrc

Add these two lines at the end of the file and save it:

PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
export PKG_CONFIG_PATH

Finally, close the console and open a new one, restart the computer or logout and then login again. OpenCV will not work correctly until you do this.

There is a final step to configure Python with OpenCV. You need to copy the file cv.so into the correct place. You can do that by just executing the following command:

sudo cp /usr/local/lib/python2.7/site-packages/cv.so /usr/local/lib/python2.7/dist-packages/cv.so

referensi:

http://opencv.willowgarage.com/wiki/InstallGuide%20:%20Debian

Installing OpenCV 2.2 in Ubuntu 11.04

http://www.wikihow.com/Compile-a-C/C%2B%2B-Program-in-Ubuntu

______________________________________________________

KODE DAN APLIKASI

Contoh aplikasi C++ (file .cpp) color filtering http://mablresearch.rit.edu/wiki/index.php/Color_filtering_GUI_using_openCV

//##using C++ library##
#include <iostream>
using namespace std;
#include <stdlib.h>
//##using openCV library##
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"
using namespace cv;
int main ( int argc, char **argv ) //--------------MAIN BODY---------------
{
VideoCapture webCam(0); // video source for webcam
webCam.set(CV_CAP_PROP_FRAME_WIDTH,640);
webCam.set(CV_CAP_PROP_FRAME_HEIGHT,480);
// slices matrcies that hold H,S and V
vector<Mat> slices;
// Cross Element for Erosion/Dilation
Mat cross = getStructuringElement(MORPH_CROSS, Size(5,5));
// create matrices to hold image
Mat camImage;		// raw image from webcam
Mat blurImage;		// blur image
Mat hsvImage;		// hsv image 
Mat hue;			// hue channel
Mat hue1;			// Hue upper bound
Mat hue2;			// Hue lower bound
Mat hue3;			// hue color filtering
Mat sat;			// Sat channel
Mat sat1;			// Sat upper bound
Mat sat2;			// sat lower bound
Mat sat3;			// sat color filtering
Mat val;			// Val channel
Mat val1;			// Val upper bound
Mat val2;			// Val lower bound
Mat val3;			// Val color filtering
Mat erd;			// Erosion Image
Mat dia;			// dialate image
Mat HnS;			// sat and hue channel
Mat HSV;			// HSV color fiter detected

// slide bar values
int HuethresH =0, 
HuethresL =0,
SatthresL =0,
SatthresH = 0,
ValthresL =0,
ValthresH = 0,
erosionCount = 1,
blurSize = 3;

// new window
cvNamedWindow("Color Tune",CV_WINDOW_NORMAL);

// make tune bar
cvCreateTrackbar( "Hue UpperT","Color Tune", &HuethresH, 255, 0 );
cvCreateTrackbar ("Hue LowerT","Color Tune", &HuethresL,255, 0);
cvCreateTrackbar( "Sat UpperT","Color Tune", &SatthresH, 255, 0 );
cvCreateTrackbar( "Sat LowerT","Color Tune", &SatthresL, 255, 0 );
cvCreateTrackbar( "Val UpperT","Color Tune", &ValthresH, 255, 0 );
cvCreateTrackbar( "Val LowerT","Color Tune", &ValthresL, 255, 0 );
cvCreateTrackbar ("EroTime","Color Tune", &erosionCount,15, 0);
cvCreateTrackbar ("BlurSize","Color Tune", &blurSize,15, 0);
// check blurSize bound
if(blurSize == 0)
blurSize = 1; //reset blurSize

// get and display webcam image
while(1)
{
 // get new image over and over from webcam
 webCam >> camImage;

 // check blurSize bound
if(blurSize == 0)
blurSize = 1; //reset blurSize

// blur image
//blur(camImage, blurImage, Size(11,11));
blur(camImage, blurImage, Size(blurSize,blurSize));

// conver raw image to hsv
cvtColor (camImage, hsvImage, CV_RGB2HSV);

// check blurSize bound
if(blurSize == 0)
blurSize = 1; //reset blurSize
blur(hsvImage, hsvImage, Size(blurSize,blurSize));
//blur(hsvImage, hsvImage, Size(5,5));

// split image to H,S and V images
split(hsvImage,slices);

slices[0].copyTo (hue); // get the hue channel
slices[1].copyTo(sat); // get the sat channel
slices[2].copyTo(val); // get the V channel
//apply threshold HUE upper/lower for color range
threshold (hue,hue1,HuethresL,255, CV_THRESH_BINARY); // get lower bound
threshold (hue, hue2,HuethresH,255, CV_THRESH_BINARY_INV); // get upper bound

hue3 = hue1 &hue2; // multiply 2 matrix to get the color range

// apply thresshold for Sat channel
threshold (sat,sat1,SatthresL,255, CV_THRESH_BINARY); // get lower bound
threshold (sat, sat2,SatthresH,255, CV_THRESH_BINARY_INV); // get upper bound
sat3 = sat1 & sat2; // multiply 2 matrix to get the color range

// apply thresshold for Val channel
threshold (val,val1,SatthresL,255, CV_THRESH_BINARY); // get lower bound
threshold (val, val2,SatthresH,255, CV_THRESH_BINARY_INV); // get upper bound
val3 = val1 & val2; // multiply 2 matrix to get the color range
// combine sat and hue filter together
HnS = sat3 & hue3;
// erode and dialation to reduce noise
erode(HnS,erd,cross,Point(-1,-1),erosionCount); // do erode
dilate(HnS,dia,cross,Point(-1,-1),erosionCount);// do dialate
// combine sat, val and hue filter together
HSV = sat3 & hue3 & val3;

// erode and dialation to reduce noise
erode(HSV,erd,cross,Point(-1,-1),erosionCount); // do erode
dilate(HSV,dia,cross,Point(-1,-1),erosionCount); // do dialate

// display image over and over
imshow("Webcam Orignal", camImage);
//imshow("Blur", blurImage);
//imshow("HSV Image", hsvImage);
//imshow("Hue channel",hue);
//imshow("Lower bound",hue1);
//imshow("Upper bound", hue2);
//imshow("L channel", Val);
//imshow("Color detected", hue3);
//imshow("Erosion",erd);
imshow("Hue color",hue3);
//imshow("Sat channel",sat);
imshow("Sat color",sat3);
//imshow("Val color",val3);
imshow("Sat and Hue",HnS);
imshow("HSV",HSV);
// Pause for highgui to process image painting
cvWaitKey(5);
}
//------CLEAN UP------- 
cvDestroyAllWindows();
}

_____________________________________________________

Aplikasi Color Tracking dengan library cvblob

Terlebih dahulu download budel file-nya dan extract. File dapat di diwnload di http://code.google.com/p/cvblob/. Setelah itu install dengan cmake

COMPILING AND INSTALLING

In Linux, if you have unpacked the source in $CVBLOB, enter in a console:

cd $CVBLOB
cmake .
make
sudo make install

lengkapnya bisa dilihat di readme.txt nya.

Jika sudah selesai maka bisa dicoba aplikasi samplenya.

#include <iostream>
#include <iomanip>

#if (defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) || (defined(__APPLE__) & defined(__MACH__)))
#include <cv.h>
#include <highgui.h>
#else
#include <opencv/cv.h>
#include <opencv/highgui.h>
#endif

#include <cvblob.h>
using namespace cvb;

int main()
{
  CvTracks tracks;

  cvNamedWindow("red_object_tracking", CV_WINDOW_AUTOSIZE);

  CvCapture *capture = cvCaptureFromCAM(0);
  cvGrabFrame(capture);
  IplImage *img = cvRetrieveFrame(capture);

  CvSize imgSize = cvGetSize(img);

  IplImage *frame = cvCreateImage(imgSize, img->depth, img->nChannels);

  IplConvKernel* morphKernel = cvCreateStructuringElementEx(5, 5, 1, 1, CV_SHAPE_RECT, NULL);

  //unsigned int frameNumber = 0;
  unsigned int blobNumber = 0;

  bool quit = false;
  while (!quit&&cvGrabFrame(capture))
  {
    IplImage *img = cvRetrieveFrame(capture);

    cvConvertScale(img, frame, 1, 0);

    IplImage *segmentated = cvCreateImage(imgSize, 8, 1);

    // Detecting red pixels:
    // (This is very slow, use direct access better...)
    for (unsigned int j=0; j<imgSize.height; j++)
      for (unsigned int i=0; i<imgSize.width; i++)
      {
    CvScalar c = cvGet2D(frame, j, i);

    double b = ((double)c.val[0])/255.;
    double g = ((double)c.val[1])/255.;
    double r = ((double)c.val[2])/255.;
    unsigned char f = 255*((r>0.2+g)&&(r>0.2+b));

    cvSet2D(segmentated, j, i, CV_RGB(f, f, f));
      }

    cvMorphologyEx(segmentated, segmentated, NULL, morphKernel, CV_MOP_OPEN, 1);

    //cvShowImage("segmentated", segmentated);

    IplImage *labelImg = cvCreateImage(cvGetSize(frame), IPL_DEPTH_LABEL, 1);

    CvBlobs blobs;
    unsigned int result = cvLabel(segmentated, labelImg, blobs);
    cvFilterByArea(blobs, 500, 1000000);
    cvRenderBlobs(labelImg, blobs, frame, frame, CV_BLOB_RENDER_BOUNDING_BOX);
    cvUpdateTracks(blobs, tracks, 200., 5);
    cvRenderTracks(tracks, frame, frame, CV_TRACK_RENDER_ID|CV_TRACK_RENDER_BOUNDING_BOX);

    cvShowImage("red_object_tracking", frame);

    /*std::stringstream filename;
    filename << "redobject_" << std::setw(5) << std::setfill('0') << frameNumber << ".png";
    cvSaveImage(filename.str().c_str(), frame);*/

    cvReleaseImage(&labelImg);
    cvReleaseImage(&segmentated);

    char k = cvWaitKey(10)&0xff;
    switch (k)
    {
      case 27:
      case 'q':
      case 'Q':
        quit = true;
        break;
      case 's':
      case 'S':
        for (CvBlobs::const_iterator it=blobs.begin(); it!=blobs.end(); ++it)
        {
          std::stringstream filename;
          filename << "redobject_blob_" << std::setw(5) << std::setfill('0') << blobNumber << ".png";
          cvSaveImageBlob(filename.str().c_str(), img, it->second);
          blobNumber++;

          std::cout << filename.str() << " saved!" << std::endl;
        }
        break;
    }

    cvReleaseBlobs(blobs);

    //frameNumber++;
  }

  cvReleaseStructuringElement(&morphKernel);
  cvReleaseImage(&frame);

  cvDestroyWindow("red_object_tracking");

  return 0;
}

Berikut adalah screenshot dari aplikasi di atas.

______________________________________________________

Daftar Pustaka

http://opencv.willowgarage.com/wiki/InstallGuide

http://opencv.willowgarage.com/wiki/InstallGuide%20%3A%20Debian

http://opencv.willowgarage.com/wiki/InstallGuide_Linux

Installing OpenCV 2.2 in Ubuntu 11.04

http://thebitbangtheory.wordpress.com/2011/10/23/how-to-install-opencv-2-3-1-in-ubuntu-11-10-oneiric-ocelot-with-python-support/

http://www.wikihow.com/Compile-a-C/C%2B%2B-Program-in-Ubuntu

http://ubuntuforums.org/showthread.php?t=1929574&page=2

http://stackoverflow.com/questions/4658764/opencv-unable-to-capture-image-from-isight-webcam

http://mablresearch.rit.edu/wiki/index.php/Color_filtering_GUI_using_openCV

http://mechomaniac.com/OpenCVBallTracking

https://sites.google.com/site/andrewssobral/pandaboard

http://is.gd/rVpk

http://code.google.com/p/cvblob/

Akuisisi Gambar Dari Webcam Menggunakan Aforge.Net Library Berbasis Bahasa C#

Terlebih dahulu install library AForge.NET di

http://www.aforgenet.com/framework/downloads.html

Buatlah sebuah project baru dan buatlah tampilan GUI seperti berikut.

 

Control Property Value
pictureBox1 BorderStyle FixedSingle
pictureBox1 SizeMode StretchImage
comboBox1 DropDownStyle DropDownList
Button1 Text Mulai Webcam
Form1 Text Wangready Webcam

Berikut code untuk form diatas.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AForge.Video;             //add reference
using AForge.Video.DirectShow;  //add reference

namespace wangready_webcam_aforge
{
    public partial class Form1 : Form
    {
        //reference sudah ditambahkan
        private FilterInfoCollection VideoCaptureDevices;//mengumpulkan setiap perangkat video yg terdeteksi
        private VideoCaptureDevice FinalVideoSource;//menampung perangkat video yang akan digunakan
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //pertama add reference semua Aforge.video.dll dan Aforge.video.directshow.dll
            VideoCaptureDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            //sekarang perangkat video sudah tersimpan pada array di atas
            foreach(FilterInfo VideoCaptureDevice in VideoCaptureDevices)
            {
                comboBox1.Items.Add(VideoCaptureDevice.Name);
            }
            //jalankan aplikasi ini maka akan didapatkan semua perangkat video yang terscan di pc
            comboBox1.SelectedIndex = 0;
            //sekarang akan ditambahkan kode untuk menjalankan webcam dan menampiljkan gambar pada picturebox
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //tambahkan kode berikut untuk menentukan perangkat sumber dari video
            FinalVideoSource = new VideoCaptureDevice(VideoCaptureDevices[comboBox1.SelectedIndex].MonikerString);
            FinalVideoSource.NewFrame += new NewFrameEventHandler(FinalVideoSource_NewFrame);
            FinalVideoSource.Start();
        }

        void FinalVideoSource_NewFrame(object sender, NewFrameEventArgs eventArgs) 
        {
            //sekarang kita tambahkan kode berikut untuk menampilkan new frame event (frame dari webcam) untuk menampilkan gambar pada picturebox
            Bitmap image = (Bitmap)eventArgs.Frame.Clone();//bitmap boxing
            pictureBox1.Image = image;
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            //kita tambahkan kode untuk membuat webcam berhenti bekerja
            //kapanpun form telah ditutup maka webcam akan berhenti bekerja secara automatis
            if (FinalVideoSource.IsRunning)
            {
                FinalVideoSource.Stop();
            }
            //selesai
            //sekarang kita jalankan
        }
    }
}

Download source code http://www.mediafire.com/file/6zljog12nbmniw1/wangready_webcam_aforge.rar

______________________________________

Daftar Pustaka

vimeo.com/7526663

Sensor Kamera CMUcam3

Tujuan dari proyek CMUcam adalah untuk memberikan kemampuan visi sederhana untuk embedded system kecil dalam bentuk sebuah sensor cerdas. CMUcam3 memperluas atas gagasan ini dengan menyediakan fleksibel dan mudah untuk menggunakan lingkungan pengembangan open source yang melengkapi platform perangkat keras biaya rendah. CMUcam3 ini berbasis ARM7TDMI sepenuhnya programmable embedded computer vision sensor. Prosesor utama adalah LPC2106 NXP terhubung ke kamera CMOS sensor Omnivision modul. Custom C code dapat dikembangkan untuk CMUcam3 menggunakan port dari GNU toolchain bersama dengan satu set library open source dan program contoh. Pemrograman menggunakan port serial port tanpa perangkat eksternal tabahan.

Modul embedded vision sensor berbasis Omnivision CMOS camera dan mikrokontroler ARM7TDMI (Philips NXP LPC2106).
Spesifikasi:
– Programmable dan open source.
– RGB, resolusi CIF (352×288).
– Slot untuk MMC/SD card dengan FAT16 driver.
– 4 port servo controller.
– Kecepatan image processing 26 fps (frame/second).
– Kompresi JPEG software.
– Lua light-weight language interpreter.
– Raw images dumps melalui port serial.
– Mampu membuat histogram.
– Tersedia keluaran video analog B/W (PAL or NTSC).
– FIFO image buffer untuk image processing dengan resolusi tinggi.
– Antarmuka serial UART TTL & RS-232.
– Mendukung Teleos 802.15.4, antarmuka jaringan Wireless Mote.

Untuk melakukan pemrograman software bisa didownload di link berikut. http://cmucam.org/wiki/Software. Jika menggunakan Windows dan saat proses installasi CygWin terdapat masalah, maka installer CygWin bisa didownload dari situsnya langsung http://cygwin.com/setup.exe.

Kelengkapan Software untuk melakukan programming pada CMUcam3

Windows: Cygwin-Installer (with packages), arm-gcc, Philips-Flash utility, .NET Runtime, CMUcam3 frame grabber

Linux: arm-gcc compiled tar, LPC-isp Flash Utility

Source Code

Pada situs http://cmucam.org/wiki/Downloads terdapat CC3 Source Tree yang bisa kita gunakan sebagai acuan dasar. Jadi kita tinggal mengedit saja sesuai keperluan.

CMUcam2 pada CMUcam3

CMUcam3 dapat diisi dengan menggunakan CMUcam2 Emulation HEX file (http://cmucam.org/attachment/wiki/Downloads/cmucam2_lpc2106-cmucam3.hex?format=raw) agar mempunyai kemampuan seperti CMUcam2. Untuk mengetes firmware tersebut bisa digunakan CMUcam2 GUI (http://www.cs.cmu.edu/~cmucam2/CMUcam2GUI.zip) yang berbasis java. Emulator java sendiri bisa didownload pada situs berikut. http://www.oracle.com/technetwork/java/javase/downloads/index.html.

Compile Source Code

Untuk mengedit file.c bisa menggunakan wordpad. Setelah semua software kelengkapan telah terinstall dengan baik, maka kita bisa langsung mencoba untuk mengkompail source code CC3 Source. Berikut urutan langkah-langkah untuk mengkompail file yang ada pada CC3 Source folder Project:

1. Jalankan CygWin (windows, console pada linux)

2. Ketik “cd alamat_direktori_project_yang dipilih”. Enter.

3. Ketik “make”, enter. Jika terdapat error, cobalah untuk mengulangi langkah 2 dengan mengganti alamat direktori project menjadi alamat dari folder CC3, enter. Lalu ketik “make”, enter. Setelah selesai, kembali ke langkah 2 untuk mengkompail file terpilih pada folder Project. Jika berhasil, maka pada folder yang terpilih akan ada file yang berekstensi .hex yang akan dimasukan ke dalam CMUcam3.

Memasukan .Hex pada CMUcam3

Pertama, matikan CMUcam3 lalu nyalakan kembali sambil menekan pushbutton yang terdapat pada modul beberapa saat. Jika CMUcam3 sudah siap diprogram maka 2 led akan menyala hijau dan merah. Buka software Philips-Flash utility. Pastikan pilih COM yang akan digunakan. Klik Erase. Lalu pilih juga file .hex yang akan ditanam pada CMUcam3 dan Upload to flash. Setelah selesai, matikan CMUcam3 dan nyalakan kembali agar CMUcam3 keluar dari keadaan siap diprogram menjadi menjalankan program.

Interface CMUcam3 dengan Mikrokontroler

CMUcam3 memiliki pin UART yang tentunya bisa kita manfaatkann untuk berkomunikasi dengan mikrokontroler. Disana terdapat koneksi dengan mode RS232 atau TTL. Jika menggunakan mode RS232 maka kita tinggal mengkoneksikannya dengan conector DB9 pada CMUcam3. Akan tetapi, jika menggunakan mode TTL maka ada jumper yang harus dilepas dan hati-hati jika mengkoneksikan CMUcam3 dengan pin TTL ini karena UART dari ARM yang rawan terbakar. Perhatikan level tegangan dan konsumsi arus antara CMUcam3 dan mikrokontroler yang digunakan. Disarankan gunakan saja RS232 karena koneksi terproteksi oleh IC MAX232 yang terdapat pada modul CMUcam3.

Berikut contoh program untuk CMUcam3 yang bisa digunakan untuk deteksi warna yang bisa terkoneksi ke mikrokontroler lain.

________________________________________________________

#include <stdio.h>
#include <stdlib.h>
#include <cc3.h>
#include <cc3_ilp.h>
#include <cc3_color_track.h>
#include <cc3_color_info.h>
#include <cc3_frame_diff.h>

void simple_track_color(cc3_track_pkt_t *t_pkt);
void simple_get_mean (cc3_color_info_pkt_t * s_pkt);
int main(void) {
cc3_color_info_pkt_t s_pkt;
uint8_t data;
uint32_t threshold;
int32_t tmp;
cc3_track_pkt_t t_pkt;
uint32_t x0, y0, x1, y1;
cc3_frame_diff_pkt_t fd_pkt;
cc3_uart_init (0, CC3_UART_RATE_115200,
CC3_UART_MODE_8N1, CC3_UART_BINMODE_TEXT);
cc3_camera_init ();
cc3_camera_set_resolution(CC3_CAMERA_RESOLUTION_LOW);
cc3_pixbuf_frame_set_subsample(CC3_SUBSAMPLE_NEAREST, 2, 1);
// init pixbuf with full size width and height

x0 = 0;
x1 = cc3_g_pixbuf_frame.raw_width;
y0 = 0;
y1 = cc3_g_pixbuf_frame.raw_height;
fd_pkt.coi = 1;
fd_pkt.template_width = 8;
fd_pkt.template_height = 8;
t_pkt.track_invert = false;
t_pkt.noise_filter = 0;
cc3_pixbuf_frame_set_roi (x0, y0, x1, y1);
// Load in color tracking parameters

t_pkt.lower_bound.channel[0] = 168;
t_pkt.upper_bound.channel[0] = 240;
t_pkt.lower_bound.channel[1] = 29;
t_pkt.upper_bound.channel[1] = 36;
t_pkt.lower_bound.channel[2] = 14;
t_pkt.upper_bound.channel[2] = 18;

//set servo awal posisi
cc3_gpio_set_servo_position(0,128);
while(true) {
simple_track_color(&t_pkt);

data = getchar();
if(data==’x’)
{
printf(“%c”,t_pkt.centroid_x);
}
else if(data==’y’)
{
printf(“%c”,t_pkt.centroid_y);
}
else if(data==’d’)
{
printf(“%c”,(uint8_t)t_pkt.int_density/10);
}
else if(data==’r’) // L R
{
t_pkt.lower_bound.channel[0] = getchar();
}
else if(data==’s’) // H R
{
t_pkt.upper_bound.channel[0] = getchar();
}
else if(data==’g’) // L G
{
t_pkt.lower_bound.channel[1] = getchar();
}
else if(data==’h’) // H G
{
t_pkt.upper_bound.channel[1] = getchar();
}
else if(data==’b’) // L B
{
t_pkt.lower_bound.channel[2] = getchar();
}
else if(data==’c’) // H B
{
t_pkt.upper_bound.channel[2] = getchar();
}
else if(data==’p’)
{
printf(“\n centroid=[%d,%d] bounding box=[%d,%d,%d,%d] num pix=[%d] density=[%d] \n”,
t_pkt.centroid_x, t_pkt.centroid_y,
t_pkt.x0,t_pkt.y0,t_pkt.x1,t_pkt.y1,
t_pkt.num_pixels, t_pkt.int_density );
}
else if(data==’w’)
{
printf(“\n R=[%d,%d] G=[%d,%d] B=[%d,%d] \n”,
t_pkt.lower_bound.channel[0],t_pkt.upper_bound.channel[0],
t_pkt.lower_bound.channel[1],t_pkt.upper_bound.channel[1],
t_pkt.lower_bound.channel[2],t_pkt.upper_bound.channel[2]);
}
else if(data==’a’)
{
// init pixbuf with width and height
cc3_pixbuf_load ();

threshold = 30;

// set window to 1/2 size
x0 = cc3_g_pixbuf_frame.x0 + cc3_g_pixbuf_frame.width / 4;
x1 = cc3_g_pixbuf_frame.x1 – cc3_g_pixbuf_frame.width / 4;
y0 = cc3_g_pixbuf_frame.y0 + cc3_g_pixbuf_frame.width / 4;
y1 = cc3_g_pixbuf_frame.y1 – cc3_g_pixbuf_frame.width / 4;
cc3_pixbuf_frame_set_roi (x0, y0, x1, y1);
// call get mean
simple_get_mean (&s_pkt);
// set window back to full size
x0 = 0;
x1 = cc3_g_pixbuf_frame.raw_width;
y0 = 0;
y1 = cc3_g_pixbuf_frame.raw_height;
cc3_pixbuf_frame_set_roi (x0, y0, x1, y1);
// fill in parameters and call track color
tmp = s_pkt.mean.channel[0] – threshold;
if (tmp < 16)
tmp = 16;
if (tmp > 240)
tmp = 240;
t_pkt.lower_bound.channel[0] = tmp;
tmp = s_pkt.mean.channel[0] + threshold;
if (tmp < 16)
tmp = 16;
if (tmp > 240)
tmp = 240;
t_pkt.upper_bound.channel[0] = tmp;
tmp = s_pkt.mean.channel[1] – threshold;
if (tmp < 16)
tmp = 16;
if (tmp > 240)
tmp = 240;
t_pkt.lower_bound.channel[1] = tmp;
tmp = s_pkt.mean.channel[1] + threshold;
if (tmp < 16)
tmp = 16;
if (tmp > 240)
tmp = 240;
t_pkt.upper_bound.channel[1] = tmp;
tmp = s_pkt.mean.channel[2] – threshold;
if (tmp < 16)
tmp = 16;
if (tmp > 240)
tmp = 240;
t_pkt.lower_bound.channel[2] = tmp;
tmp = s_pkt.mean.channel[2] + threshold;
if (tmp < 16)
tmp = 16;
if (tmp > 240)
tmp = 240;
t_pkt.upper_bound.channel[2] = tmp;

}
else
{
printf(“n”);
}
}
}
void simple_track_color(cc3_track_pkt_t *t_pkt)
{
cc3_image_t img;
img.channels = 3;
img.width = cc3_g_pixbuf_frame.width;
img.height = 1;  // image will hold just 1 row for scanline processing

img.pix = cc3_malloc_rows (1);
if (img.pix == NULL) {
return;
}
cc3_pixbuf_load ();
if (cc3_track_color_scanline_start (t_pkt) != 0) {
while (cc3_pixbuf_read_rows (img.pix, 1)) {
// This does the HSV conversion

// cc3_rgb2hsv_row(img.pix,img.width);

cc3_track_color_scanline (&img, t_pkt);
}
}
cc3_track_color_scanline_finish (t_pkt);
free (img.pix);
return;
}

void simple_get_mean (cc3_color_info_pkt_t * s_pkt)
{
cc3_image_t img;
img.channels = 3;
img.width = cc3_g_pixbuf_frame.width;
img.height = 1;               // image will hold just 1 row for scanline processing
img.pix = malloc (3 * img.width);

cc3_pixbuf_load ();
if (cc3_color_info_scanline_start (s_pkt) != 0) {
while (cc3_pixbuf_read_rows (img.pix, 1)) {
cc3_color_info_scanline (&img, s_pkt);
}
cc3_color_info_scanline_finish (s_pkt);
}
free (img.pix);
}
______________________________________________________________
Keterangan instruksi untuk interfacing dengan CMUcam3 dari program di atas.

‘x’ –> jika mikrokontroler mengirim nilai ascii dari huruf x , CMUcam3 akan mengirim balasan hex titik tengah koordinat sumbu x  warna yang terdeteksi.

‘y’ –> jika mikrokontroler mengirim nilai ascii dari huruf y , CMUcam3 akan mengirim balasan hex titik tengah koordinat sumbu y  warna yang terdeteksi

‘d’ –> jika mikrokontroler mengirim nilai ascii dari huruf d , CMUcam3 akan mengirim balasan hex nilai density yaitu nilai kepadatan pixel warna yang terdeteksi dibagi 10.

‘r’ –> jika mikrokontroler mengirim nilai ascii dari huruf r ,dilanjutkan dengan nilai hex filter warna merah (0-255) minimum.

‘s’ –> jika mikrokontroler mengirim nilai ascii dari huruf s , dilanjutkan dengan nilai hex filter warna merah (0-255) maximum.

‘g’ –> jika mikrokontroler mengirim nilai ascii dari huruf g , dilanjutkan dengan nilai hex filter warna hijau (0-255) minimum.

‘h’ –> jika mikrokontroler mengirim nilai ascii dari huruf h , dilanjutkan dengan nilai hex filter warna hijau (0-255) maximum.

‘b’ –> jika mikrokontroler mengirim nilai ascii dari huruf b , dilanjutkan dengan nilai hex filter warna biru (0-255) minimum.

‘c’ –> jika mikrokontroler mengirim nilai ascii dari huruf c, dilanjutkan dengan nilai hex filter warna biru (0-255) maximum.

‘p’ –> jika mikrokontroler mengirim nilai ascii dari huruf p, maka CMUcam3 akan mengirim ascii centroid=[%d,%d] bounding box=[%d,%d,%d,%d] num pix=[%d] density=[%d]

‘w’ –> jika mikrokontroler mengirim nilai ascii dari huruf w, maka CMUcam akan mengirim ascii R=[%d,%d] G=[%d,%d] B=[%d,%d] yaitu nilai filter warna yang digunakan.

‘a’ –> jika mikrokontroler mengirim nilai ascii dari huruf a, CMUcam3 akan meng-grab warna yang ada dihadapannya dan digunakan sebagai warna yang difilter atau dideteksi selanjutnya.

Untuk mengujinya bisa juga dihubungkan dengan hyperterminal pada PC.

Berikut link untuk mendownload .hex dari program di atas. http://www.mediafire.com/file/fo8jtyjwu7w77dr/simple-track-color-wangready.wordpress.com_lpc2106-cmucam3.hex

______________________________________________________________

Berikut contoh schematic rangkaian interface CMUcam3 dengan mikrokontroler atmega128 11.0592MHz + LCD 2×16 yang berkomunikasi menggunakan UART RS232

______________________________________________________________

Contoh program dengan CVAVR untuk mendeteksi adanya warna yang difilter

/*****************************************************
Chip type           : ATmega128
Program type        : Application
Clock frequency     : 11.059200 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 1024
*****************************************************/

#include <mega128.h>
#include <delay.h>

// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x1B ;PORTA
#endasm
#include <lcd.h>

#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// USART0 Receiver buffer
#define RX_BUFFER_SIZE0 8
char rx_buffer0[RX_BUFFER_SIZE0];

#if RX_BUFFER_SIZE0<256
unsigned char rx_wr_index0,rx_rd_index0,rx_counter0;
#else
unsigned int rx_wr_index0,rx_rd_index0,rx_counter0;
#endif

// This flag is set on USART0 Receiver buffer overflow
bit rx_buffer_overflow0;

// USART0 Receiver interrupt service routine
interrupt [USART0_RXC] void usart0_rx_isr(void)
{
char status,data;
status=UCSR0A;
data=UDR0;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
rx_buffer0[rx_wr_index0]=data;
if (++rx_wr_index0 == RX_BUFFER_SIZE0) rx_wr_index0=0;
if (++rx_counter0 == RX_BUFFER_SIZE0)
{
rx_counter0=0;
rx_buffer_overflow0=1;
};
};
}

#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART0 Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter0==0);
data=rx_buffer0[rx_rd_index0];
if (++rx_rd_index0 == RX_BUFFER_SIZE0) rx_rd_index0=0;
#asm(“cli”)
–rx_counter0;
#asm(“sei”)
return data;
}
#pragma used-
#endif

// USART0 Transmitter buffer
#define TX_BUFFER_SIZE0 8
char tx_buffer0[TX_BUFFER_SIZE0];

#if TX_BUFFER_SIZE0<256
unsigned char tx_wr_index0,tx_rd_index0,tx_counter0;
#else
unsigned int tx_wr_index0,tx_rd_index0,tx_counter0;
#endif

// USART0 Transmitter interrupt service routine
interrupt [USART0_TXC] void usart0_tx_isr(void)
{
if (tx_counter0)
{
–tx_counter0;
UDR0=tx_buffer0[tx_rd_index0];
if (++tx_rd_index0 == TX_BUFFER_SIZE0) tx_rd_index0=0;
};
}

#ifndef _DEBUG_TERMINAL_IO_
// Write a character to the USART0 Transmitter buffer
#define _ALTERNATE_PUTCHAR_
#pragma used+
void putchar(char c)
{
while (tx_counter0 == TX_BUFFER_SIZE0);
#asm(“cli”)
if (tx_counter0 || ((UCSR0A & DATA_REGISTER_EMPTY)==0))
{
tx_buffer0[tx_wr_index0]=c;
if (++tx_wr_index0 == TX_BUFFER_SIZE0) tx_wr_index0=0;
++tx_counter0;
}
else
UDR0=c;
#asm(“sei”)
}
#pragma used-
#endif

// Standard Input/Output functions
#include <stdio.h>

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Port E initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTE=0x00;
DDRE=0x00;

// Port F initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTF=0x00;
DDRF=0x00;

// Port G initialization
// Func4=In Func3=In Func2=In Func1=In Func0=In
// State4=T State3=T State2=T State1=T State0=T
PORTG=0x00;
DDRG=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
ASSR=0x00;
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// OC1C output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
OCR1CH=0x00;
OCR1CL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// Timer/Counter 3 initialization
// Clock source: System Clock
// Clock value: Timer 3 Stopped
// Mode: Normal top=FFFFh
// Noise Canceler: Off
// Input Capture on Falling Edge
// OC3A output: Discon.
// OC3B output: Discon.
// OC3C output: Discon.
// Timer 3 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR3A=0x00;
TCCR3B=0x00;
TCNT3H=0x00;
TCNT3L=0x00;
ICR3H=0x00;
ICR3L=0x00;
OCR3AH=0x00;
OCR3AL=0x00;
OCR3BH=0x00;
OCR3BL=0x00;
OCR3CH=0x00;
OCR3CL=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
// INT3: Off
// INT4: Off
// INT5: Off
// INT6: Off
// INT7: Off
EICRA=0x00;
EICRB=0x00;
EIMSK=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
ETIMSK=0x00;

// USART0 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART0 Receiver: On
// USART0 Transmitter: On
// USART0 Mode: Asynchronous
// USART0 Baud rate: 115200
UCSR0A=0x00;
UCSR0B=0xD8;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x05;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// LCD module initialization
lcd_init(16);

// Global enable interrupts
#asm(“sei”)

//delay, menunggu cmucam3 benar-benar aktif
delay_ms(1000);

//setting nilai filter RGB
//deeteksi warna Dark orange (web colour) : http://en.wikipedia.org/wiki/Orange_%28colour%29
//centre RGB (255,140,0)
putchar(‘r’);
putchar(245);   // set nilai red minimum

putchar(‘s’);
putchar(255);   // set nilai red maksimum

putchar(‘g’);
putchar(130);   // set nilai green minimum

putchar(‘h’);
putchar(150);   // set nilai green maksimum

putchar(‘b’);
putchar(0);   // set nilai blue minimum

putchar(‘c’);
putchar(10);   // set nilai blue maksimum

while (1)
{
// Place your code here
//meminta nilai density dari CMUCAM3 dan menampilakan hasilnya pada LCD atmega128
putchar(‘d’);
if(getchar() > 0)
{
lcd_clear();
lcd_gotoxy(0,1);
lcd_putsf(“warna terdeteksi”);
}
else
{
lcd_clear();
lcd_gotoxy(0,1);
lcd_putsf(“tidak ada warna terdeteksi”);
}
delay_ms(300);
};
}
______________________________________________________________

Daftar Pustaka

http://cmucam.org

http://www.cmucam.org/discussion/message/1343

http://digi-ware.com

http://en.wikipedia.org/wiki/Orange_%28colour%29

Simple Color Tracking Menggunakan Webcam Dengan Library AForge.NET

Beberapa waktu lalu saat sempat terpikir untuk membuat aplikasi image processing, saya menemukan sebuah library yang saya kira cukup simple untuk diimplementasikan yaitu AForge.NET untuk bahasa C#. Alhamdulillah saat itu ada beberapa perangkat yang tersedia di laboratorium sehigga bisa terealisasi. Berikut uraian saya.

Simple Color Tracking

Abstraksi

Robotics vision adalah salah satu bidang kajian dalam dunia robotika. Salah satu langkah awal untuk memulainya adalah robot mampu mengenali warna. Dalam kesempatan kali ini, robot didisain mampu mengenali warna lalu mengikuti gerak dari warna yang terdeteksi tersebut. Sebagai sensornya digunakan kamera dan aktuator yang digunakan adalah motor servo. Sedangkan otak dari sistem tersebut masih menggunakan PC mengingat harga IC untuk aplikasi real time sangat mahal.

1. Pendahuluan

Penggunaan kamera(digital) dalam dunia robotik dikenal sebagai robotics vision. Seperti halnya pada manusia, kamera dapat didisain sebagai mata pada robot. Dengan mata, robot dapat lebih leluasa “melihat” lingkungannya sebagaimana manusia.

Dalam dua dasawarsa terakhir ini tenologi robotics vision berkembang sangat pesat. Kemajuan ini dicapai berkat perkembangan teknologi IC yang makin kompak dan cepat, dan kemajuan di bidang komputer (sebagai pengolah), baik perangkat keras maupun perangkat lunak. Teknologi optiknya pada dasarnya masih tetap menggunakan teknik yang telah berkembang sejak lebih dari 100 tahun yang lalu, yaitu penggunaan konfigurasi lensa cembung dan cekung.

2. Deteksi Warna

Ada banyak metode yang bisa digunakan untuk dapat mendeteksi warna menggunakan kamera. Diantaranya adalah dengan menggunakan Euclidean Color Filtering. Filter ini memfilter piksel-piksel pada gambar yang berada – di dalam/di luar – dari lingkup RGB (Red Green Blue) dengan pusat dan radius terntentu. Filter tersebut membiarkan piksel-piksel dengan warna yang berada – di dalam/di luar –  dari lingkup yang telah ditentukan dan mengisi sisanya dengan warna tertentu.

Setelah warna difilter maka untuk menghasilkan gambar yang lebih baik maka digunakan Erosion dan Dilatation. Erosion memberikan nilai minimum di sekitar piksel-piksel untuk setiap piksel dari citra hasil. Di sekitar piksel-piksel yang harus diproses, ditentukan oleh penataan elemen: 1 – untuk memproses tetangga piksel tersebut, -1 – untuk melewatinya. Filter sangan berguna terutama untuk pengolahan citra biner. Dimana filter ini menghapus piksel yang tidak dikelilingi dengan jumlah tertentu tetangganya. Ini memberi kemampuan untuk menghapus piksel nois (piksel yang berdiri sendiri) atau menyusutkan objek.

Dilatation, filter ini menetapkan nilai maksimum sekitar piksel untuk setiap piksel dari citra hasil. Di sekitar piksel-piksel yang harus diproses, yang ditentukan oleh penataan elemen: 1 – untuk memproses tetangga, -1 – untuk melewatinya. Filter ini berguna untuk pengolahan citra biner, di mana memungkinkan untuk melebarkan objek terpisah atau menggabungkan objek.

1. Diagram Alur

Input Gambar (dari webcam) –> Konversi data gambar ke dalam bentuk Bitmap (PC) –> Euclidean Color Filtering (PC) –> Erosion (PC) –> Dilatation (PC) –> Deteksi koordinat warna (PC) –> Pengiriman data ke mikrokontroler (PC – mikrokontroler) –> pengontrolan servo oleh mikrokontroler (mikrokontroler).

2. Pemograman

Untuk pemograman digunakan software Visual Studio 2008 dengan menggunakan bahasa C#. Alasan menggunakan bahasa C# adalah karena tersedianya library yang cocok bagi perancang, yaitu AForge.net. Pemograman pada VS 2008 dilakukan dengan menggunakan GUI. Selain itu, digunakan pula software CodeVision AVR sebagai compiler untuk mikrokontroler yang akan mengontrol servo secara mandiri.

3. Sistem Antarmuka PC – Mikrokontroler

Pengiriman data dari PC ke Mikrokontroler menggunakan RS232 dengan Baudrate disesuaikan. Jika posisi warna terdeteksi berada pada koordinat (0,0).

Jika posisi warna terdeteksi tidak berada pada koordinat (0,0).

4. Percobaan

Percobaan dilakukan dengan sejumlah warna. Objek berwarna tersebut digerak-gerakan di depan perangkat webcam-servo yang mempunyai 2 DOF (Degrees Of Freedom). Dengan sumbu Z sekitar 1800 dan sumbu X sekitar 600.

5. Hasil Percobaan

Robot mampu mengikuti arah objek. Jika robot kehilangan objek, maka robot akan bergerak ke arah saat objek terakhir terdeteksi. Proses deteksi warna ini masih terpengaruh oleh intensitas cahaya.

6. Kesimpulan

Kamera dapat mengikuti arah gerak dari objek berwarna yang telah ditentukan walaupun masih terdapat kekurangan pada algoritma juga pada  perancangan software dan hardware.

7. Daftar Pustaka

[1] Aforge.NET-Framework-Documentaion

[2] Lee, Wei-Meng, Practical .NET 2.0 Networking Projects, Apress, 2007.

[3] Pitowarno, Endra, Robotika Desain, Kontrol, dan Kecerdasan Buatan, Andi, Yogyakarta, 2006.

[4] www.aforgenet.com

[5] www.codeproject.com

[6] www.msdn.microsoft.com

8. Lampiran


Gambar 1. Tampilan software.

Gambar 2. Tampilan setting Euclidean Color Filter. Gambar 3. Foto Perangkat.

Berikut installer demo software simple color tracking.
http://www.mediafire.com/file/304priwevhameq0/simple%20color%20tracking.rar

Berikut beberapa link referensi lainnya.

http://www.aforgenet.com/articles/step_to_stereo_vision/

http://www.aforgenet.com/articles/lego_pan_tilt_camera/

Berikut Schematic untuk rangkaian kontroler servo.

Berikut link yang bisa didownload yang berisi PCB Project EAGLE beserta firmware (.hex) untuk attiny2313 berdasarkan schematic di atas.

http://www.mediafire.com/file/mqdrsjj3qoc7777/Color_Tracking-wangready.wordpress.com.rar

________________________________________________________________________________________

Update Servo Controller dengan Fuzzy Control System LINK.
________________________________________________________________________________________

project file http://www.mediafire.com/download/rap5garamf1peb9/P3_simple_color_tracking.rar