Anda di halaman 1dari 17

LAPORAN PENELITIAN

JURUSAN TEKNIK INFORMATIKA


STIKOM BALIKPAPAN

IMPLEMENTASI METODE CONTRAST


STRETCHING UNTUK MEMPERBAIKI
KONTRAS CITRA

oleh

Setyo Nugroho
Jurusan Teknik Informatika
STIKOM Balikpapan
2005
DAFTAR ISI

LANDASAN TEORI ........................................................................................................ 2


Citra Digital ........................................................................................................................ 2
Contrast Stretching ............................................................................................................. 2
Histogram ........................................................................................................................... 3

CARA PENELITIAN....................................................................................................... 5
File citra digital dengan format BMP ................................................................................. 5
Proses Contrast Stretching.................................................................................................. 6
Histogram ........................................................................................................................... 7
Statistik Citra ...................................................................................................................... 8

HASIL DAN PEMBAHASAN......................................................................................... 9

PENUTUP ....................................................................................................................... 11

DAFTAR PUSTAKA...................................................................................................... 11

LAMPIRAN .................................................................................................................... 12

1
LANDASAN TEORI

Citra Digital

Citra didefinisikan sebagai fungsi intensitas cahaya dua-dimensi f(x,y) dimana x dan y
menunjukkan koordinat spasial, dan nilai f pada suatu titik (x,y) sebanding dengan brightness (gray
level) dari citra di titik tersebut.
Citra digital adalah citra dengan f(x,y) yang nilainya di-digitalisasi-kan (dibuat diskrit)
baik dalam koordinat spasialnya maupun dalam gray levelnya. Digitalisasi dari koordinat spasial
citra disebut dengan image sampling, sedangkan digitalisasi dari gray level citra disebut dengan
gray-level quantization.
Citra digital dapat dibayangkan sebagai suatu matriks dimana baris dan kolomnya
menunjukkan suatu titik di dalam citra, dan nilai elemen matriks tersebut menunjukkan gray level
di titik tersebut. Elemen-elemen dari citra digital tersebut biasanya disebut dengan pixel, yang
merupakan singkatan dari picture elements.
Pada tulisan ini citra digital yang digunakan berukuran 256x256 pixel dan memiliki 256
gray level.

Contrast Stretching

Tujuan pengolahan citra digital adalah untuk mendapatkan citra baru yang lebih sesuai
untuk digunakan dalam aplikasi tertentu. Salah satu jenis pengolahan citra adalah yang disebut
dengan contrast stretching. Contrast stretching ini adalah teknik yang digunakan untuk
mendapatkan citra baru dengan kontras yang lebih baik daripada kontras dari citra asalnya.
Citra yang memiliki kontras rendah dapat terjadi karena kurangnya pencahayaan,
kurangnya bidang dinamika dari sensor citra, atau kesalahan setting pembuka lensa pada saat
pengambilan citra. Ide dari proses contrast stretching adalah untuk meningkatkan bidang dinamika
dari gray level di dalam citra yang akan diproses.
Proses contrast stretching termasuk proses perbaikan citra yang bersifat point processing,
yang artinya proses ini hanya tergantung dari nilai intensitas (gray level) satu pixel, tidak
tergantung dari pixel lain yang ada di sekitarnya.
Gambar 1 menunjukkan transformasi tipikal yang digunakan untuk contrast stretching.
Disini diasumsikan bahwa citra memiliki range gray level dari 0 sampai 255.

2
Pada gambar 1, c adalah gray level dari citra sebelum diproses dan d adalah gray level dari
citra setelah diproses. Titik (c1,d1) dan titik (c2,d2) akan menentukan bentuk dari fungsi
transformasi, dan dapat diatur untuk menentukan tingkat penyebaran grey level dari citra yang
dihasilkan.

255

d2

d1

0 c1 c2 255

c
Gambar 1
Fungsi contrast stretching

Jika c1=c2 dan d1=d2 maka transformasi akan berbentuk garis lurus yang berarti tidak ada
perubahan gray level pada citra yang dihasilkan.
Secara umum diasumsikan c1<=c2 dan d1<=d2 sehingga fungsi akan menghasilkan nilai
tunggal dan nilainya akan selalu naik.
Untuk menghitung nilai hasil transformasi tersebut, kita dapat membuat tiga fungsi
sebagai berikut:
Untuk c <= 0 < c1, maka d = c . (d1 / c1)
Untuk c1 <= c < c2, maka d = d1 + ( (c-c1) . ((d2-d1) / (c2-c1)) )
Untuk c2 <= c <=255, maka d = d2 + ( (c-c2) . (255-d2) / (255-c2) )

Histogram

Histogram dari citra digital dengan gray level dalam range [0,L-1] adalah fungsi diskrit
p(rk) = nk/n, dimana:
rk : gray level ke-k
nk : banyaknya pixel di dalam citra dengan gray level tersebut
n : jumlah seluruh pixel di dalam citra
k=0, 1, 2, …, L-1
Jika fungsi ini digambarkan dengan grafik maka akan memberikan deskripsi secara global
dari penampakan citra.

3
Gambar 2 berikut menunjukkan histogram dari empat jenis citra secara umum.

(a) Citra yang gelap:

(b) Citra yang terang:

(c) Citra berkontras rendah:

(d) Citra berkontras tinggi:

Gambar 2
Jenis-jenis dasar histogram

Histogram pada gambar (a) menunjukkan bahwa gray level terkonsentrasi di bagian kiri
atau bagian gelap dari range gray scale. Sebaliknya pada gambar (b) gray level terkonsentrasi di
bagian kanan atau bagian terang dari range gray scale. Pada gambar (c) histogram memiliki bentuk
yang sempit yang menunjukkan bahwa citra memiliki dynamic range rendah yang berarti
berkontras rendah. Sedangkan pada gambar (d) gray level tersebar luas yang menunjukkan bahwa
citra berkontras tinggi.
Meskipun histogram hanya menunjukkan sifat-sifat umum dari citra dan tidak memberikan
informasi apa-apa tentang isi citra, namun bentuk dari histogram dapat memberikan informasi
mengenai kemungkinan untuk melakukan perbaikan kontras citra tersebut.

4
CARA PENELITIAN

Untuk mengimplementasikan proses contrast stretching pada komputer, penulis membuat


program yang memiliki kemampuan untuk:
• membuka file yang berisi citra digital
• menampilkan citra digital tersebut di layar
• melakukan pemrosesan contrast stretching
• menampilkan citra digital hasil proses
• menampilkan histogram citra, baik sebelum maupun setelah diproses
• menampilkan statistik citra secara umum
Adapun batasan dari program ini adalah:
• file citra yang digunakan harus berformat BMP, berukuran 256x256 pixel, dengan
256 gray-level

File citra digital dengan format BMP

File citra dengan format BMP adalah salah satu format standar yang digunakan dalam
sistem operasi Windows. File ini biasanya disimpan dengan ekstensi .BMP. Struktur dari file BMP
adalah sebagai berikut:

BITMAPFILEHEADER
BITMAPINFOHEADER
Array RGBQUAD
Array warna

Struktur BITMAPFILEHEADER menunjukkan jenis file dan ukuran file. Struktur


BITMAPINFOHEADER menunjukkan ukuran (lebar dan tinggi) dari citra, format warna citra,
dan banyaknya warna yang digunakan di dalam citra. Struktur RGBQUAD berisi nilai intensitas
warna yang dibagi menjadi komponen R, G, dan B (red, green, dan blue). Sedangkan array warna
berisi informasi mengenai isi citra itu sendiri, yaitu pixel-pixel yang membentuk citra tersebut.
Untuk mempercepat proses pengolahan citra digital, maka pixel-pixel yang ada di dalam
file BMP dicopykan ke dalam variabel array. Dengan demikian pada proses selanjutnya tidak perlu
dilakukan pembacaan file secara berulang-ulang. Deklarasi array untuk menyimpan citra tersebut
adalah:

arCitra1 : array[1..256, 1..256] of byte;


arCitra2 : array[1..256, 1..256] of byte;

Secara lengkap, proses peng-copy-an pixel ini dapat dilihat pada procedure BukaFileCitra
di listing program terlampir. Untuk menampilkan citra ke layar, digunakan component Timage dari
Delphi.

5
Proses Contrast Stretching

Setelah semua pixel tersimpan di dalam variabel array, proses contrast stretching dapat
dilakukan dengan melakukan perhitungan untuk setiap pixel yang ada di dalam array tersebut.
Sebelum dilakukan contrast stretching, pemakai dapat menentukan nilai c1, c2, d1, dan d2 yang
akan menentukan bentuk fungsi contrast stretching. Gambar 3 menunjukkan contoh pemilihan
nilai-nilai tersebut.

Gambar 3
Penentuan nilai c1, d1, c2, dan d2
untuk contrast stretching

Selanjutnya nilai c1, c2, d1, dan d2 yang dipilih oleh pemakai dimasukkan ke dalam
variabel untuk digunakan dalam perhitungan selanjutnya. Implementasi dari proses contrast
stretching dapat dilihat pada procedure ContrastStretch di dalam listing program. Berikut ini
bagian dari procedure tersebut yang berfungsi untuk melakukan proses contrast stretching:

{ contrast stretching }
for ix:=1 to 256 do begin
for iy:=1 to 256 do begin
warnab := arCitra1[ix,iy];
if warnab < c1 then {zone 1}
warnab2 := round( warnab * d1 / c1 )
else if warnab < (c2) then {zone 2}
warnab2 := d1 + round( (warnab-c1) * (d2-d1) / (c2-c1) )
else {zone 3}
warnab2 := d2 + round( (warnab-c2) * (255-d2) / (255-c2) );
arCitra2[ix,iy] := warnab2;
end;
end;

6
Histogram

Untuk menampilkan histogram, penulis membuat jendela histogram yang akan


menampilkan dua buah histogram, yaitu untuk citra sebelum diproses dan citra setelah diproses.
Gambar 4 menunjukkan contoh tampilan histogram tersebut.

Gambar 4
Tampilan histogram citra

Histogram tersebut diperoleh dengan cara menyiapkan array bernama untuk menampung
jumlah pixel dari masing-masing gray level. Deklarasi array tersebut adalah:

arHistogram1 : array[0..255] of longint;


arHistogram2 : array[0..255] of longint;

Berikut ini bagian program untuk mengisi array histogram tersebut berdasarkan informasi
gray level dari citra:

{ update data array histogram }


for ix:=1 to 256 do begin
for iy:=1 to 256 do begin
warnab := arCitra1[ix,iy];
inc(arHistogram1[warnab]);
warnab := arCitra2[ix,iy];
inc(arHistogram2[warnab]);
end;
end;

Selanjutnya data tersebut diplot ke component Timage dengan menggunakan perintah


MoveTo dan LineTo untuk membuat garis-garis vertikal yang membentuk grafik histogram.
Implementasi lengkapnya dapat dilihat pada procedure UpdateHistogram.

7
Statistik citra

Program juga menyediakan fasilitas untuk melihat statistik citra yang berisi nilai pixel
terendah, tertinggi, dan rata-rata, baik untuk citra sebelum diproses maupun setelah diproses.
Bagian program untuk menghitung statistik citra adalah sebagai berikut:

pix_max := 0;
pix_min := 255;
tmp := 0;
{ Hitung nilai pixel rata-rata, tertinggi, terendah
(dalam greyscale level)}
for ix:=1 to 256 do begin
for iy:=1 to 256 do begin
warnab := arCitra1[ix,iy];
if warnab > pix_max then
pix_max := warnab;
if warnab < pix_min then
pix_min := warnab;
tmp := tmp + warnab;
end;
end;
pix_rerata := round( tmp / (256 * 256) );

Perhitungan ini ada di dalam procedure HitungStatistikCitra.

Gambar 5
Tampilan statistik citra

8
HASIL DAN PEMBAHASAN

Program yang dibuat telah diujicobakan untuk beberapa file citra dengan mencoba nilai c1,
c2, d1, dan d2 yang berbeda-beda untuk mengubah bentuk fungsi contrast stretching. Pada contoh
kasus berikut, program dicoba untuk membuka file citra yang memiliki kontras rendah.

Contoh kasus 1:
File citra: fruit2.bmp
Nilai (c1, d1) = (0, 0) ; (c2, d2) = (90, 255)
Statistik citra sebelum diproses:
Nilai pixel terendah : 0
Nilai pixel tertinggi : 137
Nilai pixel rata-rata : 37
Statistik citra setelah diproses:
Nilai pixel terendah : 0
Nilai pixel tertinggi : 255
Nilai pixel rata-rata : 104

Tampilan citra:

Tampilan histogram:

9
Contoh kasus 2:
File citra: tank.bmp
Nilai (c1, d1) = (0, 0) ; (c2, d2) = (7, 255)
Statistik citra sebelum diproses:
Nilai pixel terendah : 0
Nilai pixel tertinggi : 7
Nilai pixel rata-rata : 5
Statistik citra setelah diproses:
Nilai pixel terendah : 0
Nilai pixel tertinggi : 255
Nilai pixel rata-rata : 189

Tampilan citra:

Tampilan histogram:

Dari kedua contoh kasus tersebut, terlihat bahwa dengan melakukan proses contrast
stretching kita dapat memperoleh citra baru yang memiliki kontras lebih baik sehingga
menghasilkan citra yang lebih sesuai untuk ditangkap mata manusia.
Terlihat bahwa citra yang histogramnya menyempit memiliki kontras rendah, sedangkan
citra yang histogramnya menyebar memiliki kontras tinggi.
Untuk memilih nilai c1, d1, c2, dan d2 yang tepat, kita dapat melihat statistik yang ada
yang menunjukkan range nilai gray level pixel. Statistik tersebut sangat membantu untuk
menentukan bentuk fungsi contrast stretching yang sesuai karena bentuk fungsi contrast stretching

10
yang sesuai untuk citra yang satu belum tentu sesuai untuk citra yang lain. Sebagai contoh, pada
kasus 1 dan kasus 2 di atas digunakan fungsi contrast stretching yang berbeda dengan mengubah
nilai c1, c2, d1, dan d2.

PENUTUP

Citra yang memiliki kontras rendah cenderung sulit untuk diamati dan dianalisa dengan
baik oleh mata manusia. Proses contrast stretching dapat digunakan untuk melakukan perbaikan
citra digital yang memiliki kontras rendah sehingga memiliki kontras yang lebih baik. Bentuk
fungsi contrast stretching yang digunakan dapat diatur dengan menentukan nilai c1, c2, d1, dan d2
yang tepat berdasarkan histogram dari citra yang akan diproses.
Histogram dapat digunakan untuk menganalisa tingkat brightness (kecerahan) maupun
kontras dari citra secara umum, sehingga dapat membantu menentukan langkah perbaikan citra
selanjutnya.
Secara umum program yang dibuat telah berfungsi dengan baik, namun demikian masih
terbuka kemungkinan untuk dikembangkan lebih lanjut, misalnya dengan menambahkan
kemampuan untuk membuka citra dengan sembarang ukuran, membuka file citra dengan format
yang lain, dan menyimpan citra hasil proses ke dalam file baru.

DAFTAR PUSTAKA

• Rafael C. Gonzalez, Richard E. Woods, 1993, Digital Image Processing, Addison-Wesley


Publishing Company Inc., USA.
• Microsoft Corporation, 1996, Microsoft Win32 Programmer’s Reference, Microsoft
Corporation.

11
LAMPIRAN

Listing Program

program PCD1; procedure FormCreate(Sender: TObject);


procedure Exit2Click(Sender: TObject);
uses procedure ViewHistogram1Click(Sender: TObject);
Forms, private
PCDUnit1 in 'PCDUnit1.pas' {Form1}, { Private declarations }
PCDAbout in 'PCDAbout.pas' {AboutBox}, public
PCDUnit2 in 'PCDUnit2.pas' {frmStat}, { Public declarations }
Histo in 'Histo.pas' {frmHisto}, end;
PCDContrast in 'PCDContrast.pas' {frmContrast};
var
{$R *.RES} Form1: TForm1;

begin { variabel global }


Application.Initialize; arCitra1 : array[1..256, 1..256] of byte;
Application.CreateForm(TForm1, Form1); arCitra2 : array[1..256, 1..256] of byte;
Application.CreateForm(TAboutBox, AboutBox); arHistogram1 : array[0..255] of longint;
Application.CreateForm(TfrmStat, frmStat); arHistogram2 : array[0..255] of longint;
Application.CreateForm(TfrmHisto, frmHisto); nmfile : string;
Application.CreateForm(TfrmContrast, frmContrast); c1, c2, d1, d2 : integer; { parameter utk contrast stretching
Application.Run; }
end.
procedure TampilkanHasil;
{
Pengolahan citra digital. implementation

Input: uses PCDAbout, PCDUnit2, Histo, PCDContrast;


- File citra dg format BMP, ukuran 256x256 pixel, 256 level
grayscale {$R *.DFM}

Output: {-------------------------------------------------------------------------}
- Tampilan citra sebelum diproses. procedure BukaFileCitra;
- Tampilan citra setelah diproses dengan contrast stretching. { syarat: file citra berformat BMP, berukuran 256x256,
- Statistik pixel citra. 256 level grayscale }
- Histogram citra. var
} i, ix, iy : integer;
warna : longint;
unit PCDUnit1; warnab : byte;
bfh : TBitmapFileHeader;
interface bih : TBitmapInfoHeader;
colorTbl : array[0..255] of TRGBQuad;
uses mst : TMemoryStream;
Windows, Messages, SysUtils, Classes, Graphics, b : byte;
Controls, Forms, Dialogs, numColor : integer;
Menus, ExtCtrls, StdCtrls, Buttons, ComCtrls; syarat : boolean;
bm : TBitmap;
type begin
TForm1 = class(TForm) { buka file citra, copykan semua pixel citra ke dalam array }
Image1: TImage; mst := TMemoryStream.Create;
Image2: TImage; mst.LoadFromFile(nmfile);
Label1: TLabel; mst.ReadBuffer(bfh, sizeof(bfh));
Label2: TLabel; mst.ReadBuffer(bih, sizeof(bih));
OpenDialog1: TOpenDialog; if (bih.biWidth <> 256) or (bih.biHeight <> 256) or
MainMenu1: TMainMenu; (bih.biBitCount <> 8) then begin
File1: TMenuItem; MessageDlg('Format file salah! Hanya bisa membuka
Open1: TMenuItem; file BMP berukuran 256x256, 8 bit per pixel.', mtError,
Proses1: TMenuItem; [mbOK], 0);
Statistik1: TMenuItem; mst.Free;
ContrastStretching1: TMenuItem; exit;
About1: TMenuItem; end;
Bevel1: TBevel; if bih.biClrUsed<256 then numColor:=bih.biClrUsed else
Help1: TMenuItem; numColor:=256;
Exit2: TMenuItem; for i:=0 to numColor-1 do
ViewHistogram1: TMenuItem; mst.ReadBuffer(colorTbl[i], 4);
View1: TMenuItem; for iy:=256 downto 1 do begin
procedure Open1Click(Sender: TObject); for ix:=1 to 256 do begin
procedure ContrastStretching1Click(Sender: TObject); mst.ReadBuffer(b, 1);
procedure About1Click(Sender: TObject); warna := longint(colorTbl[b]);
procedure Statistik1Click(Sender: TObject);

12
arCitra1[ix,iy] := (byte(warna) + byte(warna shr 8) + pix_max := 0;
byte(warna shr 16)) div 3; pix_min := 255;
arCitra2[ix,iy] := 0; tmp := 0;
end; { Hitung nilai pixel rata-rata, tertinggi, terendah (dalam
end; greyscale level)}
mst.Free; for ix:=1 to 256 do begin
{ tampilkan file citra di image1 } for iy:=1 to 256 do begin
form1.image1.Picture.LoadFromFile(nmfile); warnab := arCitra2[ix,iy];
{ bersihkan image2 } if warnab > pix_max then
form1.Image2.Canvas.Brush.Color := clBlack; pix_max := warnab;
form1.Image2.Canvas.FillRect(Rect(0, 0, 256, 256)); if warnab < pix_min then
end; pix_min := warnab;
tmp := tmp + warnab;
{-------------------------------------------------------------------------} end;
procedure TampilkanHasil; end;
var ix, iy : integer; pix_rerata := round( tmp / (256 * 256) );
warna : longint; Str(pix_min, s);
warnab : byte; frmStat.Memo1.Lines.Add(' Nilai pixel terendah : ' + s);
begin Str(pix_max, s);
{ tampilkan citra setelah diproses } frmStat.Memo1.Lines.Add(' Nilai pixel tertinggi : ' + s);
for ix:=1 to 256 do begin Str(pix_rerata, s);
for iy:=1 to 256 do begin frmStat.Memo1.Lines.Add(' Nilai pixel rata-rata : ' + s);
warnab := arCitra2[ix,iy]; end;
warna := warnab or (longint(warnab) shl 8) or
(longint(warnab) shl 16); {=============================================
form1.image2.Canvas.Pixels[ix-1,iy-1] := warna; ============================}
end;
end; procedure TForm1.Open1Click(Sender: TObject);
begin
end; OpenDialog1.Execute;
if OpenDialog1.FileName <> '' Then begin
{-------------------------------------------------------------------------} nmfile := Form1.OpenDialog1.FileName;
procedure HitungStatistikCitra; BukaFileCitra;
var ix, iy : integer; UpdateHistogram;
warnab : byte; end;
tmp : longint; end;
s : string;
pix_rerata, pix_max, pix_min : byte; procedure TForm1.ContrastStretching1Click(Sender:
begin TObject);
frmStat.Memo1.Text := ''; begin
frmStat.Memo1.Lines.Add('Nama file citra: ' + nmfile); frmContrast.Show;
frmStat.Memo1.Lines.Add(''); end;
{ --- citra 1 ---}
frmStat.Memo1.Lines.Add('Statistik citra sebelum procedure TForm1.About1Click(Sender: TObject);
diproses:'); begin
{ init variabel } AboutBox.ShowModal;
pix_max := 0; end;
pix_min := 255;
tmp := 0; procedure TForm1.Statistik1Click(Sender: TObject);
{ Hitung nilai pixel rata-rata, tertinggi, terendah (dalam begin
greyscale level)} HitungStatistikCitra;
for ix:=1 to 256 do begin frmStat.Show;
for iy:=1 to 256 do begin end;
warnab := arCitra1[ix,iy];
if warnab > pix_max then procedure TForm1.FormCreate(Sender: TObject);
pix_max := warnab; begin
if warnab < pix_min then { bersihkan image1 & image2 }
pix_min := warnab; form1.Image1.Canvas.Brush.Color := clBlack;
tmp := tmp + warnab; form1.Image1.Canvas.FillRect(Rect(0, 0, 256, 256));
end; form1.Image2.Canvas.Brush.Color := clBlack;
end; form1.Image2.Canvas.FillRect(Rect(0, 0, 256, 256));
pix_rerata := round( tmp / (256 * 256) ); { nmfile := 'fruit3.bmp';
Str(pix_min, s); BukaFileCitra;}
frmStat.Memo1.Lines.Add(' Nilai pixel terendah : ' + s); end;
Str(pix_max, s);
frmStat.Memo1.Lines.Add(' Nilai pixel tertinggi : ' + s); procedure TForm1.Exit2Click(Sender: TObject);
Str(pix_rerata, s); begin
frmStat.Memo1.Lines.Add(' Nilai pixel rata-rata : ' + s); form1.close;
end;
{ --- citra 2 ---}
frmStat.Memo1.Lines.Add(''); procedure TForm1.ViewHistogram1Click(Sender: TObject);
frmStat.Memo1.Lines.Add('Statistik citra setelah begin
diproses:'); ViewHistogram1.Checked := not
{ init variabel } ViewHistogram1.Checked;

13
frmHisto.Visible := ViewHistogram1.Checked; private
end; { Private declarations }
public
end. { Public declarations }
end;

unit PCDUnit2; var


frmHisto: TfrmHisto;
interface
procedure UpdateHistogram;
uses
Windows, Messages, SysUtils, Classes, Graphics, implementation
Controls, Forms, Dialogs,
StdCtrls, PCDUnit1; uses PCDUnit1;

type {$R *.DFM}


TfrmStat = class(TForm)
Memo1: TMemo; {-------------------------------------------------------------------------}
Button1: TButton; procedure UpdateHistogram;
procedure Button1Click(Sender: TObject); var i : integer;
private ix, iy, n : integer;
{ Private declarations } warnab : byte;
public maxHistogramValue1 : integer;
{ Public declarations } maxHistogramValue2 : integer;
end; skala1 : real;
skala2 : real;
var r : TRect;
frmStat: TfrmStat; begin
{ inisialisasi }
implementation for i:=0 to 255 do begin
arHistogram1[i] := 0;
{$R *.DFM} arHistogram2[i] := 0;
end;
procedure TfrmStat.Button1Click(Sender: TObject); { update data array histogram }
begin for ix:=1 to 256 do begin
frmStat.Close; for iy:=1 to 256 do begin
end; warnab := arCitra1[ix,iy];
inc(arHistogram1[warnab]);
end. warnab := arCitra2[ix,iy];
inc(arHistogram2[warnab]);
end;
unit Histo; end;
{ histogram scaling }
interface maxHistogramValue1 := 0;
maxHistogramValue2 := 0;
uses for i:=0 to 255 do begin
Windows, Messages, SysUtils, Classes, Graphics, if arHistogram1[i] > maxHistogramValue1 then
Controls, Forms, Dialogs, maxHistogramValue1 := arHistogram1[i];
ExtCtrls, StdCtrls; if arHistogram2[i] > maxHistogramValue2 then
maxHistogramValue2 := arHistogram2[i];
type end;
TfrmHisto = class(TForm) skala1 := 100 / maxHistogramValue1;
Image1: TImage; skala2 := 100 / maxHistogramValue2;
Image2: TImage; { inisialisasi gambar histogram }
Label3: TLabel; r := Rect(0, 0, 256, 101);
Label4: TLabel; frmHisto.Image1.Canvas.Brush.Color := clWhite;
Label5: TLabel; frmHisto.Image1.Canvas.FillRect(r);
Label6: TLabel; frmHisto.Image2.Canvas.Brush.Color := clWhite;
Label1: TLabel; frmHisto.Image2.Canvas.FillRect(r);
Label2: TLabel; frmHisto.Image1.Canvas.MoveTo(0,100);
Label7: TLabel; frmHisto.Image1.Canvas.LineTo(256,100);
Label8: TLabel; frmHisto.Image2.Canvas.MoveTo(0,100);
procedure FormCreate(Sender: TObject); frmHisto.Image2.Canvas.LineTo(256,100);
procedure FormClose(Sender: TObject; var Action: { mulai gambar histogram }
TCloseAction); for i:=0 to 255 do begin
procedure Image1MouseMove(Sender: TObject; Shift: { histogram citra 1 }
TShiftState; X, frmHisto.Image1.Canvas.MoveTo(i,100);
Y: Integer); n := round( arHistogram1[i] * skala1 );
procedure FormMouseMove(Sender: TObject; Shift: frmHisto.Image1.Canvas.LineTo(i,100-n);
TShiftState; X, { histogram citra 2 }
Y: Integer); frmHisto.Image2.Canvas.MoveTo(i,100);
procedure Image2MouseMove(Sender: TObject; Shift: n := round( arHistogram2[i] * skala2 );
TShiftState; X, frmHisto.Image2.Canvas.LineTo(i,100-n);
Y: Integer); end;

14
end;
interface
procedure TfrmHisto.FormCreate(Sender: TObject);
begin uses
UpdateHistogram; Windows, Messages, SysUtils, Classes, Graphics,
end; Controls, Forms, Dialogs,
StdCtrls, Spin, ExtCtrls;
procedure TfrmHisto.FormClose(Sender: TObject; var
Action: TCloseAction); type
begin TfrmContrast = class(TForm)
Form1.ViewHistogram1.Checked := False; Image1: TImage;
end; Label1: TLabel;
Label2: TLabel;
procedure TfrmHisto.Image1MouseMove(Sender: TObject; Label3: TLabel;
Shift: TShiftState; X, Label4: TLabel;
Y: Integer); Button1: TButton;
begin scbC1: TScrollBar;
Label7.Caption := 'f[' + IntToStr(X) + '] = ' + lblC1: TLabel;
IntToStr(arHistogram1[X]); lblD1: TLabel;
end; scbD1: TScrollBar;
lblC2: TLabel;
procedure TfrmHisto.FormMouseMove(Sender: TObject; scbC2: TScrollBar;
Shift: TShiftState; X, lblD2: TLabel;
Y: Integer); scbD2: TScrollBar;
begin Button2: TButton;
Label7.Caption := ''; procedure Button1Click(Sender: TObject);
Label8.Caption := ''; procedure FormCreate(Sender: TObject);
end; procedure scbC1Change(Sender: TObject);
procedure scbD1Change(Sender: TObject);
procedure TfrmHisto.Image2MouseMove(Sender: TObject; procedure scbC2Change(Sender: TObject);
Shift: TShiftState; X, procedure scbD2Change(Sender: TObject);
Y: Integer); procedure Button2Click(Sender: TObject);
begin private
Label8.Caption := 'f[' + IntToStr(X) + '] = ' + { Private declarations }
IntToStr(arHistogram2[X]); public
end; { Public declarations }
end;
end.
unit PCDAbout; var
frmContrast: TfrmContrast;
interface
implementation
uses Windows, SysUtils, Classes, Graphics, Forms,
Controls, StdCtrls, uses Histo, PCDUnit1;
Buttons, ExtCtrls;
{$R *.DFM}
type
TAboutBox = class(TForm)
Panel1: TPanel; {-----------------------------------------------------------}
ProgramIcon: TImage; procedure UpdateContrastSetting;
ProductName: TLabel; begin
Version: TLabel; c1 := frmContrast.scbC1.Position;
Copyright: TLabel; d1 := frmContrast.scbD1.Position;
Comments: TLabel; c2 := frmContrast.scbC2.Position;
OKButton: TButton; d2 := frmContrast.scbD2.Position;
Label1: TLabel; { inisialisasi image }
Label2: TLabel; frmContrast.Image1.Canvas.Brush.Color :=
private TColor($00AAAAAA);
{ Private declarations } frmContrast.Image1.Canvas.FillRect(Rect(0, 0, 256 div 2,
public 256 div 2));
{ Public declarations } { update image }
end; frmContrast.Image1.Canvas.Pen.Color := clBlack;
frmContrast.Image1.Canvas.MoveTo(0,255 div 2);
var frmContrast.Image1.Canvas.LineTo(c1 div 2,(255-d1) div
AboutBox: TAboutBox; 2);
frmContrast.Image1.Canvas.LineTo(c2 div 2,(255-d2) div
implementation 2);
frmContrast.Image1.Canvas.LineTo(255 div 2,0);
{$R *.DFM} end;

end. {-------------------------------------------------------------------------}
procedure ContrastStretch;
var ix, iy : integer;
unit PCDContrast; warna : longint;

15
warnab : byte; begin
warnab2 : byte; Close;
begin end;
{----- proses citra }
{ contrast stretching } end.
for ix:=1 to 256 do begin
for iy:=1 to 256 do begin
warnab := arCitra1[ix,iy];
if warnab < c1 then {zone 1}
warnab2 := round( warnab * d1 / c1 )
else if warnab < (c2) then {zone 2}
warnab2 := d1 + round( (warnab-c1) * (d2-d1) /
(c2-c1) )
else {zone 3}
warnab2 := d2 + round( (warnab-c2) * (255-d2) /
(255-c2) );
arCitra2[ix,iy] := warnab2;
end;
end;
end;

procedure TfrmContrast.Button1Click(Sender: TObject);


begin
Button1.Enabled := False;
frmContrast.Cursor := crHourGlass;
ContrastStretch;
TampilkanHasil;
UpdateHistogram;
Button1.Enabled := True;
frmContrast.Cursor := crDefault;
end;

procedure TfrmContrast.FormCreate(Sender: TObject);


begin
lblC1.Caption := IntToStr(scbC1.Position);
lblD1.Caption := IntToStr(scbD1.Position);
lblC2.Caption := IntToStr(scbC2.Position);
lblD2.Caption := IntToStr(scbD2.Position);
UpdateContrastSetting;
end;

procedure TfrmContrast.scbC1Change(Sender: TObject);


begin
if scbC1.Position > scbC2.Position then
scbC1.Position := scbC2.Position;
lblC1.Caption := IntToStr(scbC1.Position);
UpdateContrastSetting;
end;

procedure TfrmContrast.scbD1Change(Sender: TObject);


begin
if scbD1.Position > scbD2.Position then
scbD1.Position := scbD2.Position;
lblD1.Caption := IntToStr(scbD1.Position);
UpdateContrastSetting;
end;

procedure TfrmContrast.scbC2Change(Sender: TObject);


begin
if scbC2.Position < scbC1.Position then
scbC2.Position := scbC1.Position;
lblC2.Caption := IntToStr(scbC2.Position);
UpdateContrastSetting;
end;

procedure TfrmContrast.scbD2Change(Sender: TObject);


begin
if scbD2.Position < scbD1.Position then
scbD2.Position := scbD1.Position;
lblD2.Caption := IntToStr(scbD2.Position);
UpdateContrastSetting;
end;

procedure TfrmContrast.Button2Click(Sender: TObject);

16