Download as pdf or txt
Download as pdf or txt
You are on page 1of 222

Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.

com

GÖRÜNTÜ İŞLEME - (2.Hafta)

C# PROGRAMLAMA İLE GÖRÜNTÜ İŞLEME


Görüntü işleme kapsamında geliştirilecek algoritmalar C# diliyle yazılacaktır. Bu amaçla bilgisayarımızda Visual
Studio programının kurulu olması gerekmektedir. Öncelikle programın altyapının oluşturulup, dersler ilerledikçe
içerisine kodlar eklenecektir.

Program Altyapısının Oluşturulması


Geliştirilecek program Windows Form Application uygulaması olacaktır.

Program içerisinde Menü ve Araç çubuğu kullanılacaktır. Bu amaçla MenuStrip ve ToolStrip nesneleri
kullanılacaktır.

ToolStrip (araç çubuğu) üzerindeki butonların resimlerini atarken, Paintte oluşturulan örnek resimler projenin
içerisindeki Bin klasörünün altına kopyalayalım.

Daha sonra ToolStrip üzerindeki butonu seçip Image özelliğinden butonu yükleyelim.

Butonun resmi yüklendikten sonra Properties penceresinden başka gerekli ayarlamalar yapılabilir. Örneğin
butonun adı yapacağı işle ilgili olarak değiştirilebilir.

1
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Butona tıkladığımızda ona ait olan fonksiyon kodları açılacaktır.

Programımızın tasarımını üstte bir menu çubuğu, altında ise Araç çubuğu olacak şekilde tasarlayalım. Form
üzerinde ise iki tane Picturebox olsun. Bunlardan birincisi orjinal resmi, diğeri ise dönüştürülmüş resmi göstersin.
Program ilerledikçe ekleme ve çıkarmalar olacaktır. Bu altyapı üzerinde devam edelim.

RESİM YÜKLEME
Bilgisayarımızdaki herhangi bir resmi PictureBox1 yüklemek için aşağıdaki kodları kullanabiliriz. Bunu fonksiyon
şeklinde yazarsak hem menüden hem de araç çubuğunda aynı kodlar kullanılarak resim yüklenebilir. Burada
geliştirilen programda iki tane picturebox kullanılmaktadır. Birincisinde orjinal resim (giriş resmi), ikincisinde ise
dönüştürülmüş resim (çıkış resmi) görüntülenecektir.

2
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Dosya açarken uzantıların görüntülenmesi süzmek için uygun olacaktır. Bunun için aşağıdaki kodları
kullanabiliriz.
openFileDialog1.DefaultExt = ".jpg";
openFileDialog1.Filter = "Image Files(*.BMP;*.JPG;*.GIF)|*.BMP;*.JPG;*.GIF|All files (*.*)|*.*";

Eğer resim yükleme çalışırken openFileDalog açıldıktan resim seçilmeyip "iptal" tuşuna basılırsa, resimyolu
değişkeni "null" olacağı için program hata verir. Bunu engellemek için Try-Catch kodları içine yazılması gerekir.
private void DosyaAc_menu_Click(object sender, EventArgs e)
{
DosyaAc();
}
private void DosyaAc_toolbar_Click(object sender, EventArgs e)
{
DosyaAc();
}
//DOSYA AÇ -----------------------------
public void DosyaAc()
{
try
{
openFileDialog1.DefaultExt = ".jpg";
openFileDialog1.Filter = "Image Files(*.BMP;*.JPG;*.GIF)|*.BMP;*.JPG;*.GIF|All files (*.*)|*.*";

openFileDialog1.ShowDialog();

String ResminYolu = openFileDialog1.FileName;


pictureBox1.Image = Image.FromFile(ResminYolu);
}
catch { }
}
Görüntülenen resim çeşitli boyutlarda olabilir. Bu nedenle resmin picturebox içerisinde düzgün görüntülenmesi
için SizeMode seçeneğini aşağıdaki seçeneklerden uygun olanla yapmak gerekir. Burada;
a) Normal (resmin sığdığı kadar kısmı normal görüntülenir
b) StrechImage (resim çerçevenin içine tam sığacak şekilde daraltılır yada genişletilir,
c) AutoSize (çerçeve resmin boyutlarını alır)
3
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

d) CenterImage (resmin orta bölgesi çerçeve içinde normal şekilde görüntülenir, sığmayan kısımlar dışarıda kalır,
e) Zoom (resmin orantısı bozulmadan tamamı çerçeve içinde görüntülenir).
Not: Kodla size ayarlamak için
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;

a) b)

c) d) e)

RESMİ KAYDETME
Birinci picturebox da görüntülenen orjinal resim, belli filtrelerden geçirildikten sonra ikinci picturebox da
görüntülenecektir. Görüntülenen bu ikinci resim gerektiğinde bilgisayara kaydedilebilmelidir. Bu amaçla
aşağıdaki kodları kullanabiliriz. Burada üç tip resim kaydetme yapılmaktadır. Bunlar jpeg, bitmap ve gif
resimleridir.

//RESMİ KAYDETME-----------------------------------------
public void ResmiKaydet()
{
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "Jpeg Resmi|*.jpg|Bitmap Resmi|*.bmp|Gif Resmi|*.gif";
4
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

saveFileDialog1.Title = "Resmi Kaydet";


saveFileDialog1.ShowDialog();

if (saveFileDialog1.FileName != "") //Dosya adı boş değilse kaydedecek.


{
// FileStream nesnesi ile kayıtı gerçekleştirecek.
FileStream DosyaAkisi = (FileStream)saveFileDialog1.OpenFile();

switch (saveFileDialog1.FilterIndex)
{
case 1:
pictureBox2.Image.Save(DosyaAkisi, System.Drawing.Imaging.ImageFormat.Jpeg);
break;

case 2:
pictureBox2.Image.Save(DosyaAkisi, System.Drawing.Imaging.ImageFormat.Bmp);
break;

case 3:
pictureBox2.Image.Save(DosyaAkisi, System.Drawing.Imaging.ImageFormat.Gif);
break;
}

DosyaAkisi.Close();
}
}

Not:
2019 Versiyonunda bir komutun kütüphanesini (reference) eklemek için aşağıdaki gibi mouse ile üzerine gelince
potansiyel seçenekleri gösterecektir. Bunun için “Show potential fixes” tıklayınız. Daha sonra çıkan listede
using.System..IO; kütüphanesini seçin. Kendisi otomatik olarak programın en üstüne ekleyecektir.

5
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

RESMİ PİKSEL OLARAK AKTARMA

private void btnResmiPikselOlarak_Click(object sender, EventArgs e)


{
Color OkunanRenk, DonusenRenk;
int R = 0, G = 0, B = 0;

Bitmap GirisResmi, CikisResmi;


GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width; //GirisResmi global tanımlandı. İçerisine görüntü


yüklendi.
int ResimYuksekligi = GirisResmi.Height;
CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi); //Cikis resmini oluşturuyor.
Boyutları giriş resmi ile aynı olur. Tanımlaması globalde yapıldı.

for (int x = 0; x < ResimGenisligi; x++)


{
for (int y = 0; y < ResimYuksekligi; y++)
{
OkunanRenk = GirisResmi.GetPixel(x, y);

R = OkunanRenk.R;
G = OkunanRenk.G;
B = OkunanRenk.B;

DonusenRenk = Color.FromArgb(R, G, B);


CikisResmi.SetPixel(x, y, DonusenRenk);
}
}

pictureBox2.Image = CikisResmi;
}

RESMİN NEGATİFİNİ ALMA (Negative)


Bu işlem basit olarak şu şekilde yapılır. Her piksel renk değeri bir döngü içinde 255 sayısından çıkarıldığında
geriye kalan değer, negatif rengi verecektir. Renkli resimlerde ise 3 renk de aynı işleme tabi tutulur.
Örneğin; siyah renkli bir pikselin değeri 0 dır. Bu pikselin değeri 255-0=255 olarak ayarlanırsa bu renk de beyaz
olacaktır. Yada beyaz yakın bir değer olan 212 değerini dönüştürürsek, 255-212=43 olacaktır. Bu da siyaha yakın
bir renktir. Bunu matematiksel olarak ifade edersek, g(x;y) giriş resminin Kırmızı piksel değeri, f[x;y] çıkış
resminin kırmızı piksel değeri olacaktır.

f(x; y) = 255 - g(x; y)

6
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Programlama

//NEGATİFİNİ ALMA -------------------------------------


private void btnNegatif_Click(object sender, EventArgs e)
{
Color OkunanRenk, DonusenRenk;
int R = 0, G = 0, B = 0;

Bitmap GirisResmi, CikisResmi;


GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width; //GirisResmi global tanımlandı. İçerisine görüntü


yüklendi.
int ResimYuksekligi = GirisResmi.Height;
CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi); //Cikis resmini oluşturuyor.
Boyutları giriş resmi ile aynı olur. Tanımlaması globalde yapıldı.

int i = 0, j = 0; //Çıkış resminin x ve y si olacak.


for (int x = 0; x < ResimGenisligi; x++)
{
for (int y = 0; y < ResimYuksekligi; y++)
{
OkunanRenk = GirisResmi.GetPixel(x, y);

R = 255 - OkunanRenk.R;
G = 255 - OkunanRenk.G;
B = 255 - OkunanRenk.B;

DonusenRenk = Color.FromArgb(R, G, B);


CikisResmi.SetPixel(x, y, DonusenRenk);
}
}

pictureBox2.Image = CikisResmi;

GRİ TON RESİM (Siyah-Beyaz) (Grayscale)


Griton resimler renkler olmadan sadece ışığın yoğunluğunu gösteren resimlerdir. Eski teknoloji siyah beyaz
resimlere benzer.
Bu resimler bilgisayarda 8 bit formatında saklanır. Bunun anlamı her piksel 8 bit ikili kod ile saklanır. Yani 2 8=256
olarak gösterilirse 0-255 arasında değer alır. 0 siyah rengi gösterirken, 255 beyaz rengi gösterecektir.
Bir griton resim 800x600 piksel boyutlarında olursa içerisinde 480.000 piksel olacaktır. Her piksel 8 bit=1 byte
hafızada yer alacağına göre resmin tamamı 480 kByte=0,48 MByte yer kaplayacaktır. Aynı resim renkli olsayda,

7
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

her renk (RGB-RedGreenBlue) benzer şekilde 256 ton renk alarak 28*3=224 yani 24 bit yer kaplar. Bu durumda
aynı resim bu sefer 3 katı yer kaplar.
Griton resimleri, kenar tespiti yada eşik uygulamaları gibir farklı amaçlar için ileriki uygulamlarımızda
kullanacağız.
Renkli resmin Gri-Ton a dönüştürülmesi
Renkli sayısal bir görüntüyü gri-ton bir görüntüye dönüştürme işlemi aslında RGB renk modelinde belirtilen her
bir renk bandına karşı düşen gri-ton görüntülerin ölçeklendirilmesinden başka bir şey değildir. Normalde üç
rengin değerini toplayıp üçe bölerek gri tonu elde edebiliriz. Fakat bu gözümüzün farklı renkleri farklı algılama
hassasiyetini tam yansıtmaz. Bu nedenle aşağıdaki formüllerde verildiği gibi ölçekleme yapılmalıdır. İlk verilen
formül en gerçekçi olanıdır. Dördüncü formülü ise basit olarak kullanabileceğimiz akılda kalıcı bir olabilir.
GriDegeri = (R + G + B)/3

GriDegeri = 0.299 x R + 0.587 x G + 0.114 x B

GriDegeri = 0.21 x R + 0.71 x G + 0.071 x B


GriDeğer=0.3 x R + 0.6 x G + 0.1 x B
Gri renk değeri bulunduktan sonra, R,G,B renk değerlerinin hepsi aynı renk koduna sahip olmalıdır. Yani;
R=GriDegeri, G=GriDegeri, B=GriDegeri
Tabii bu şekliyle resim yine 24 bit olarak saklanmış olur (hafızada renkli resim gibi yer tutar). Bunu 8 bit olarak
saklamak gerekir.
Araştırma: 24 bit resim 8 bit olarak nasıl saklanır. Yani renkler üç tane formatta değilde tek renk formatında
nasıl saklanır. Konuyu araştırınız. Her iki formatla saklanan gri-ton resmin hafızda kapladığı alanın farklı
olduğunu gösteriniz.

Şekil. Doğal renkli görüntüden Gri ton görüntünün elde edilmesi.

8
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Programlama

//GRİ RESİM *************************************


private void btnGriResim_Click(object sender, EventArgs e)
{
Color OkunanRenk, DonusenRenk;

Bitmap GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width; //GirisResmi global tanımlandı. Fonksiyonla gelmedi.


int ResimYuksekligi = GirisResmi.Height;

Bitmap CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi); //Cikis resmini


oluşturuyor. Boyutları giriş resmi ile aynı olur.

int GriDeger = 0;
for (int x = 0; x < ResimGenisligi; x++)
{
for (int y = 0; y < ResimYuksekligi; y++)
{
OkunanRenk = GirisResmi.GetPixel(x, y);

double R = OkunanRenk.R ;
double G = OkunanRenk.G ;
double B = OkunanRenk.B ;

//GriDeger = Convert.ToInt16((R + G + B) / 3);

GriDeger = Convert.ToInt16(R * 0.3 + G*0.6 + B*0.1);

DonusenRenk = Color.FromArgb(GriDeger, GriDeger, GriDeger);


CikisResmi.SetPixel(x, y, DonusenRenk);
}
}

pictureBox2.Image = CikisResmi;
}

Gri-ton formülü olarak 3 kanal (R,G,B) renk ortalamasını alarak da gri-ton a dönüştürebiliriz. Ama bu formül daha
az gerçekçi bir sonuç verecektir. Bunun için yukarıdaki programda ilgili satırı aşağıdaki kodlarla değiştirmeliyiz.
int GriDegeri = (int)(OkunanRenk.R + OkunanRenk.G + OkunanRenk.B)/3; //Ortalama Gri-ton formülü

9
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Not:
Resmin üzerindeki noktaların renk değerlerini öğrenmek için aşağıdaki kodları kullanabilirsiniz. Böylece hangi
rengin dönüşümlerde nasıl değiştiğini daha iyi yorumlarsınız.
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
Color Renk = ((Bitmap)pictureBox1.Image).GetPixel(e.X, e.Y);
txtRGB.Text = string.Format("R:{0} G:{1} B:{2}", Renk.R, Renk.G, Renk.B);
}

Araştırma: Renkli resimleri, Gri resme dönüştürmeyi öğrendik. Peki Gri resmi, renkli resme nasıl dönüştürürüz.
Üzerinde araştırma yapın. Aşağıdaki linkteki bu uygulamanın başarısını gözlemleyin. Daha iyi bir algoritmayı nasıl
geliştirirsiniz fikir geliştirin. (https://demos.algorithmia.com/colorize-photos )

PARLAKLIK (BRIGHTNESS)
Bir resmin parlaklılığını artırma yada rengini açma, beyaz tona doğru ilerlemek için renk kanalları üzerine aynı
büyüklükte eşdeğer bir sayı eklemekle gerçekleştirilir. Resmi koyulaştırmak için tam tersi sayı çıkarılır. Burada
dikkat edilmesi gereken üzerine eklenen sayılarla sonuç 255 değerini geçmemelidir yada çıkarılan sayılar
nedeniyle 0 altına düşmemelidir. Şu şekilde formülüze edebiliriz.
f(x,y)= g(x,y)(R∓b, G∓b, B∓b)

Program Kodları
Birinci resimler orjinal resim, ikinciler rengi 50 değerinde açılmış resimdir.

10
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

//PARLAKLIĞINI DEĞİŞTİRME ----------------------------------------


public Bitmap ResminParlakliginiDegistir()
{
int R = 0, G = 0, B = 0;
Color OkunanRenk, DonusenRenk;
Bitmap GirisResmi, CikisResmi;
GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width; //GirisResmi global tanımlandı.


int ResimYuksekligi = GirisResmi.Height;
CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi); //Cikis resmini oluşturuyor. Boyutları giriş resmi
ile aynı olur.

int i = 0, j = 0; //Çıkış resminin x ve y si olacak.


for (int x = 0; x < ResimGenisligi; x++)
{
j = 0;
for (int y = 0; y < ResimYuksekligi; y++)
{
OkunanRenk = GirisResmi.GetPixel(x, y);
//Rengini 50 değeri ile açacak.
R = OkunanRenk.R + 50;
G = OkunanRenk.G + 50;
B = OkunanRenk.B + 50;

//Renkler 255 geçtiyse son sınır olan 255 alınacak.


if (R > 255) R = 255;
if (G > 255) G = 255;
if (B > 255) B = 255;

DonusenRenk = Color.FromArgb(R, G, B);


CikisResmi.SetPixel(i, j, DonusenRenk);
j++;
}
i++;
}
return CikisResmi;

11
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

EŞİKLEME (Thresholding)
Bu teknikte resim içerisindeki her pikselin renk değeri belli bir eşik değeri ile kıyaslanır. Eğer bu eşik değerinin
altında ise bir renk, üzerinde ise başka bir renk atanır. Örneğin gri-ton bir resmi bu filtreden geçirirken, renk
değeri 128 gibi bir eşik değerin altındaysa 0-siyah olarak, üzerinde ise 255-beyaz olarak atanabilir. Matematiksel
olarak aşağıdaki gibi gösterilebilir.
0 𝑒ğ𝑒𝑟 𝑔(𝑥, 𝑦) < 𝑇 = 128
𝑓(𝑥, 𝑦) = {
255 𝑑𝑖ğ𝑒𝑟
Programlama

//EŞİKLEME -------------------------------------
public Bitmap ResmiEsiklemeYap()
{
int R = 0, G = 0, B = 0;
Color OkunanRenk, DonusenRenk;
Bitmap GirisResmi, CikisResmi;
GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width; //GirisResmi global tanımlandı.


int ResimYuksekligi = GirisResmi.Height;
CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi); //Cikis resmini oluşturuyor. Boyutları
giriş resmi ile aynı olur.

int EsiklemeDegeri = Convert.ToInt32(textBox1.Text);

for (int x = 0; x < ResimGenisligi; x++)


{
for (int y = 0; y < ResimYuksekligi; y++)
{
OkunanRenk = GirisResmi.GetPixel(x, y);
12
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

if (OkunanRenk.R >= EsiklemeDegeri)


R = 255;
else
R = 0;

if (OkunanRenk.G >= EsiklemeDegeri)


G = 255;
else
G = 0;

if (OkunanRenk.B >= EsiklemeDegeri)


B = 255;
else
B = 0;

DonusenRenk = Color.FromArgb(R, G, B);


CikisResmi.SetPixel(x, y, DonusenRenk);
}
}

pictureBox2.Image = CikisResmi;
}

HİSTOGRAM
Resim üzerinde eşikleme işlemi yapıldığında belli özellikleri ortaya çıkarmak için, uygun eşik değeri kullanmamız
gerekir. Fakat bu eşik değerinin hangi değer olması gerektiğini tam olarak bilemeyiz. İşte tam bu noktada
histogram konusu devreye girmektedir.

Görüntü histogramı, gri-ton resmin üzerindeki piksel bilgilerini gösteren bir çubuk grafiktir. Grafiğin yatay x-
ekseni 0-255 arasındaki gri ton değerlerini gösterir. y-ekseni ise bu değerlere sahip piksel sayılarını gösterir.

Aşağıdaki grafikte yatay eksen 0-255 arası eşit 4 parçaya bölünmüştür. Dikey eksen ise hangi renk tonundan en
fazla adet varsa onun sayısına bağlı olarak (n ile gösterilmiştir) eşit kısımlara bölünmüştür. Buna göre en fazla
piksel adedi 10 renk tonu civardında olduğu görülmektedir.

Resme bakıldığında renklerin koyu piksellerden oluştuğu gözükmektedir. Bu durum histogramın sol tarafa siyaha
yakın bölgede toplanmasına yol açmıştır. Aynı zamanda histogramın orta bölgeye yakın bir yerde bir zirve
yaptığını görmekteyiz. Bu bölgedeki renkler zambakların yapraklarının renginden kaynaklanmaktadır (suyun
üstündeki geniş yapraklar). 128 den sonra renk sayılarının azaldığını görmekteyiz. Bunlar açık renkli tonlardır.
Aşağıdaki gibi yapılacak iki farklı eşikle (128 veya 192) renklerin hangi nesnelere ait olduğunu görebiliriz.

13
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Programlama

private void HISTOGRAM_Click(object sender, EventArgs e)


{
ArrayList DiziPiksel = new ArrayList();

int Gri = 0;
Color OkunanRenk;
int R = 0, G = 0, B = 0;

Bitmap GirisResmi; //Histogram için giriş resmi gri-ton olmalıdır.


GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width; //GirisResmi global tanımlandı.


int ResimYuksekligi = GirisResmi.Height;

int i = 0; //piksel sayısı tutulacak.

//GRİ DİZİYE ATMA***************


for (int x = 0; x < GirisResmi.Width; x++)
{
for (int y = 0; y < GirisResmi.Height; y++)
{
OkunanRenk = GirisResmi.GetPixel(x, y);
//Gri = (int)(OkunanRenk.R + OkunanRenk.G + OkunanRenk.B) / 3; //Griton resimde üç
kanal rengi aynı değere sahiptir.

Gri = OkunanRenk.R;

DiziPiksel.Add(Gri); //Resimdeki tüm noktaları diziye atıyor.


}
}

//RENKLERİ SAYMA**************

14
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

int[] DiziPikselSayilari = new int[256];

for (int r = 0; r <= 255; r++) //256 tane renk tonu için dönecek.
{
int PikselSayisi = 0;

for (int s = 0; s < DiziPiksel.Count; s++) //resimdeki piksel sayısınca dönecek.


{
if (r == Convert.ToInt16(DiziPiksel[s]))
{
PikselSayisi++;

}
}
DiziPikselSayilari[r] = PikselSayisi;
}

//Maksimum ve Minimum X değerlerini bulma === histogramın iki ucundaki sayıları bulma
int MaksX = 0;
int MinX = 255;

for (int s = 0; s < DiziPiksel.Count; s++) //resimdeki piksel sayısınca dönecek.


{
int DiziRenkDegeri = Convert.ToInt16(DiziPiksel[s]);

if (DiziRenkDegeri > MaksX)


{
MaksX = DiziRenkDegeri;
}
if (DiziRenkDegeri < MinX)
{
MinX = DiziRenkDegeri;
}

}
txt1.Text = MinX.ToString();
txt2.Text = MaksX.ToString();

//Değerleri listbox'a ekliyor.


int RenkMaksPikselSayisi = 0; //Grafikte y eksenini ölçeklerken kullanılacak.
for (int k = 0; k <= 255; k++)
{
//listBox1.Items.Add("Renk:" + k + "=" + DiziPikselSayilari[k]);
//Maksimum piksel sayısını bulmaya çalışıyor.
if (DiziPikselSayilari[k] > RenkMaksPikselSayisi)
{
RenkMaksPikselSayisi = DiziPikselSayilari[k];
}
}

//Grafiği çiziyor. ************


Graphics CizimAlani;
Pen Kalem1 = new Pen(System.Drawing.Color.Yellow, 1);
Pen Kalem2 = new Pen(System.Drawing.Color.Red, 1);
CizimAlani = pictureBox2.CreateGraphics();

pictureBox2.Refresh();

int GrafikYuksekligi = 250;

double OlcekY = RenkMaksPikselSayisi / GrafikYuksekligi;


double OlcekX = 1.5;
int X_kaydirma = 10;

15
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

for (int x = 0; x <= 255; x++)


{
CizimAlani.DrawLine(Kalem1, (int)(X_kaydirma + x * OlcekX), GrafikYuksekligi,
(int)(X_kaydirma + x * OlcekX), (GrafikYuksekligi - (int)(DiziPikselSayilari[x] / OlcekY)));

if (x % 50 == 0)
{
CizimAlani.DrawLine(Kalem2, (int)(X_kaydirma + x * OlcekX), GrafikYuksekligi,
(int)(X_kaydirma + x * OlcekX), 0);
}
}
txt3.Text = RenkMaksPikselSayisi.ToString();
}

KARŞITLIK (CONTRAST)
Bir görüntünün ayırt edilebilirliğini ifade eden kontras ifadesini Türkçe olarak da kullanmaktayız. Resim
üzerindeki renk değerleri birbirine çok yakın değerlerde olursa (dar bir aralıkta toplandığında) düşük kontraslı
resim olur. Bunu görebilmek için resmin Histogramını çizdirmek gerekir. Bu resimlerin renk değerlerini
birbirinden uzaklaştırmak için resmin histogramı üzerinde gerdirme işlemi yapmak gerekir. Bunun için burada üç
farklı örnek üzerinde durulacaktır.
Resmin kontrasını (karşıtlığını) artırmak ile keskinliğini artırmak (sharpen) aynı şey değildir. Kontrasda resim
üzerindeki alanların renk değerleri birbirinden uzaklaştırılır. Keskinleştirmede ise alanların iç kısımları değil kenar
kısımları belirgin hale getirilir. Bu konu ileride gelecektir.

Kontras örneği: Resim renk değerlerinin arası açılmış Keskinleştirme: Kenarlar belirgin yapılmış (sharpen)

a) Lineer (Doğrusal) Kontras Uygulama (otomatik sınır belirleme)


Eğer histogram sınırları ortalarda bir yerde keskin bir şekilde oluşmuşsa tüm resim Lineer olarak siyah ve beyaz
bölgeye doğru gerdirilebilir. Aşağıdaki örnekte spektrumun dış sınırları ortada bir yerlerde direk olarak
sonlanmış (X1 ve X2 değerleri). Bu spektrum lineer olarak gerdirildiği zaman (Y1 ve Y2 ye çekildiğinde) herhangi
bir renk kaybı oluşmaz. Fakat dar bir aralıktaki renkler (60 ile 199 arası görünüyor) geniş bir aralığa
gerdirildiğinde (0-255 arasına) aralarda bazı renk değerleri doğal olarak resim üzerinde oluşmayacaktır. Buda
resmi noktalı (gürültülü) gibi gözükmesine neden olmaktadır. İkinci resimde bunu görüyoruz. Kontras
uygulanmış bu resmin spektrumuna da baktığımızda histogramı oluşturan çizgilerin aralarının açık olduğunu da
görebiliyoruz. Bu tür noktalı oluşan görüntülerde resmi yumuşatmak için ileride gelecek konulardan
bulanıklaştırma vs uygulanabilir. Bu durumda kenarlarda da bulanıklaşma olacaktır. Ardından Netleştirme
(sharpening) uygulanabilir.
Burada şuna da dikkat çekmek gerekir. Bir resim üzerinde bütün renkler aşağıda olduğu gibi ortada toplanmış
iken içerisinde bir kaçtane piksel beyaz yada siyah bölgelerde sınırların dışında olabilir. Oysa çok az sayıda birkaç
tane olan bu pikseller sınırları değiştireceğinden resmin kontrasını da etkileyecektir. O yüzden çok az sayıdaki
piksellerin buna yol açmaması için en fazla piksel sayısının belli bir oranı üzerinde olan piksellerin değerleri
sınırları bulmak için kullanılmalıdır. Aşağıdaki örnekte en fazla piksel sayısının (grafiğin en üst tepesi) 1/100 kadar
olan pikseller sınırları bulmak için (X1 ve X2 için) kullanılmıştır. Bu oran istenirse değiştirilebilir. Böylece çok

16
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

sayıdaki renkler resmi etkilememiş olur. Çok sayıdaki bu renkler zaten grafiğin ortalarında bir yerdeyse bunlar
zaten sınırları etkilemeyecektir. Burada söz konusu olan sınırların dışında bulunan birkaç pikselin renk değeridir.

Kontras için kullanacağımız formülü aşağıdaki gibi elde edebiliriz. Sonuçta bu formül lineer olarak grafik üzerinde
bir değeri elde etmek istediğimiz genel bir formüldür. Formülün çıkarılışı için Lineer bir grafik üzerindeki orantı
kullanılabilir.

Not: Bu formüldeki Y değerlerini A,B,C olarak değiştirmek iyi olacaktır. Resmin Y eksenine ait değerler gibi
algılanıyor. Y1,, A yap , Y2 -B yap, Y –C yap
(𝑋 − 𝑋1)
𝑌= (𝑌2 − 𝑌1) + 𝑌1
(𝑋2 − 𝑋1)
private void KONTRAS_histogram_Click(object sender, EventArgs e)
{
Color OkunanRenk, DonusenRenk;
//int R = 0, G = 0, B = 0;
int Red;

Bitmap GirisResmi, CikisResmi;


GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width; //GirisResmi global tanımlandı. İçerisine görüntü


yüklendi.
int ResimYuksekligi = GirisResmi.Height;

17
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi); //Cikis resmini oluşturuyor.


Boyutları giriş resmi ile aynı olur. Tanımlaması globalde yapıldı.

int X1 = Convert.ToInt16(txt1.Text);
int X2 = Convert.ToInt16(txt2.Text);
int A = 0; //Convert.ToInt16(textBox3.Text);
int B = 255; //Convert.ToInt16(textBox4.Text);

for (int x = 0; x < ResimGenisligi; x++)


{
for (int y = 0; y < ResimYuksekligi; y++)
{
OkunanRenk = GirisResmi.GetPixel(x, y);

Red = OkunanRenk.R;
//G = OkunanRenk.G;
//B = OkunanRenk.B;

//int Gri = (R + G + B) / 3;

int Gri = Red;

//*********** İnterpolasyon işlemi***************

int X = Gri;

int C = (((X - X1) * (B - A)) / (X2 - X1)) + A;

if (C > 255) C = 255;


if (C < 0) C = 0;

DonusenRenk = Color.FromArgb(C, C, C);


CikisResmi.SetPixel(x, y, DonusenRenk);
}
}
pictureBox3.Refresh();
pictureBox3.Image = null;
pictureBox3.Image = CikisResmi;

18
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

b) Lineer (Doğrusal) Kontras Uygulama-(Manuel Sınır Belirleme)


Yukarıdaki örnekte sınırlar (X1,X2) tüm spektrumu sonlara dayanmışsa (0-255 lere) bu resmi nasıl gerdireceğiz?
Bu durumda resmin daha gerdirirsek sınırlar spektrumun dışına çıkacak demektir. Böyle bir durumda sınırı aşan
değerler 0 ve 255 ile düzeltileceğinden resmin doğallığı kaybolacaktır. Yani resimde hiç bulunmasa bile siyah ve
beyaz alanlar artacaktır. Bunun çözümü için bir sonraki çoklu Lineer Grafik uygulanabilir. Fakat burada direk kişi
çekmek istediği sınırları kendisi belirlesin ve bunun sonucunun nasıl olacağını görelim.

c) Çoklu Lineer (doğrusal) Kontras Uygulama-(Manuel Sınır Belirleme)


Bir önceki maddede anlatıldığı şekilde resmin sınırları spektrumun sınırlarına dayanmış olabilir. Bu durumda tüm
resme aynı genişletmeyi uygulamak spetkrumun dışına çıkmaya neden oluyordu. Bunun yerine resim üzerinde
bazı bölgeleri daraltarak, bazı bölgeleri genişleterek farklı kontras bölgeleri oluşturarak uygun bir çözüm
bulabiliriz.

Şekil. Lineer germe fonksiyonu

2006.]

Not: Yukarıda verilen histogram örnekleri renkli resimlere de uygulanabilir. Histogram hesabı gri renk üzerinden
yapılırsa ve bulunan değerler üç kanal içinde uygulandığında sonuçlar gözlemlenebilir. Bu denemeler ödevler
içinde istenecektir.

---------------------------***-------------------------

19
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Renkli Resim Üzerinde Kontras Artırma-(Histogramsız uygulama)


Aşağıda hazır kullanım için geliştirilmiş formüller kullanılarak renkli resim üzerinde kontras yapabiliriz. Burada
temel mantık resmi 128 değerinin üzerindeki renkleri yukarı 255 doğru, aşağıdaki renkleri 0 doğru ötelemekten
ibarettir. F sayısı öteleme miktarını belirlerken, bunu kullanarak her üç kanalın renk değerini belirleyebiliriz. Bu
formül kullanıldığında renk değerleri 255 üzerine ve 0 altına inebileceğinden bu sınırlarda kesmek resmin aslında
doğallığını kaybettirir. Yani aşırı kontrasta resim üzerinde beyaz ve siyah bölgeler belirgin olarak artabilir. Onun
yerine yukarıda kullanılan histogram yöntemi ile kontras uygulamak daha iyi sonuç verir. Yani hangi sınır
değerlerin nereye çekileceğine grafikle görerek karar vermek daha iyi sonuçlar verir. Yine de bu formül pratik
kullanım için tercih edilebilir.
Görüntünün kontrasını ayarlama da İlk adım, aşağıdaki formülle verilen bir kontrast düzeltme faktörünü
hesaplamaktır:
259(𝐶 + 255) F: Kontras düzeltme faktörü (double)
𝐹=
255(259 − 𝐶)
C=Kontras seviye katsayısı

Algoritma'nın doğru çalışması için kontrast düzeltme faktörü (F) değerinin bir tamsayı değil, ondalık sayı (double)
olması gerekir. Formüldeki C değeri, istenilen kontrast seviyesini belirtir.
Bir sonraki adım, gerçek kontrast ayarını yapmaktır. Aşağıdaki formüller kırmızı (R), yeşil (G), mavi (M) renkler
için verilmiştir.
𝑅 ′ = 𝐹(𝑅 − 128) + 128
𝐺 ′ = 𝐹(𝐺 − 128) + 128
𝐵′ = 𝐹(𝐵 − 128) + 128
Bu formüllerden çıkan R,G,B renk değerlerinin 0-255 geçerli renk aralığında olması gerekir.
Kırmızı, yeşil ve mavi değerlerin 0'dan 255'e kadar geçerli bir aralıkta olmasını sağlar. Kontrast seviyesi (C) ise
+255 ile -255 arasında olmalıdır. Pozitif değerler kontrast miktarını artırırken, Negatif değerler kontrast miktarını
düşürecektir.
---------------------------***-------------------------

Program Kodları
Aşağıdaki resimler Orijinal resim, +128 Kontrast ve -128 kontrast miktarlarını göstermektedir.

public Bitmap Karsitlik()


{
int R = 0, G = 0, B = 0;
Color OkunanRenk, DonusenRenk;
Bitmap GirisResmi, CikisResmi;
GirisResmi = new Bitmap(pictureBox1.Image);

20
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

int ResimGenisligi = GirisResmi.Width; //GirisResmi global tanımlandı.


int ResimYuksekligi = GirisResmi.Height;
CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi); //Cikis resmini oluşturuyor. Boyutları
giriş resmi ile aynı olur.

double C_KontrastSeviyesi = Convert.ToInt32(textBox1.Text);

double F_KontrastFaktoru = (259 * (C_KontrastSeviyesi + 255)) / (255 * (259 -


C_KontrastSeviyesi));

for (int x = 0; x < ResimGenisligi; x++)


{

for (int y = 0; y < ResimYuksekligi; y++)


{
OkunanRenk = GirisResmi.GetPixel(x, y);
R = OkunanRenk.R;
G = OkunanRenk.G;
B = OkunanRenk.B;

R = (int)((F_KontrastFaktoru * (R - 128)) + 128);


G = (int)((F_KontrastFaktoru * (G - 128)) + 128);
B = (int)((F_KontrastFaktoru * (B - 128)) + 128);

//Renkler sınırların dışına çıktıysa, sınır değer alınacak.


if (R > 255) R = 255;
if (G > 255) G = 255;
if (B > 255) B = 255;

if (R < 0) R = 0;
if (G < 0) G = 0;
if (B < 0) B = 0;

DonusenRenk = Color.FromArgb(R, G, B);


CikisResmi.SetPixel(x, y, DonusenRenk);
}

}
pictureBox2.Image = CikisResmi;
}

ÖDEVLER
Ödev 1: (Parlaklık)
Sürgü kullanarak bir resmin parlaklığını artırma yada düşürme işlemini dinamik olarak gerçekleştirin.

21
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Ödev 2: (Eşikleme)
Form üzerinde iki tane sürgü kullanarak Eşikleme yapan bir program yazınız. Sürgüler grafik altında x ekseni
boyunca olsun. Sürgü ilerletildikçe resmin nasıl değiştiği gözlemlenebilsin. Olay şöyle çalışsın. Sürgülerin birisi 50,
diğeri 200 gösteriyorsa, Gri renk değeri 50 ile 200 da ise o pikseli direk göstersin. Bu iki sınırın dışında ise
göstermesin yani siyah yapsın.

Aynısını Renkli Resim içinde yapın. Yani Kırmızı, Yeşil ve Mavi kanallara göre 3 tane ayrı Histogram grafiği çizdirin.
Her grafiğin altında iki tane sürgü bulunsun. Okunan renk Kanal değeri (örneğin kırmızı) Bu sürgülerin değerleri
arasında ise kırmızıyı kendi renginde göstersin. Dışında ise hiç göstermesin (yani siyah yapsın). Aynı işlemi diğer
üç kanal içinde yapmanız gerekir.
Histogram grafikleri bize hangi sınırı dışarıda tutacağımız daha iyi gösterir.

Ödev 3: (Histogram ile Resmi Sıkıştırma)


a) Aşağıdaki gibi bir siyah beyaz resmin belli bir sınırın ötesindeki beyaz renkleri sıfırlayan ve o bölgelerin
koyulaşmasını sağlayan ve bunu histogram üzerinden ayarlayan programı yazınız. Histogramın altındaki
sürgü sürüklendiğinde resim değişsin ve resmin histogramı tekrar yenilensin. Aşağıdaki histogramda tek
bir sürgü kullanılmıştır. Beyaz bölge geriye çekildiğinde tüm 0-255 arasındaki sayılar Ölçeklenerek
yenilenmesi gerekir. Diyelim sürgü 180 çekilirse, önceden 255 olan renk artık 180 değerine gelmiş olması
gerekir. Tüm diğer renk değerleri de 0-180 arası ölçeklenmelidir.

b) Aynı uygulamayı çift sürgü ile yapın. Yani resmi hem aşağıdan yukarı doğru sıkıştırın, hemde üstten aşağı
doğru sıkıştırın. Böyle bir resimde renk değerleri belli bir aralık içine gelmiş olacaktır.

c) Yeni oluşan resim üzerinde istenen noktaya Mouse ile tıklandığında Textbox içinde o noktanın X ve Y
koordinatını göstersin. Ayrıca R, G, B şeklinde üç renk değerinide göstersin. Böylece resmin hangi kısmı
nasıl bir renk değeri almış kontrol edilsin. Bunun için MouseMove ve MouseDown olaylarına
bakmalısınız. Örnek kodlar İnt.Tab.Prg dersinin sayfalarında vardır.

22
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Ödev 4: (Gri Resim üzerinde Histogram ile Resmin Kontrasını Artırma)


Aşağıdaki gibi bir resmin histogramını çizdirdikten sonra, Kontras uygulayalım. Kontrasın uygulanacak sınır
değerlerini Grafiğin bulunduğu picturebox üzerinden Mouse ile tıklayarak belirleyelim. Mouse’un sol tuşuna
Picturebox2 üzerinde tıklayınca okuduğu x koordinatını X1 kabul edilsin Textbox1 de gösterilsin. Daha sonra
mouse’un Sağ tuşuna Picturebox2 üzerinde tıklayınca okunan koordinatın x değeri X2 olarak kabul edilsin ve bu
da Textbox2 de gösterilsin. Bu sınırlar 0 ve 255 çekilecek şekilde bir başka düğmeye tıklayınca kontras uygulasın.
(Dikkat: Pixturebox 2 nin boyu 400 ise, x=400 koordinatından alınan renk değeri 400 olamaz. Bu nedenle alınan X
koordinatlarını ölçeklemelisiniz. Ölçek = 255/400 olur. Kendi uygulamanıza göre ayarlayın).

Ödev 5: (Renkli resimler üzerinde histogramla Kontras artırma)


a) Kontras uygulamasını her bir Renk kanalı için ayrı ayrı uygulayın. Önce her renk kanalının Histogramını
çizdirin. Grafik üzerinden 0 ve 255 çekilecek sınır değerlerini üstteki örnekde olduğu gibi mouse ile
tıklayarak bulun. Yada tahmini olarak renk için sınırları belirleyin (50 lik kızmızı dikey çizgileri çizdirirseniz
gözle daha iyi görürsünüz). Bu değerleri (6 tane değer olur) textboxlara yazın. Ardından başka bir butona
basınca bu her bir renk değeri için kendi sınır değeri kullanılarak yeni kontras uygulanmış renk değerleri
ile resmi yeniden oluşturun. Bu yeni oluşan resmi, orijinal resimle karşılaştırın. Renkli resimde başarılı bir
Kontras yapabildinizmi görün. Renkli resimde iyi bir kontras oluşturmak için ne yapılabilir yazarak
yorumlayın.
b) Ders notları içinde renkli resim için verilen hazır bir formül vardır. Bu formülü kullanarak elde ettiğiniz
kontras sonucunu kendi bulduğunuz çözüm ile karşılaştırın. Ödev içinde yorumlayarak gösterin.

23
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Ödev 6: (Mouse ile tıklayarak belirlenen bölgenin içerisindeki renkleri değiştirme)


Picturebox üzerinde mouse ile tıklayarak belli bir kapalı bölge çizin. Alanı gözle de görmek için kesikli olarak bir
çizgi ile çerçeve oluşturun. Daha sonra bu bölgenin içerisindeki renk değerleri için Sürgü ile
i) Parlatma (Brightness)
ii) Kontras Uygulayın. Kontrası hem histogram çizdirerek, hemde hazır formül ile uygulayın.
iii) Renk değişimi yaptırın. R, G, B nin her bir değeri için ayrıca üç sürgü kullanabilirsiniz.

a) Çizgilerle belli bir alanı çizmek için İnt.Tab.Prg dersinin sayfasında örnek kodlar vardır. Oradaki bilgilerle
bu çizimi yaptırın.
b) Tıklanan noktanın Kapalı bir poligonun içerisinde olup olmadığını bulmak için Analik Geometri konuları
içinde bir araştırma yapmalısınız. Yani tıklanan nokta bir poligonun (çokgenin) içinde mi kalır yoksa
dışında mı kalır bunu araştırın. Bulduğunuz formül ve yöntemleri anlatın. Ezbere olmasın, mantığını
anlayın.

Ödev 7:
Renkli Resimler üzerinde farklı kanalların histogramlarını çizdirme yapınız. Sonuçları yorumlayarak bu bilgiler
nelerde kullanılabilir yazınız.
Ödev 8:
Eski tarihi bir siyah resmi alıp bunun üzerinde belirleyeceğiniz 10 tane noktanın rengini siz verin. Bu renk
tahminlerinden yola çıkarak tüm resmi renklendirme işlemini kendi yazacağınız algoritma yapsın…
Ödev 9:
İyi bir gece görüş dürbünü yapabilmek için sadece ortamın ışığını artırmak yetmez. Bunun için renklerinde
birbirinden uzaklaştırılması (kontrası artırmak) gerekir. Bu işlem için kendiniz bir gece görüş kamerası algoritması
geliştirin. Gece karanlığında çok az ışıkta çekilmiş bir çok fotografı en iyi gündüz çekimine dönüştüren
algoritmayı yazın. Çekimler geceleyin bir ay ışığı görüntüsü olabilir, karanlık bir odada camdan az bir ışık geliyor
olabilir. İyi bir algoritma geliştirmek için kontras sınırlarını kendiniz sürükleyerek ayarlamaya çalışın. Ayrıca belli
bölgelerde ışık artırma işlemide yapın. Birde Histogram grafiğinin ortasında bir noktadan kaydırma yaparak onun
altındaki renkleri açarak, yukarısındaki renkleri ise bir birine yaklaştırarak daha iyi görüntüler elde etmeye
çalışın.

24
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Ödev 10:
Aşağıdaki gibi kişiye özel renk paleti oluşturmak için bir uygulama yapın. Bunun için Pikturebox içinde 16 milyon
rengin her birini oluşturun. (R*G*B=255*255*255 = 16.581.375). Mantığını kendiniz bulacaksınız. Ardından yan
tarafa bir skala daha oluşturun. Ortadan bir renk seçildiğinde o rengin tonlarını açıktan koyuya doğru bir şerit
halinde göstersin. Böylece kişi ortadan hangi rengi atamak istediğini belirlesin, yandan da bu rengin tonlarını
oluştursun. En son karar verdiği rengin RGB değerlerini aşağıda göstersin ve Bu rengi kaydet dediği zaman yanda
oluşturulan küçük pencerelerin içine rengi kaydetsin (yani orda göstersin). Böylece kişiye özgü bir renk paleti
oluşmuş olsun.

Ödev 11:
Gri Resmi, renkli resme dönüştüren bir program yazın. Bu dönüşüm normal algoritma ile zordur. İçerisinde yapay
zekaya ihtiyaç vardır. Yapay zeka kısmını kendimiz şu şekilde oluşturabiliriz. Resmin üzerinden yaklaşık 10 tane
nokta seçin. Bu noktalardaki renkleri yan tarafta bir Textboxlarda gösterin. Aldığınız bu örnek rengin tahmini
olması gereken renk değerini atayın. Bu tahmini renkler üzerinde yukarı aşağıya tolerans belirleyelim. Bu şekilde

25
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

10 tane rengin tahmini üzerinde resmi tekrar renkli resme dönüştürün. Yada kendiniz farklı bir algoritma
geliştirin. 3 tane resmi aynı ekranda gösterin (Orijinal, Gri, Dönüşmüş Resim)

Ödev 12
Aşağıda resimlerde görüldüğü gibi bir resmi sulu boyama efekti verecek şekilde renklendirme algoritması
geliştirin. Burada kırmızı bölgedeki detaylar kırmızı tek renkle boyanıyor muş gibi olsun. Mavilerde tek mavi
renkle boyanıyor muş gibi olsun. Bunun Eşikleme mantığını kullanabilirsiniz. Tabii bu mantığı daha da
geliştirmeniz gerekir. Algoritmanın çalıştığını farklı resimler gösterin. (Not: Aşağıdaki örnek hatalıdır. Çünkü sarı
çiçekte oranın hepsini sarı görmek isteriz. Mavini olduğu bölge hepsi mavi olmalıdır. Kırmızı da aynı şekilde)

26
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

GÖRÜNTÜ İŞLEME - (3.Hafta)

GEOMETRİK DÖNÜŞÜMLER
Geometrik dönüşümler resim üzerindeki her pikselin bir konumdan (x1,y1) başka bir konuma (x2,y2)
haritalanmasıdır. Bununla ilgili olarak aşağıdaki işlemler kullanılabilir.
• Taşıma (Move):Resim içeriğinin konumunu değiştirme. Kanvas (tuval) üzerinde pikseller hareket ettirilir.
• Aynalama (Mirror): Resmin aynadaki görüntüsüne benzer simetrisini alma, görüntüyü takla attırma.
• Eğme ve Kaydirma (Skew): Resmin bir kenarından tutup kaydırma işlemidir.
• Ölçekleme (Zoom/Scale): Resim boyutunu değiştirme yada yaklaştırma uzaklaştırma.
• Döndürme (Rotate): Resmi çevirme.

Bu temel operatörler için aşağıdaki genel fonksiyonu kullanabiliriz. Bu formülde A matrisi ölçekleme, döndürme
ve aynalama işlemlerini formülüze ederken, B matrisi taşıma için kullanılır. Perspektif dönüşümlerde ise her iki
matris de kullanır.
𝑥2 𝑥1
[𝑦 ] = [𝐴] [𝑦 ] + [𝐵]
2 1

Geometrik dönüşümler görüntünün belli bir bölgesini yaklaştırma, yada belli bir seri resmin birleştirme için
kullanılabilir. Örneğin sırayla çekilmiş resimleri tek bir resim halinde panoramik (geniş açılı resimler) halin
getirmek için kullanılabiilr.

TAŞIMA (Translate)
Taşıma operatörü, giriş resmindeki her pikseli, çıkış resmindeki yeni bir konuma taşıma işlemidir. Orjinal
resimdeki (x1,y1) koordinatındaki her piksel belli bir öteleme mesafesi (βx, βy) boyunca taşınarak yeni konumu
olan (x2,y2) koordinatına yerleştirilir. Taşıma işlemi görüntü üzerinde iyileştirmeler yaparken yada başka
uygulamaların alt işlemleri olarak kullanılabilir.

Taşıma operatörü aşağıdaki formüller kullanılarak gerçekleştirilir.

𝑥2 = 𝑥1 + 𝑇𝑥
𝑦2 = 𝑦1 + 𝑇𝑦

Matris formatında

𝑥2 𝑥1 𝑇𝑥
[𝑦 ] = [𝑦 ] + [𝑇 ]
2 1 𝑦

Yeni oluşan koordinatlar (x2,y2) resmin sınırları dışına çıktıysa ya yok sayılır veya sınırlar genişletilerek, geride
bırakılan boşluk alanları doldurulur. Bu durumda iki tane alandan bahsedebiliriz. Bir tanesi görüntünün
bulunduğu resim (image) diğeri ise üzerinde kaydırıldığı zemin yani tuval (canvas) (bkz resim a). Burada resim
kaydırıldığında altında kanvas da görünecektir (resim b). Kanvas yeni sınırları da kapsayacak şekilde büyütülürse
resmin dışarı çıkan kısımları tekrar görünecektir fakat zeminde kanvas da görünecektir (resim c). Kanvas istenen
renge boyanabilir yada renksiz düşünülebilir (resim d).

1
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

a) b) c) d)

Programlama

public Bitmap Tasima()


{
Color OkunanRenk;
Bitmap GirisResmi, CikisResmi;
GirisResmi = new Bitmap(pictureBox1.Image);
int ResimGenisligi = GirisResmi.Width;
int ResimYuksekligi = GirisResmi.Height;
CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

double x2 = 0, y2 = 0;

//Taşıma mesafelerini atıyor.


int Tx = 100;
int Ty = 50;

for (int x1 = 0; x1 < (ResimGenisligi); x1++)


{
for (int y1 = 0; y1 < (ResimYuksekligi); y1++)
{
OkunanRenk = GirisResmi.GetPixel(x1, y1);

x2 = x1 + Tx;
y2 = y1 + Ty;

if (x2 > 0 && x2 < ResimGenisligi && y2 > 0 && y2 < ResimYuksekligi)
CikisResmi.SetPixel((int)x2, (int)y2, OkunanRenk);
}
}
pictureBox2.Image = CikisResmi;
}

2
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Taşıma işlemini Mouse ile yaptırma

bool TasimaIslemi = false;

private void TASIMA_Click(object sender, EventArgs e)


{
TasimaIslemi = true;

ResmiDiziyeYukle();
}

ArrayList diziX = new ArrayList();


ArrayList diziY = new ArrayList();

ArrayList diziR = new ArrayList();


ArrayList diziG = new ArrayList();
ArrayList diziB = new ArrayList();

public void ResmiDiziyeYukle()


{
Bitmap GirisResmi = new Bitmap(pictureBox1.Image);

for (int x = 0; x < GirisResmi.Width; x++)


{
for (int y = 0; y < GirisResmi.Height; y++)
{
Color OkunanRenk = GirisResmi.GetPixel(x, y);

diziR.Add(OkunanRenk.R);
diziG.Add(OkunanRenk.G);
diziB.Add(OkunanRenk.B);

diziX.Add(x);
diziY.Add(y);
}
}
}

int Tx1 = 0, Ty1 = 0, Tx2 = 0, Ty2 = 0;


private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if(TasimaIslemi==true)
{
Tx1 = e.X;
Ty1 = e.Y;
}

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)


3
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

{
if (TasimaIslemi == true)
{
Tx2 = e.X;
Ty2 = e.Y;

int Tx = Tx2 - Tx1;


int Ty = Ty2 - Ty1;

Tasima(Tx, Ty);

public void Tasima(int Tx, int Ty)


{
Bitmap GirisResmi = new Bitmap(pictureBox1.Image);
Bitmap CikisResmi = new Bitmap(GirisResmi.Width, GirisResmi.Height); //Cikis resmini
oluşturuyor. Boyutları giriş resmi ile aynı olur. Tanımlaması globalde yapıldı.

for (int i=0; i<diziX.Count; i++)


{
int x1 = Convert.ToInt32(diziX[i]);
int y1 = Convert.ToInt32(diziY[i]);
int R = Convert.ToInt32(diziR[i]);
int G = Convert.ToInt32(diziG[i]);
int B = Convert.ToInt32(diziB[i]);

int x2 = x1 + Tx;
int y2 = y1 + Ty;

Color DonusenRenk = Color.FromArgb(R, G, B);

if(x2>0 && x2<CikisResmi.Width && y2>0 && y2<CikisResmi.Height)


{
CikisResmi.SetPixel(x2, y2, DonusenRenk);
}

}
pictureBox1.Image = CikisResmi;
}

AYNALAMA (Mirror/Reflect/Flip)
Yansıtma işlemi, görüntüyü orijinal resimdeki (x1, y1) konumundan alarak, belirlenen eksen veya bir nokta
etrafında yansıtarak yeni bir konuma (x2, y2) yerleştirilmesidir.

Bununla ilgili yapılabilecek dönüşümler şu şekildedir.

a) Ekranın orta noktasına (x0 -y0) göre aynalama

Bunun için x0 mesafesinden x1 mesafesini çıkarırsak birinci koordinatın eksene uzaklığını buluruz. Bunun iki katını
alıp x1 mesafesini de eklersek x2 koordinatının mesafesini bulmuş oluruz. y koordinatları değişmeyecektir.
Ekranın ortası yerine tıklanan noktayı eksen kabul ederek aynalama da benzer şekilde yapılabilir.

𝑥2 = 𝑥1 + 2(𝑥0 − 𝑥1 )

𝑥2 = −𝑥1 + 2𝑥0

4
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

𝑦2 = 𝑦1

b) y0 noktasından geçen yatay eksen etrafında aynalama


Bunun için de benzer mantık kullanılabilir. Bu durumda formüller aşğıdaki gibi olacaktır.
𝑥2 = 𝑥1

𝑦2 = −𝑦1 + 2𝑦0

c) (x0,y0) noktasından geçen herhangi bir θ açısına sahip bir eksen etrafında aynalama.
∆= (𝑥1 − 𝑥0 ) 𝑆𝑖𝑛𝜃 − (𝑦1 − 𝑦0 ) 𝐶𝑜𝑠𝜃
olmak üzere
𝑥2 = 𝑥1 + 2 𝛥 (−𝑆𝑖𝑛𝜃) yeni x koordinatını verir.
𝑦2 = 𝑦1 + 2 𝛥 (𝐶𝑜𝑠𝜃) yeni y koordinatını verir.
Eğer (x0,y0) noktası resmin merkezi olmazsa, yansıyan görüntü sınırların dışına çıkacaktır.

Programlama

Orta dikey eksen etrafında aynalama Orta yatay eksen etrafında aynalama

5
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

45 derecelik eksen etrafında aynalama

public Bitmap Aynalama()


{
Color OkunanRenk;
Bitmap GirisResmi, CikisResmi;
GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width;


int ResimYuksekligi = GirisResmi.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

double Aci = Convert.ToDouble(textBox1.Text);


double RadyanAci = Aci * 2 * Math.PI / 360;

double x2 = 0, y2 = 0;

//Resim merkezini buluyor. Resim merkezi etrafında döndürecek.


int x0 = ResimGenisligi / 2;
int y0 = ResimYuksekligi / 2;

for (int x1 = 0; x1 < (ResimGenisligi); x1++)


{
for (int y1 = 0; y1 < (ResimYuksekligi); y1++)
{
OkunanRenk = GirisResmi.GetPixel(x1, y1);

//----A-Orta dikey eksen etrafında aynalama ----------------


//x2 = Convert.ToInt16(-x1 + 2 * x0);
//y2 = Convert.ToInt16(y1);

//----B-Orta yatay eksen etrafında aynalama ----------------


//x2 = Convert.ToInt16(x1);
//y2 = Convert.ToInt16(-y1 + 2 *y0);

//----C-Ortadan geçen 45 açılı çizgi etrafında aynalama----------


double Delta = (x1 - x0) * Math.Sin(RadyanAci) - (y1 - y0) * Math.Cos(RadyanAci);

x2 = Convert.ToInt16(x1 + 2 * Delta * (-Math.Sin(RadyanAci)));


y2 = Convert.ToInt16(y1 + 2 * Delta * (Math.Cos(RadyanAci)));

if (x2 > 0 && x2 < ResimGenisligi && y2 > 0 && y2 < ResimYuksekligi)
CikisResmi.SetPixel((int)x2, (int)y2, OkunanRenk);
}
}
6
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

pictureBox2.Image = CikisResmi;
}

d) İki noktası verilen eksen etrafında aynalama: (DÜZENLE-KENDİ TARZINLA ANLAT!)


İki noktası bilinen bir doğrunun şekli aşağıda görülmektedir

Şekil. İki noktası bilinen doğrunun eğimi karşı kenarın komşu kenara oranı ile belirtilir.
İki noktası bilinen doğrunun eğimin den hareket edersek x ve y değerleri arasındaki bağıntı bu doğrunun
eğiminden bulunur. denklemini ifade eder.
𝑦2 − 𝑦1 𝑦 − 𝑦1
𝑚= =
𝑥2 − 𝑥1 𝑥 − 𝑥1

İçler dışlar çarpımı yaparak x değerini girdi y değerini çıktı olarak verirsek buna göre doğrunun denklemi
aşağıdaki şekilde olacaktır. Bu denklemde sadece x ve y değerleri bilinmiyor. Diğerlerinin hepsi bilinen sayısal bir
değerdir.
(𝑦2 − 𝑦1)(𝒙 − 𝑥1)
𝒚= + 𝑦1
(𝑥2 − 𝑥1)

Örnek: Noktanın doğruya göre simetriğinin bulunması için aşağıdaki şekilde verildiği şekliyle somut bir örnek
üzerinde görelim. Buradaki doğrunun denklemi ve A noktasının koordinatları bilinmektedir. Bilinenler ışığında B
noktasının koordinatlarını bulmaya çalışalım.

Bir noktanın doğruya göre simetriğinin görünümü


7
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Doğru denkleminden doğrunun eğimi bulunmaktadır. Denklemde y yalnız bırakılır ve x’in katsayısı eğimi ifade
etmektedir. Doğrunun eğimi aşağıda verilmiştir.

A noktasının eğime olan dik uzaklığı ile B noktasının eğime olan dik uzaklığı birbirine eşittir. Bu eşitlik yardımı ile
koordinat bilgisine ulaşılacaktır. A noktası ile B noktası arasındaki uzaklığın orta noktası yani C noktasının
koordinatları aşağıda bulunmaktadır.

C noktasının x ve y noktaları doğrunun denkleminde yerine yazılırsa aşağıdaki eşitlikler elde edilir.

Birbirine dik doğruların eğimleri çarpımı 1 eşittir. Bu eşitlik ile bir denklem daha türetilecektir. Öncelikle AB
doğrusunun eğimi aşağıdaki gibi ifade edilmektedir.

Doğrunun eğimi ve AB doğrusunun eğimlerinin çarpım ifadesinden aşağıdaki denklem elde edilir.

Yukarıdaki (2a+b=8) denklemi ile (a-2b=-5) eşitliği alt alta toplanarak denklemdeki bilinmeyen (a, b) değerleri
bulunur (iki bilinmeyenin çözümü için iki denklem gerekir).

Bu noktalarda zaten aynalamanın yapılmış olduğu noktalar olmuş olur.

EĞME-KAYDIRMA (Shearing)
Resmin bir tarafı sabit dururken diğer tarafının x ekseni yada y ekseni doğrultusunda kaydırmak için aşağıdaki
matrisi kullanabiliriz.
x-ekseni doğrultusunda kaydırmak için;
8
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

𝑥2 1 𝑏 𝑥1 𝑥2 = 𝑥1 + 𝑏 𝑦1
[𝑦 ] = [ ][ ]
2 0 1 𝑦1
𝑦2 = 𝑦1

𝑥2 1 −𝑏 𝑥1 𝑥2 = 𝑥1 − 𝑏 𝑦1
[𝑦 ] = [ ][ ]
2 0 1 𝑦1
𝑦2 = 𝑦1

y-ekseni doğrultusunda kaydırmak için;


𝑥2 1 0 𝑥1 𝑥2 = 𝑥1
[𝑦 ] = [ ][ ]
2 𝑏 1 𝑦1
𝑦2 = b𝑥1 + 𝑦1

𝑥2 1 0 𝑥1 𝑥2 = 𝑥1
[𝑦 ] = [ ][ ]
2 −𝑏 1 𝑦1
𝑦2 = −b𝑥1 + 𝑦1

Ödev: Üst taraftan diğer yönlerdende verilmeyen eğilme formüllerini çıkarın.


Programlama

public Bitmap Egme_Kaydirma()


{
Color OkunanRenk;
Bitmap GirisResmi, CikisResmi;
GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width;


9
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

int ResimYuksekligi = GirisResmi.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

//Taşıma mesafelerini atıyor.


double EgmeKatsayisi = 0.2;
double x2 = 0, y2 = 0;

for (int x1 = 0; x1 < (ResimGenisligi); x1++)


{
for (int y1 = 0; y1 < (ResimYuksekligi); y1++)
{
OkunanRenk = GirisResmi.GetPixel(x1, y1);

// +X ekseni yönünde
//x2 = x1 + EgmeKatsayisi * y1;
//y2 = y1;

// -X ekseni yönünde
//x2 = x1 - EgmeKatsayisi * y1;
//y2 = y1;

// +Y ekseni yönünde
//x2 = x1;
//y2 = EgmeKatsayisi * x1 + y1;

// -Y ekseni yönünde
x2 = x1;
y2 = -EgmeKatsayisi * x1 + y1;

if (x2 > 0 && x2 < ResimGenisligi && y2 > 0 && y2 < ResimYuksekligi)
CikisResmi.SetPixel((int)x2, (int)y2, OkunanRenk);
}
}
pictureBox2.Image = CikisResmi;
}

ÖLÇEKLEME (Scaling)
Ölçekleme işlemi bir görüntünün boyutunu veya bir bölümünü küçültme yada büyültmek için kullanılır. Bu işlem
görüntü üzerinde alınan bir grup matrisin pikselin değerini daha küçük yada büyük matrise dönüştürme ile
gerçekleştirilir. Böylece matris büyüklüğüne göre ya pikseller çoğaltılır (yaklaştırma), yada azaltılır (uzaklaştırma).
Ölçeklenen resimler büyük resimlerin küçültülerek daha küçük hafızalarda saklanması, yada büyüterek belli bir
bölgeye dikkat çekmek için kullanılabilir.
Uzaklaştırma (Küçültme)(Zoom out)
Yeni oluşturulacak görüntüdeki pikselin değeri için iki farklı teknik kullanılabilir.
a) Piksel değiştirme: Bir grup komşu pikselin değeri, tek bir piksel değerine dönüştürülürken içlerinden birinin
değerine yada rastgele herhangi birinin değerine dönüştürülebilir. Bu metot işlemler açısından daha basittir
fakat örneklenen pikseller arasındaki farklılık çok fazla ise zayıf sonuçlara yol açabilir.

10
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

b) Piksel İnterpolasyonu: İkinci metod ise komşu pikseller arasında istatistiksel bir örnekleme yaparak (örneğin
ortalamasını alarak) oluşturulacak pikselin değerini belirler.

Şekil. Piksel değiştirmede dörtlü çerçevelerin sol üst köşelerindeki değerler kullanılmıştır. İnterpolasyonda ise
dört tane pikselin ortalama değeri kullanılmıştır.

Programlama (Küçültme-Piksel Değiştirme Metodu)


Giriş resmini x ve y yönünde birer piksel atlayarak okursak ve okunan değerleri yeni resimde sırayla yerleştirirsek
1/2x lik bir küçültme sağlamış oluruz. Döngüdeki x ve y artış değeri küçültme katsayısı olacaktır.

public Bitmap Kucultme_DegistirmeMetodu()


{
Color OkunanRenk;
Bitmap GirisResmi, CikisResmi;
GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width;


int ResimYuksekligi = GirisResmi.Height;
CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

int x2= 0, y2 = 0; //Çıkış resminin x ve y si olacak.


int KucultmeKatsayisi = 2;
for (int x1 = 0; x1 < ResimGenisligi; x1=x1+KucultmeKatsayisi)
{
y2 = 0;
for (int y1 = 0; y1 < ResimYuksekligi; y1 = y1 + KucultmeKatsayisi)

11
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

{
OkunanRenk = GirisResmi.GetPixel(x1, y1);

CikisResmi.SetPixel(x2, y2, OkunanRenk);


y2++;
}
x2++;
}
pictureBox2.Image = CikisResmi;
}

Programlama (Küçültme-İnterpolasyon Metodu)


Giriş resmini x ve y yönünde küçültme katsayısı kadar atlayarak okursak ve her atladığında aradaki piksellerin
ortalama değerini alırsak ve bu ortalama değerleri çıkış resmine aktarırsak 1/x lik bir küçültme sağlamış oluruz.

public Bitmap Kucultme_InterpolasyonMetodu()


{
Color OkunanRenk, DonusenRenk;
Bitmap GirisResmi, CikisResmi;
int R = 0, G = 0, B = 0;

GirisResmi = new Bitmap(pictureBox1.Image);


int ResimGenisligi = GirisResmi.Width; //GirisResmi global tanımlandı.
int ResimYuksekligi = GirisResmi.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi); //Cikis resminin boyutları

int x2 = 0, y2 = 0; //Çıkış resminin x ve y si olacak.


int KucultmeKatsayisi = 2;

for (int x1 = 0; x1 < ResimGenisligi; x1 = x1 + KucultmeKatsayisi)


{
y2 = 0;
for (int y1 = 0; y1 < ResimYuksekligi; y1 = y1 + KucultmeKatsayisi)
{
//x ve y de ilerlerken her atlanan pikselleri okuyacak ve ortalama değerini alacak.
R = 0; G = 0; B = 0;
try //resim sınırının dışına çıkaldığında hata vermesin diye
{
for (int i = 0; i < KucultmeKatsayisi; i++)
{
for (int j = 0; j < KucultmeKatsayisi; j++)
{
12
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

OkunanRenk = GirisResmi.GetPixel(x1 + i, y1 + j);

R = R + OkunanRenk.R;
G = G + OkunanRenk.G;
B = B + OkunanRenk.B;

}
}
}
catch { }

//Renk kanallarının ortalamasını alıyor


R = R / (KucultmeKatsayisi * KucultmeKatsayisi);
G = G / (KucultmeKatsayisi * KucultmeKatsayisi);
B = B / (KucultmeKatsayisi * KucultmeKatsayisi);

DonusenRenk = Color.FromArgb(R, G, B);


CikisResmi.SetPixel(x2, y2, DonusenRenk);
y2++;
}
x2++;
}

return CikisResmi;
}

Yaklaştırma (Büyültme)(Zoom in)


Bir görüntünün tamamı yada belli bir bölgesi büyütülürken benzer bir işlemle, tek piksel çoğaltma yada
interpolasyon alarak çoğalma kullanılabilir.
a) Piksel Değiştirme: Bu yöntemde ele alınan pikselin değeri değiştirilmeden istenen matris büyüklüğüne göre
çoğaltılır. Matris büyüklüğü burada Ölçekleme skalasına bağlı olarak değişir.
b) Piksel İnterpolasyonu: Komşu piksellerin değerleri arasında fark, oluşturulacak piksel sayısına bağlı olarak
kademeli şekilde belirlenebilir (interpolasyon işlemi). Böylece piksel geçişleri daha az bir keskinliğe sahip olmuş
olur.

Şekil. Yakınlaştırma yöntemleri. a) Piksel değeri ile çoğaltma, b) İnterpolasyon ile çoğaltma.

13
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Programlama

private void button1_Click(object sender, EventArgs e)


{
Color OkunanRenk;
Bitmap GirisResmi, CikisResmi;
GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width;


int ResimYuksekligi = GirisResmi.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

int BuyutmeKatsayisi = Convert.ToInt32(textBox1.Text);

int x2 = 0, y2 = 0;

for (int x1 = 0; x1 < ResimGenisligi; x1++)


{

for (int y1 = 0; y1 < ResimYuksekligi; y1++)


{

OkunanRenk = GirisResmi.GetPixel(x1 , y1 );

for (int i = 0; i < BuyutmeKatsayisi; i++)


{
for (int j = 0; j < BuyutmeKatsayisi; j++)
{
x2 = x1* BuyutmeKatsayisi + i;
y2 = y1 * BuyutmeKatsayisi + j;

if (x2 > 0 && x2 < ResimGenisligi && y2 > 0 && y2 < ResimYuksekligi)
CikisResmi.SetPixel(x2 , y2 , OkunanRenk);

}
}
}

pictureBox2.Image = CikisResmi;

DÖNDÜRME (Rotation)
Döndürme işlemi bir nokta etrafında belli bir açı (θ) değerinde çevirerek giriş resmindeki (x1,y1) koordinatını
çıkış resmindeki (x2,y2) noktasına taşıma işlemidir. Çoğu döndürme işleminde sınırların dışına çıkan kısımlar yok
sayılır.
14
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Döndürme işlemi çoğunlukla resmin görünümü daha iyi hale getirmek için kullanılabilir. Afin işlemlerinde
(persfektif bakış) de kullanılan bir işlem olacaktır.

Döndürme işlemi için formüllerimizi çıkaralım. Bir orijin (0,0) etrafında x-y eksen takımını saat yönünde θ açısı
kadar döndürdüğümüzde şekildeki gibi olacaktır. Burada x1 ve y1 değerleri ile θ açısı bilenen değerlerdir. x2 ve
y2 değerlerini bulmaya çalışalım. θ açısının bulunduğu üçgenlerin kenarlarına a,b,c,d sembollerini atarsak
aşağıdaki formüllerimiz çıkacaktır.

𝑑 𝑆𝑖𝑛𝜃 1 𝑆𝑖𝑛𝜃
𝑇𝑎𝑛𝜃 = → 𝑑 = 𝑥2 𝑇𝑎𝑛𝜃 → 𝑑 = 𝑥2 𝑥1 = 𝑎 + 𝑏 → 𝑥1 = 𝑥2 + 𝑦1 →
𝑥2 𝐶𝑜𝑠𝜃 𝐶𝑜𝑠𝜃 𝐶𝑜𝑠𝜃

𝑏 𝑆𝑖𝑛𝜃 1 𝑆𝑖𝑛𝜃
𝑇𝑎𝑛𝜃 = → 𝑏 = 𝑦1 𝑇𝑎𝑛𝜃 → 𝑏 = 𝑦1 𝑥2 = 𝑥1 − 𝑦1 →
𝑦1 𝐶𝑜𝑠𝜃 𝐶𝑜𝑠𝜃 𝐶𝑜𝑠𝜃

𝑥2 = 𝑥1 𝐶𝑜𝑠𝜃 − 𝑦1 𝑆𝑖𝑛𝜃

𝑆𝑖𝑛𝜃
𝑑 𝑑 (𝑥2 𝐶𝑜𝑠𝜃 )
𝑆𝑖𝑛𝜃 = →𝑎= → 𝑎= → 1 𝑆𝑖𝑛𝜃
𝑎 𝑆𝑖𝑛𝜃 𝑆𝑖𝑛𝜃 𝑦2 = 𝑐 + 𝑑 → 𝑦2 = 𝑦1 + 𝑥2 →
𝐶𝑜𝑠𝜃 𝐶𝑜𝑠𝜃
1
𝑎 = 𝑥2 1 𝑆𝑖𝑛𝜃
𝐶𝑜𝑠𝜃 𝑦2 = 𝑦1 + (𝑥1 𝐶𝑜𝑠𝜃 − 𝑦1 𝑆𝑖𝑛𝜃) →
𝐶𝑜𝑠𝜃 𝐶𝑜𝑠𝜃
𝑆𝑖𝑛𝜃
𝑏 𝑏 (𝑦1 𝐶𝑜𝑠𝜃 )
𝑆𝑖𝑛𝜃 = →𝑐= → 𝑐= → 1 𝑆𝑖𝑛2 𝜃
𝑐 𝑆𝑖𝑛𝜃 𝑆𝑖𝑛𝜃 𝑦2 = 𝑦1 + 𝑥1 𝑆𝑖𝑛𝜃 − 𝑦1 →
𝐶𝑜𝑠𝜃 𝐶𝑜𝑠𝜃
1
𝑐 = 𝑦1 1 𝑆𝑖𝑛2 𝜃
𝐶𝑜𝑠𝜃 𝑦2 = 𝑥1 𝑆𝑖𝑛𝜃 + 𝑦1 ( − ) →
𝐶𝑜𝑠𝜃 𝐶𝑜𝑠𝜃

𝐶𝑜𝑠 2 𝜃
𝑦2 = 𝑥1 𝑆𝑖𝑛𝜃 + 𝑦1 ( ) →
𝐶𝑜𝑠𝜃

𝑦2 = 𝑥1 𝑆𝑖𝑛𝜃 + 𝑦1 𝐶𝑜𝑠𝜃

Bu iki denklemi matris formunda yazarsak, orijin etrafında (resmin sol üst köşesi) bir noktanın dönüşü şu şekilde
olur.
𝑥2 𝐶𝑜𝑠𝜃 𝑆𝑖𝑛𝜃 𝑥1
[𝑦 ] = [ ][ ]
2 −𝑆𝑖𝑛𝜃 𝐶𝑜𝑠𝜃 𝑦1

15
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Pozitif θ açısı saatin yönünde dönmeyi ifade etmektedir. Resim alanı içerisindeki görüntü döndürülürken
döndürme noktası sol üst köşe yerine resmin ortasını almak gerekir. Bu durumda koordinatlardan resmin orta
noktasını gösteren x0 ve y0 değerlerini çıkarmak gerekir. Yani ilk işlemde orijin resmin ortasındaymış gibi
düşünüp, dönme işlemi gerçekleştikten sonra, resmi sol üst köşeye taşırsak x0 ve y0 değerlerini çıkarırız.
Resimlerde y koordinat ekseni aşağıya doğru bakmaktadır. Buna göre kullanacağımız formülleri çıkarırsak, şu
şekilde olacaktır.
𝑥2 = 𝑥1 𝐶𝑜𝑠𝜃 − 𝑦1 𝑆𝑖𝑛𝜃
(𝑥2 − 𝑥0 ) = (𝑥1 − 𝑥0 )𝐶𝑜𝑠𝜃 − (𝑦1 − 𝑦0 ) 𝑆𝑖𝑛𝜃
𝑥2 = (𝑥1 − 𝑥0 )𝐶𝑜𝑠𝜃 − (𝑦1 − 𝑦0 ) 𝑆𝑖𝑛𝜃 + 𝑥0

𝑦2 = 𝑥1 𝑆𝑖𝑛𝜃 + 𝑦1 𝐶𝑜𝑠𝜃
(𝑦2 − 𝑦0 ) = (𝑥1 − 𝑥0 )𝑆𝑖𝑛𝜃 + (𝑦1 − 𝑦0 )𝐶𝑜𝑠𝜃
𝑦2 = (𝑥1 − 𝑥0 )𝑆𝑖𝑛𝜃 + (𝑦1 − 𝑦0 )𝐶𝑜𝑠𝜃 + 𝑦0
Bu iki denklemi matris formunda yazarsak, resmin ortasındaki (x0,y0) noktası etrafında, (x1,y1) noktasını
çevirdiğimizde (x2,y2) yeni konumuna şu formülle döndürülür.
𝑥2 𝐶𝑜𝑠𝜃 𝑆𝑖𝑛𝜃 (𝑥1 − 𝑥0 ) 𝑥0
[𝑦 ] = [ ][ ] + [𝑦 ]
2 −𝑆𝑖𝑛𝜃 𝐶𝑜𝑠𝜃 (𝑦1 − 𝑦0 ) 0

Döndürme işlemi nedeniyle resmin orjinal boyutunun dışına çıkan kısımlar yok sayılabilir yada bu kısımlar siyah
renge dönüştürülebilir.

Bu formüller kullanıldığında x2 ve y2 koordinat değerleri, formül içindeki Sin ve Cos değerlerinden dolayı ondalık
sayı olarak çıkacaktır. Bu durumda dönmüş olan piksel değeri, resim üzerindeki yatay ve dikey konumda olan
piksel ızgarasının üzerine tam oturmayacaktır. Aynı anda birkaç pikselin üzerine basacaktır. Eğer en yakın tam
sayı değerine yuvarlatılsa bile bazı noktalara renk ataması yapılamayacaktır. Bazı pikseller çift adreslenirken
bazıları kaçırılacaktır. Bu durumda resim üzerinde boşluklar gözükecektir. Bu bozucu duruma alias (aliasing)
denir.

16
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Bu sorunu çözmek için değişik yöntemler kullanılabilir. Bunlardan üç tanesi şu şekildedir. Başka yöntemlerde
geliştirilebilir.
a) Kaynak resim üzerindeki pikseller aşırı örneklenerek büyütülebilir. Yani her piksel aynı renkte olmak
üzere nxn lik küçük bir matris şeklinde (örn: 2x2) büyütülebilir. Bu haliyle resim döndürülür ve ardından
küçültülürse aradaki boşluklar kaybolacaktır.
b) İkinci yöntemde ise sorunu tersine çevirebiliriz. Hedef piksel üzerine basan 4 tane kaynak pikselin
hangisi ağırlıkça en fazla yer işgal ediyorsa onun rengi atanabilir. Ayrıca bu algoritmaya üzerine basan 4
tane pikselin alan ağırlılığı ile doğru orantılı olacak şekilde ortalama bir renk değeri atanabilir. Bu durum
daha pürüzsüz bir görüntünün oluşmasını sağlayacaktır fakat hesaplama zamanı artacaktır.

c) Üçüncü yöntem ise daha ilginç bir yöntemdir. Bu yöntemde tüm pikseller önce yatay olarak sağa doğru
kaydırılır. Daha sonra dikey olarak aşağı doğru kaydırılır. Sonra tekrar sağa doğru yatayda kaydırılırsa
resim dönmüş olarak gözükecektir.

Sağa doğru kaydırma;


𝑥2 = (𝑥1 − 𝑥0 ) − (𝑦1 − 𝑦0 ) tan (𝜃/2) + 𝑥0
𝑦2 = (𝑦1 − 𝑦0 ) + 𝑦0
Aşağı kaydırma;
𝑥2 = (𝑥1 − 𝑥0 ) + 𝑥0
𝑦2 = (𝑥1 − 𝑥0 )𝑆𝑖𝑛𝜃 + (𝑦1 − 𝑦0 ) + 𝑦0
Tekrar Sağa doğru kaydırma;
𝑥2 = (𝑥1 − 𝑥0 ) − (𝑦1 − 𝑦0 ) tan (𝜃/2) + 𝑥0

17
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

𝑦2 = (𝑦1 − 𝑦0 ) + 𝑦0
Bu işlemleri matris formatında gösterirsek topluca şu şekilde olacaktır.
𝑥2 1 −Tan (𝜃/2) 1 0 1 −Tan (𝜃/2) (𝑥1 − 𝑥0 ) 𝑥0
[𝑦 ] = [ ][ ][ ][ ] + [𝑦 ]
2 0 1 𝑆𝑖𝑛𝜃 1 0 1 (𝑦1 − 𝑦0 ) 0

Araştırma: Buradaki Kaydırma işlemi ile Döndürme İşlemi arasındaki arasındaki bağlantıların nasıl bulunduğunu
çıkarın.
Programlama (Alias düzeltme yok)
Alias düzeltilmeden sadece resmi döndürmeye ait kodlar aşağıdadır. Resim üzerinde farklı açılardaki alias
oluşumları gösterilmiştir.

public Bitmap Dondurme()


{
Color OkunanRenk;
Bitmap GirisResmi, CikisResmi;
GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width;


int ResimYuksekligi = GirisResmi.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

int Aci = Convert.ToInt16(textBox1.Text);


double RadyanAci = Aci * 2 * Math.PI / 360;

double x2 = 0, y2 = 0;

//Resim merkezini buluyor. Resim merkezi etrafında döndürecek.


int x0 = ResimGenisligi / 2;
int y0 = ResimYuksekligi / 2;

for (int x1 = 0; x1 < (ResimGenisligi); x1++)


{
for (int y1 = 0; y1 < (ResimYuksekligi); y1++)
{
OkunanRenk = GirisResmi.GetPixel(x1, y1);

//Döndürme Formülleri
x2 = Math.Cos(RadyanAci) * (x1 - x0) - Math.Sin(RadyanAci) * (y1 - y0) + x0;
y2 = Math.Sin(RadyanAci) * (x1 - x0) + Math.Cos(RadyanAci) * (y1 - y0) + y0;

18
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

if(x2>0 && x2<ResimGenisligi && y2>0 && y2<ResimYuksekligi )


CikisResmi.SetPixel((int)x2, (int)y2, OkunanRenk);
}
}
pictureBox2.Image = CikisResmi;
}

Programlama (Alias düzeltme, kaydırma yöntemi ile)


Kaydırma yöntemi alias hatası düzelse de 30 derecede hala sorun devam etmektedir. Ondalık sayıların tam
sayıya çevrilmesi bu derecede hataya neden olmaktadır.

public Bitmap Dondurme_Alias()


{
Color OkunanRenk;
Bitmap GirisResmi, CikisResmi;
GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width;


int ResimYuksekligi = GirisResmi.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

int Aci = Convert.ToInt16(textBox1.Text);


double RadyanAci = Aci * 2 * Math.PI / 360;

double x2 = 0, y2 = 0;

//Resim merkezini buluyor. Resim merkezi etrafında döndürecek.


int x0 = ResimGenisligi / 2;
int y0 = ResimYuksekligi / 2;

for (int x1 = 0; x1 < (ResimGenisligi); x1++)


{
for (int y1 = 0; y1 < (ResimYuksekligi); y1++)
{
OkunanRenk = GirisResmi.GetPixel(x1, y1);

//Aliaslı Döndürme -Sağa Kaydırma


x2 = (x1 - x0) - Math.Tan(RadyanAci / 2) * (y1 - y0) + x0;
y2 = (y1 - y0) + y0;

x2 = Convert.ToInt16(x2);
y2 = Convert.ToInt16(y2);

19
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

//Aliaslı Döndürme -Aşağı kaydırma


x2 = (x2 - x0) + x0;
y2 = Math.Sin(RadyanAci) * (x2 - x0) + (y2 - y0) + y0;

x2 = Convert.ToInt16(x2);
y2 = Convert.ToInt16(y2);

//Aliaslı Döndürme -Sağa Kaydırma


x2 = (x2 - x0) - Math.Tan(RadyanAci / 2) * (y2 - y0) + x0;
y2 = (y2 - y0) + y0;

x2 = Convert.ToInt16(x2);
y2 = Convert.ToInt16(y2);

if (x2 > 0 && x2 < ResimGenisligi && y2 > 0 && y2 < ResimYuksekligi)
CikisResmi.SetPixel((int)x2, (int)y2, OkunanRenk);
}
}
pictureBox2.Image = CikisResmi;
}
Araştırma: Yukarıda Alias düzeltme yapıldığı halde 30 derece neden hala boşlukların çıktığını araştırın.

KIRPMA
Kırpma işleminin mantığını ve algoritmasını kendiniz geliştirin. Ödev olarak istenecektir.
------------------------- 000 ------------------------------
Haftalık Ödev: Aşağıda verilen Ö1, Ö3 ve Ö4 ödevlerinin hepsinin uygulamasınıı yapınız.
------------------------- 000 ------------------------------
Ödev 1: a)Tıklayarak Resmi Taşıma: Resim üzerine bir noktaya tıklansın. Ardından ikinci noktaya tıklandığında
resmin o noktası yeni yerine gelecek şekilde resmi taşıyın. Tıklanan noktların gözle görülebilmesi için resim
üzerinde küçük bir kare çizdirin. (Picturebox üzerinde çizgi nasıl çizdirilir öğrenmek için İnt.Tab.Prg 4. Notlara
bakın)
b)Basılı Tutarak Resmi Taşıma: Bu işlemin aynısı mouse basılı iken de yapılabilir. Mouse basılı iken her hareket
ettiği nokta alınıp resim sürekli mouse takip edecek şekilde taşınabilir.
c) Formül Çıkarma: Aynalama komutlarından Resmin orta noktasına göre (x0,y0) belli bir açıda (θ) aynalarken
kullanılan aşağıdaki formüllerin çıkarılışını bulunuz. (Bilinenler x1, y1, x0, y0 dır. Bulunacak olan x2, y2) (Örnek
olarak döndürme işlemlemlerinin içindeki formül çıkarma yöntemini kullanabilirsiniz). Bu formüllerin
doğruluğunu kontrol ediniz, nasıl çalıştığını gösteriniz.
(x0,y0) noktasından geçen herhangi bir θ açısına sahip bir eksen etrafında aynalama.
∆= (𝑥1 − 𝑥0 ) 𝑆𝑖𝑛𝜃 − (𝑦1 − 𝑦0 ) 𝐶𝑜𝑠𝜃
olmak üzere
𝑥2 = 𝑥1 + 2 𝛥 (−𝑆𝑖𝑛𝜃) yeni x koordinatını verir.
𝑦2 = 𝑦1 + 2 𝛥 (𝐶𝑜𝑠𝜃) yeni y koordinatını verir.
Eğer (x0,y0) noktası resmin merkezi olmazsa, yansıyan görüntü sınırların dışına çıkacaktır.

20
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Ödev 2: Kaydırma komutuna tıklandığında resmin köşelerinden tutulup çekebilecek şekilde kaydırma
işlemi yapın. Örnek görünümü aşağıdakine benzer olsun. Burada olduğu gibi tüm köşelerden tutmak yerine üst
kenara yakın bölgede mouse basılı iken yana doğru sürükleme yaparsak, resim sağa doğru kaysın. Yan kenara
yakın bir bölgede mouse basılı iken aşağıda doğru sürüklersem resim aşağı doğru kaysın. Bu şekilde 4 kenar
üzerinde de bunu yapabilelim. Her iki yönede kayacak şekilde ayarlayabilelim.
Bir resim yana kaydırıldıktan sonra o resim tekrar aynı picturebox üzerinde gözükmeli. Yani yan tarafta değil
hepsi picturebox1 üzerinde olmalı. Böylecde tekrardan eğik resim üzerinde ikinci bir kaydırma işlemi
yapılabilmeli. Fakat bu esnada dışarı taşan piksellerin bilgisi kaybolacağından bunları kaybetmemek için tüm
resim üzerindeki piksel değerlerinin hem koordinatları hemde renk bilgileri dizide tutulabilir.

Ödev 3: Tıklanan iki noktayı eksen kabul eden çizginin etrafında aynalama yapan programı yazınız. Formüller
ders notları içerisinde vardır.

Ödev 4: Küçük bir resmi belli oranlarda büyütebilen bir program yazınız. Resim büyütme esnasında aralarda
oluşan piksel boşlukları (alias) için çözümde bulmaya çalışın.

Ödev 5: Resim üzerinde mouse ile tıklanan iki noktanın arasında oluşan dikdörtgeni Kırpma aracı olarak kullanan
programı yazın. Yani çizilen dikdörtgenin dışındaki kısımlar ikinci resimde olmayacak.

21
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com


------------------ 000--------------

Ödev 6: Bir resmi yukarıda anlatıldığı gibi yarı yarıya küçültme değil belli oranlarda küçültme yapabilecek
programı yazınız. %70, %30 gibi oranlarda da küçültme yapabilsin.

Ödev 7: Resmin ortasında tıklanan herhangi bir nokta etrafında texbox’tan girilen açı kadar çevirme yapan
kodaları yazın. Resmin ortasında tıklanan yerde küçük bir artı şeklinde işaret çizdirin. Dönme işleminden sonra
bu işaret kalkmalı.

Ödev 8: Ölçekleme komutuna tıklandığında resmin köşelerinde küçük kutucuklar oluşsun.


a) Mouse ile bu noktadan basarak sürüklenip bırakıldığında, bırakılan nokta ile köşe arasında resim
küçülmüş olsun. Bu esnada orantısı bozulmasın. Aynı işlemi büyütme içinde yapın.
b) Köşe yerine kenarların ortasındaki noktalardan çekildiğinde resim yatay / dikey uzasın (orantısı
bozulsun).

a) b)

Ödev 9: Ölçekleme işlemlerinden büyültme işlemini hem "Piksel Değiştirme" metodu ile hem de "Piksel
İnterpolasyon" metodu ile programlayın. Hangisinin daha iyi bir sonuç verdiğini görmek için print-screen ile
alarak Paintte büyütüp inceleyin. Yanyana getirip kenarları karşılaştırın.

Ödev 10: Mouse ile bir resmi döndürme işlemi yaptırın. Resmin üzerinde mouse sol tuşana basılı tutarken ve
mouse ile döndürme hareketi yaparken resmin 4 kenarını çizgi şeklinde ve mouse takip edecek şekilde Orta

22
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

nokta etrafında çizdirin. Mousdan elimizi çektiğimiz anda resim gösterilen en son dikdörgenin içerisinde dönmüş
olarak gözüksün. Bu esnada picturbox ın dışına taşan kısımlar gözükmeyecektir.

Ödev 11: Resim döndürme işlemini açı olmadan Kaydırma yöntemini kullanarak programlayın. (Köşelerden 50
piksel kaydırak dönder)(Hem saat yönünde, hemde tersi yönde çalışan komutlar geliştirin)

Ödev 12: a) Döndürme komutunu programlarken Geometrik dönüşümle programlayın. Oluşan Alias boşluklarını
yok etmek için resim oluştuktan sonra siyah noktaların etrafındaki pikselleri okutun ve renk olarak etrafındaki
piksellerin ortalamasını alacak şekilde programlayın. Bu şekilde döndürme nedeniyle oluşan hatayı yok etmeye
çalışın. Eğer Aliasları yok etmek için iyi bir algoritma bulursanız büyük harflerle anlatın.
b) Döndürme işlemini Yana ve aşağı kaydırarak programlayın. Notlarda bu konuda hazır formül verilmiştir
fakat bunlar resmin ortasına göre kaydırma yapıyor. Siz bunu kullanmayacaksınız. Resmin köşesinden
eğerek döndürme yapacak. Bu konu notlar içinde anlatılmıştı. Burada yana ve aşağı kaydırırken oluşan
açı yı geliştireceğiniz formüller içinde kullanının. Yani açı verildiği zaman köşeden itibaren eğerek tam o
açı kadar dönmeyi sağlayacak yöntemi yada formülü bulun. Resmin dışına çıkan kısımların
kaybolmamasına dikkat edin. O problemi de çözün. Geliştirdiğiniz önemli uygulamaları büyük harflerle
anlatın.

a)

b)

Ödev 13: Kırpma işlemini yapan kodları yazınız. Mouse takip eden çizgi çizdirerek yapın...

23
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Ödev 14:
Aşağıdaki gibi bir resmin 4 kenarından tutup sağa-sola yada yukarı aşağı mouse ile sürükleme yaptığımızda, o
kenar üzerinde ilgili kaydırma işlemini yaptırın. Bu uygulamada mouse ile aynı anda kaydırma işlemi oluşsun...

Ödev 15:
Aşağıdaki resimde gösterildiği şekilde bir resim büyültme algoritması geliştirin. Bu işlemde resim iki bütülürken
her pikseli 4 lü gözlerin bir köşesine ekleyin. Aralardaki boşlukları sağa doğru tararken iki pikselin ortalamasını
alarak, aşağı doğru tararken yine iki pikselin ortalamasını alarak algoritmayı geliştirin.

Ödev 16 (Mouse un bulunduğu nokta etrafında tekerle zoom yapma): Aşağıdaki resimde gösterildiği gibi Mouse
resmin herhangi bir noktasında iken Mouse tekerini çevirdiğimizde bulunduğu noktanın etrafında zoom in/out
(yaklaştırma /uzaklaştırma) işlemlerini yapan algoritmayı geliştirin.

24
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Ödev 17 (Mouse bulunduğu nokta etrafında, tekerle döndürme): Aşağıdaki resimde gösterildiği gibi Mouse
resmin üzerinde herhangi bir noktada tutalım. Döndürme komutunu aktif ettikten sonra bu işlemleri yapmalıyız.
Odaklanılan nokta üzerinde iken Mouse tekeri geriye yada ileri dönderildiğinde resimde bulunan noktanın
etrafında dönsün. Oluşan Alias (resim piksel boşlukları) olayı da bu esnada bulunabilir.

Ödev 18 (Alias Yok Etme): Resim pikselleri üzerinde hesaplama yaptığımızda double olan küsüratlı değerler
resmin üzerine yerleştirilirken integer a çevrilmek zorundadır. Bu nedenle küsüratlar kaybolunca bazı piksellerin
üzerine renk atanmamaktadır. Bu durum Alias dediğimiz boşlukların oluşmasına neden olmaktadır. Aşağıda
resimde verildiği şekilde bir resmi değişik açılarda döndürdüğümüzde alias oluşan boşlukları kapatan bir
algoritma geliştirin. Bunun için fikir olarak şu söylenebilir. Resmi öncelikle diziye atın. Döndürme işlemlerini dizi
üzerinden yapın. Yeni resmin çerçevesini de dizide tutun. Bu ikinci dizide her renk atanan koordinata bir eğer bir
atama yapıldıysa bunu bir bilgide tutun. En tarama işlemi bittiğinde bu ikinci dizi bize hangi piksellerde renk
atanmadığı bilgisini verecektir. Sonrada ikinci resmi bir daha taradığımızda renk atanmayan piksellerindeki
etrafındaki 9 piksele bakıp bunların ortalama rengi, bu atanmayan piksele verilebilir. Bu şekilde algoritmayı
geliştirin.

25
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

26
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

GÖRÜNTÜ İŞLEME - (4.Hafta)


PERSPEKTİF DÜZELTME
Perspektif nesnenin bulunduğu konuma bağlı olarak, gözlemcinin gözünde bıraktığı etkiyi (görüntüyü) iki
boyutlu bir düzlemde canlandırmak için geliştirilmiş bir iz düşüm tekniğidir. Perspektif düzeltmede amaç kişinin
veya nesnenin konum değiştirmesi sonucu oluşacak etkiyi düzeltmektir. Bu işlem sayesinde görüntü oluştuktan
sonra dahi belirli kısıtlar içerisinde resme baktığımız açıyı değiştirebiliriz. Örneğin, perspektif olarak çekilmiş bir
resmi, tam karşıdan çekilmiş gibi düzeltme yapabiliriz, yada çekilen kamera açısını farklı bir noktaymış gibi
ayarlayabiliriz. Algoritma karakter tanıma uygulamalarında çekilmiş bir görüntüyü belirli kalıplar içerisine
oturmada, plaka tanıma, yüz tanıma gibi uygulamalarda normalizasyon sırasında sıklıkla kullanılmaktadır.
Konuya geçmeden önce dönüşüm matrislerinde işlemi kolaylaştıran "Homojen koordinatlar" konusunu bir
inceleyelim.
Homojen Koordinatlar
Homojen koordinat sistemine göre, cisimler üzerinde uygulanan geometrik dönüşümlerin arka arkaya
yapılabilmesini matematiksel anlamda çok esnek hale getirmektedir. Cisimlerin koordinatları matris formunda
yazılarak çarpım notasyonuna tabi tutulur ve cismin yeni şekli veya konumu kolaylıkla elde edilmiş olur.
Kartezyen koordinat sisteminde bulunan bir cismin koordinatları A(x1,y1) şeklindedir. Bu koordinatlara üçüncü
bir bileşen eklenirse boyut artımına sebep olur ki, oluşan yeni sistem homojen koordinat sistemi adını alır.

Homojen koordinat sistemi yukarıda da bahsedildiği gibi,iki boyutlu kartezyen koordinat sistemine üçüncü bir
boyut (z) eklenmesiyle oluşturulur. A(x1,y1) koordinatları artık A(x1,y1,h) üçlüsüne dönüşür. Dönüşüm için
homojen koordinatlar bir h değeri ile çarpılır yada bölünür. Bu sayede iki koordinat sistemi arasında bir ilişki
oluşur.
Araştırma: Homejen koordinatlara neden ihtiyaç duyuyoruz. Bu koordat sistemi olmadan matris tersini alamaz
mıyız. Araştırın?
Bu ilişkide kullanılan üçüncü koordinat bileşeni olan z, genel olarak h ile ifade edilir ve 1 alınır. Çünkü iki
boyutlu eksendeki bir noktanın, homojen koordinat ekseninde sonsuz gösterimi olacaktır. Örneğin kartezyen
koordinat sisteminde (x=2,y=3) koordinatlarına sahip bir cismin, Homojen koordinattaki gösterimi aşağıdaki gibi
sonsuz sayıda olabilir.
Kartezyen gösterim = Homojen gösterim
A(x1,y1)= A(x1,y1,h)
A(2,3)= A(2,3,1) (h=1)
A(2,3)= A(4,6,2) (h=2)
A(2,3)= A(6,9,3) (h=3)
... = ......
A(2,3)= A(2n,3n,n) (h=n)

1
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Bu noktaların hepsi kartezyen koordinatta aynı noktayı gösterir ve hepsi birbirine eşit demektir. Bu nedenle bir
çok işlemi kolaylaştırması için homojen koordinatta h=1 alınır. Böylece matematiksel dönüşümler kolaylaşmış
olacaktır. Dikkat edersek yukarıda tek tablo şeklinde verilen dönüşüm formüllerindeki matris gösterimleri
homojen koordinatlarda verilmiştir. Örnek olarak birini yazacak olursak (döndürme matrisini seçelim) aşağıdaki
şekilde olur.
Döndürme matrisinin normal gösterimi Döndürme matrisinin homojen koordinatlar
kullanılarak gösterimi
𝑥2 𝐶𝑜𝑠𝜃 𝑆𝑖𝑛𝜃 𝑥1 𝑥2 𝐶𝑜𝑠𝜃 𝑆𝑖𝑛𝜃 0 𝑥1
[𝑦 ] = [ ][ ]
2 −𝑆𝑖𝑛𝜃 𝐶𝑜𝑠𝜃 𝑦1 [𝑦2 ] = [−𝑆𝑖𝑛𝜃 𝐶𝑜𝑠𝜃 0] [𝑦1 ]
𝑧 0 0 1 1
Sonuç olarak homojen koordinat sistemi bize afin dönüşümlerinin tamamının çarpımsal matris formunda
uygulanabilme kolaylığı sağlayacak. Geometrik hesaplamalarda esnek bir hesaplama imkanı sağlayacaktır. Bu
avantajı gelecek örneklerde daha iyi anlayacağız.
-------------------000----------------
Şimdi gelelim pespektif dönüşüm için kullanılan parametrelerin nasıl bulunabileceğine. Perspektif dönüşümünün
bir matris çarpması ile yapıldığını biliyoruz. Dönüşüm için kullandığımız matrisi homojen koordinatları da dahil
ederek aşağıdaki gibi oluşturabiliriz. Homojen koordinatlarda yazarken h=1 aldığımız için denklemler aşağıdaki
gibi oluşturulur. Burada (x1,y1) giriş resmindeki pikselin koordinatlarını, (X1,Y1) ise çıkış resmindeki
koordinatları temsil etmektedir (Dikkat: önceki notlarda çıkış resminin koordinatlarını x2,y2 şeklinde
kullanıyorduk. Fakat aşağıda 4 tane noktaya ihtiyaç olacak. Dolayıs noktaları 1,2,3,4 indisleri ile
kullanacağımızdan burada çıkış resimlerinin koordinatları büyük harflerle gösterilmiştir.) Her iki resimdeki bu
noktaların koordinat değerleri bilinmektedir. Bilinmeyen [A] matrisinin elemanlarıdır.
𝑿𝟏 𝑧 𝑎11 𝑎12 𝑎13 𝑥1
[𝒀𝟏 𝑧 ] = [𝑎21 𝑎22 𝑎23 ] [𝑦1 ]
𝑧 𝑎31 𝑎32 1 1
Burada amacımız A matrisinin (axx-elemanları ile gösterilen matris) elemanlarını bulmaktır. İlk olarak matris
değerlerini açık denklemler şeklinde yazalım.
𝑿𝟏 z = 𝑎11 𝑥1 + 𝑎12 𝑦1 + 𝑎13
𝒀𝟏 z = 𝑎21 𝑥1 + 𝑎22 𝑦1 + 𝑎23
z = 𝑎31 𝑥1 + 𝑎32 𝑦1 + 1
Buradaki z denklemini önceki iki denklemde yerine yazarsak ve X1,Y1 çekersek denklemler aşağıdaki gibi olur.
𝑎11 𝑥1 + 𝑎12 𝑦1 + 𝑎13
𝑿𝟏 =
𝑎31 𝑥1 + 𝑎32 𝑦1 + 1
𝑎21 𝑥1 + 𝑎22 𝑦1 + 𝑎23
𝒀𝟏 =
𝑎31 𝑥1 + 𝑎32 𝑦1 + 1
Bu denklemlere içler dışlar çarpımı uygularsak;
𝑎31 𝑥1 𝑿𝟏 + 𝑎32 𝑦1 𝑿𝟏 + 𝑿𝟏 = 𝑎11 𝑥1 + 𝑎12 𝑦1 + 𝑎13
𝑎31 𝑥1 𝒀𝟏 + 𝑎32 𝑦1 𝒀𝟏 + 𝒀𝟏 = 𝑎21 𝑥1 + 𝑎22 𝑦1 + 𝑎23
Yalnız kalan X1 veY1 terimlerini çekersek;
𝑿𝟏 = 𝑎11 𝑥1 + 𝑎12 𝑦1 + 𝑎13 − 𝑎31 𝑥1 𝑿𝟏 − 𝑎32 𝑦1 𝑿𝟏
𝒀𝟏 = 𝑎21 𝑥1 + 𝑎22 𝑦1 + 𝑎23 − 𝑎31 𝑥1 𝒀𝟏 − 𝑎32 𝑦1 𝒀𝟏
Bu iki denklemi matris formunda yazacak olursak [C]=[B][A] şeklinde bir format ortaya çıkar. Burada [A] bir
vektördür (Tek boyutlu matris).

2
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

𝑎11
𝑎12
𝑎13
𝑿𝟏 𝑥 𝑦 1 0 0 0 −𝑥1 𝑿𝟏 −𝑦1 𝑿𝟏 𝑎21
[ ]=[ 1 1 ]
𝒀𝟏 0 0 0 𝑥1 𝑦1 1 −𝑥1 𝒀𝟏 −𝑦1 𝒀𝟏 𝑎22
𝑎23
𝑎31
[𝑎32 ]
ifadesi elde edilir. Burada aranılan [A] matrisi [A]=[B−1][C] işlemi ile kolaylıkla bulunabilir. Burada dikkat
edilmesi gereken bir nokta elimizde sekiz bilinmeyenli bir [A] matrisi olmasına rağmen görünürde sadece iki
denklemimiz olmasıdır. Sekiz bilinmeyenli bir denklemin çözümü için bağımsız sekiz tane denklem
gerekmektedir. Bu amaçla tek bir nokta yerine 4 tane (x,y) noktası kullanılarak [A] matrisinin elemanları
bulunacak. Bulduğumuz axx değerleri iki resim arasındaki dönüşümü yapacak olan 3x3 lük dönüşüm matrisini
oluşturacaktır. Bilinen 4 nokta için matris denklemimizi tekrar yazarsak aşağıdaki şekilde olur.

𝑿𝟏 𝑥1 𝑦1 1 0 0 0 −𝑥1 𝑿𝟏 −𝑦1 𝑿𝟏 𝑎
11
𝒀𝟏 0 0 0 𝑥1 𝑦1 1 −𝑥1 𝒀𝟏 −𝑦1 𝒀𝟏 𝑎
12
𝑿𝟐 𝑥2 𝑦2 1 0 0 0 −𝑥2 𝑿𝟐 −𝑦2 𝑿𝟐 𝑎13
𝒀𝟐 0 0 0 𝑥2 𝑦2 1 −𝑥2 𝒀𝟐 −𝑦2 𝒀𝟐 𝑎21
=
𝑿𝟑 𝑥3 𝑦3 1 0 0 0 −𝑥3 𝑿𝟑 −𝑦3 𝑿𝟑 𝑎22
𝒀𝟑 0 0 0 𝑥3 𝑦3 1 −𝑥3 𝒀𝟑 −𝑦3 𝒀𝟑 𝑎23
𝑿𝟒 𝑥4 𝑦4 1 0 0 0 −𝑥4 𝑿𝟒 −𝑦4 𝑿𝟒 𝑎31
[𝑎 ]
[ 𝒀𝟒 ] [ 0 0 0 𝑥4 𝑦4 1 −𝑥4 𝒀𝟒 −𝑦4 𝒀𝟒 ] 32
Bu matris denkleminde, en sağdaki [A] matrisinin elemanları hariç diğer tüm elemanları biliyoruz. [A] matrisini
yanlız bırakabilmek için ortadaki 8x8 lik [B] matrisinin tersini alıp, karşı taraftaki 8x1 lik [C] matrisi ile
çarpmalıyız. Yani [A]=[B−1][C] şeklinde bir işlem yapacağız. Bu işlem için matris tersini almayı öğrenmemiz
gerekiyor. Şimdi bu konuya bakalım daha sonra kaldığımız yerden devam ederiz.

Matris Tersini Alma


Matrisler sabit değerli sayıların bir düzen içerisinde tablo şeklinde yazılması ile oluşturulur. Bu konuda
geliştirilen matematik görüntü işleme, istatistik gibi pek çok alandaki problemlerin bilgisayar programı ile
çözümünü kolaylaştırır. Bu amaçla matrislerle ilgili Determinant hesaplama, Tersini alma gibi konuları bilmek
önem arz eder.
Matris tersini alma işlemi ile ilgili olarak Algoritmik işlemler için uygun olan Gauss Jordan yöntemini
kullanalım. Bu yöntemde amaç bir matrisin tersini almak için, tersi olan matris ile çarpımını, birim matrise
dönüştürmektir. Yani bir matrisin kendisi [A] ise tersi [A-1] olur, buna da [B] matrisi diyelim. Bu durumda [A]
matrisi ile tersi olan [B] matrisinin çarpımı birim matrisi [I] vermelidir. Birim matris köşegeni 1 olan diğer
elemanları 0 olan kare matristir.
[A] x [A-1]=[I]
Bu ifade A matrisinin tersini B matrisi ile gösterirsek, yani [A-1] =[B] dersek;
[A] x [B] = [I]
olur.
Matris tersini alma ile ilgili bir çok yöntem olmasına rağmen bizi programlama kolaylığı için Gauss Jordan
yöntemini öğrenelim ve buna göre programını yazalım.
Gauss Jordan Yöntemi ile Matris Tersini Alma:
Gauss-Jordan yöntemi, özellikle büyük denklem takımlarını çözmede kolaylık sağlamaktadır. Bir diğer avantajı
programlamaya uygun bir yöntemdir. Pratik bir şekilde en büyük matrislerin çözümünü sağlayan bir yöntemdir.
Benzeri olan Gauss Eliminasyon (yok etme) metoduna benzer.
3
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Bir örnek üzerinde bu yöntemi inceleyelim. Aşağıdaki denklem takımını çözmeye çalışalım.
11 = 𝑥 + 2𝑦 + 2𝑧
4 = 3𝑥 + 2𝑦 − 𝑧
3 = 2𝑥 − 𝑦 + 𝑧
Bu denklem takımını matris formatında yazarsak aşağıdaki şekilde olur.
11 1 2 2 𝑥
[ 4 ] = [3 2 −1] [𝑦]
3 2 −1 1 𝑧
Bu matris takımını [C]=[A][X] matris formatında gösterirsek, buradaki [X] matrisindeki değerleri bilmiyoruz ve
bunu bulmak için [A] matrisinin tersini alıp [C] matrisi ile çarpmalıyız. Yani [X]=[A -1][C] şeklinde olmalıdır.
Buna göre [A] katsayılar matrisinin tersini nasıl alırız. Bunun için Gauss Jordan yöntemini kullanacağız.
Gauss Jordan yönteminde [A] katsayı matrisini birim matrise dönüştürmeye çalışacağız ve bu durumda [C]
matrisi de ilgili sayılarla çarpılarak belli bir değer alacak. [A] matrisi birim matris olunca yeni değerlere sahip
olan [C] matrisi x,y,z değerlerini gösteren sonuç matrisi olacaktır, yani denklem takımının çözümü olacaktır.
11 1 2 2 𝑥 ∗ 1 0 0 𝑥
[ 4 ] = [3 2 −1] [𝑦] ==> [∗] = [0 1 0] [𝑦]
3 2 −1 1 𝑧 ∗ 0 0 1 𝑧
Buradaki işlemleri matrsi formunda kısaltmalı olarak gösterirsek,
[C] =[A] [X] [A] [A-1] = [I]
[C] =([I]/ [A-1]) [X] [A]= [I]/ [A-1]
[C] [A-1] = [I] [X]

Şimdi [C][A] matrislerine çeşitli satır işlemleri uygulayarak bu dönüşümü yapalım. Burada uygulanabilecek satır
işlemleri aşağıdaki işlemlerden herhangi biri olabilir.
• Bir satırın bir sabit ile çarpılması
• Bir satırın diğer bir satır ile yer değiştirmesi
• Bir satırın diğer bir satırdan çıkarılması
Daha basit gösterim için aşağıdaki formatı kullanalım. Burada [C] matrisi ile [A] matrisi sadece yanyana
getirilmiş. Herhangi bir matematiksel anlamı yok. İşlemler yapılırken her iki matrisi de uygulanacak. Böylece sağ
taraftaki [A] matrisi birim matrise dönüşürken sol taraftaki [C] matriside başka bir değerler alacaktır. Böyle [A]
matrisinin birim matris olması sonucu ortaya çıkan [C] matrisi aslında çözüm olarak aradığımız [C] [A-1] ifadesi
olmuş oluyor.
11 1 2 2
[ 4 ] [3 2 −1]
3 2 −1 1
Önce köşegenin altındaki terimleri 0 yapalım. Köşegen üzerindeki değerleri de 1 yapalım. Burada hangi satırda
işlem yaparsak o satırın kaçıncı elemanı 0 yada 1 yapmaya çalışıyoruz ona bakıyoruz. Eğer 3 eleman bulunan
satırın ilk elemanı değiştirmeye çalışıyorsak en yukarıdaki 1 satırda işlemleri yapmalıyız. Son 3. Elemanı
değiştirmeye çalışıyorsak en son 3. Satırı kullanmalıyız. Çıkan değerleri kendi bulunduğu satır ile topluyoruz.
a) (a21=3) değerini 0 yapmak için birinci satırı -3 ile çarpıp (ilk terim olduğu için birinci satır ile çarpıyoruz) 2.
satır ile toplayalım. Yani [-3*11][-3*1 , -3*2, -3*2] = [-33][-3, -6, -6] olur. Bu değerleri 2. satır ile toplarsak
[33+4][-3+3, -6+2, -6-1]=[-29][0,-4,-7]. Bu sonucu matristeki yerlerinde gösterirsek; (Not: burada R gösterimi
Row (satır manasında). İşlem yapılan satırları ifade ediyor. )

4
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

11 1 2 2 𝑅2 =−3𝑅1 +𝑅2 11 1 2 2
[ 4 ] [𝟑 2 −1] → [−29] [𝟎 −4 −7]
3 2 −1 1 3 2 −1 1
b) (a22=-4) değerini 1 yapmak için ikinci satırı -4 bölmemiz yeterli olacaktır. Yani [-29/-4][0/-4 , -4/-4, -7/-4] =
[29/4][0 , 1, 7/4] olur. Bu sonucu matristeki yerlerinde gösterirsek;
11 1 2 2 𝑅2 =𝑅2 /−4 11 1 2 2
[−29] [0 −𝟒 −7] → [29/4] [0 𝟏 7/4]
3 2 −1 1 3 2 −1 1
c) (a31=2) değerini 0 yapmak için; o satırdaki ilk eleman olduğu için birinci satırı kullanmalıyız. Birinci satırı -2
ile çarparsak ve çıkan sonuçları da 3. satır ile toplarsak bu ilk terimi sıfır yapmış oluruz. Yani [-2*11][-2*1 , -2*2,
-2*2] = [-22][-2, -4, -4] olur. Bu değerleri 3. satır ile toplarsak [-22+3][-2+2, -4-1, -4+1]=[-19][0,-5,-3]. Bu
sonucu matristeki yerlerinde gösterirsek;
11 1 2 2 𝑅3 =−2𝑅1 +𝑅3 11 1 2 2
[29/4] [0 1 7/4] → [29/4] [0 1 7/4]
3 𝟐 −1 1 −19 𝟎 −5 −3
d) (a32=-5) değerini 0 yapmak için; için ikinci satırı kullanmalıyız. İkinci satırı +5 ile çarparsak ve çıkan sonuçları
da kendisi ile toplarsak bu ikinci terimi sıfır yapmış oluruz. Yani [5*29/4][5*0 , 5*1, 5*7/4] = [145/4][0, 5, 35/4]
olur. Bu değerleri 3. satır ile toplarsak [(145/4) -19][0+0, 5-5, (35/4)-3] =[69/4][0,0,23/4]. Bu sonucu matristeki
yerlerinde gösterirsek;
11 1 2 2 𝑅 =+5𝑅 +𝑅 11 1 2 2
3 2 3
[29/4] [0 1 7/4] → [29/4] [0 1 7/4 ]
−19 0 −𝟓 −3 69/4 0 𝟎 23/4
e) (a33=23/5) değerini 1 yapmak için; üçüncü satırı ya 23/4 bölmeliyiz yada 4/23 ile çarpmalıyız.
11 1 2 2 𝑅 =𝑅 ∗4/23 11 1 2 2
3 3
[29/4] [0 1 7/4 ] → [29/4] [0 1 7/4]
69/4 0 0 𝟐𝟑/𝟒 3 0 0 𝟏
Buraya kadar yapılan işlemler Gauss Eliminasyon yöntemi olarak geçmektedir. Köşegenin üst kısmındaki
değerleri de 0 yaparsak Gauss Jordan yöntemi olmuş oluyor. Benzer şekilde kaldığımız yerden devam ederek
köşegenin üst kısmını da 0 yapalım.
f) (a12=2) değerini 0 yapmak için; ikinci satırı -2 ile çarpıp birinci satır ile toplamalıyız. Yani [-2*29/4][-2*0 , -
2*1, -2*7/4] = [-29/2][0, -2, -7/2] olur. Bu değerleri 1. satır ile toplarsak [-29/2+11][0+1, -2+2, -7/2+2]=[-
7/2][1,0,-3/2]. Bu sonucu matristeki yerlerinde gösterirsek;
11 1 𝟐 2 𝑅 =−2∗𝑅 +𝑅 −7/2 1 𝟎 −3/2
1 2 1
[29/4] [0 1 7/4] → [ 29/4 ] [0 1 7/4 ]
3 0 0 1 3 0 0 1
f) (a13=-3/2) değerini 0 yapmak için; üçüncü satırı 3/2 ile çarpıp birinci satır ile toplamalıyız. Yani [3/2*3][3/2*0 ,
3/2*0, 3/2*1] = [9/2][0, 0, 3/2] olur. Bu değerleri 1. satır ile toplarsak [9/2-7/2][0+1, 0+0, 3/2-3/2]=[1][1,0,0]. Bu
sonucu matristeki yerlerinde gösterirsek;
−7/2 1 0 −𝟑/𝟐 𝑅 =3/2∗𝑅 +𝑅 1 1 0 𝟎
1 3 1
[ 29/4 ] [0 1 7/4 ] → [29/4] [0 1 7/4]
3 0 0 1 3 0 0 1
g) (a23=7/4) değerini 0 yapmak için; üçüncü satırı -7/4 ile çarpıp ikinci satır ile toplamalıyız. Yani [-7/4*3][-7/4*0
, -7/4*0, -7/4*1] = [-21/4][0, 0, -7/4] olur. Bu değerleri 2. satır ile toplarsak [-21/4+29/4][0+0, 0+1, -
7/4+7/4]=[2][0,1,0]. Bu sonucu matristeki yerlerinde gösterirsek;
1 1 0 0 𝑅 =−7/4∗𝑅 +𝑅 1 1 0 0
1 3 2
[29/4] [0 1 𝟕/𝟒] → [2] [0 1 𝟎]
3 0 0 1 3 0 0 1
Böylece katsayılar matrisini birim matrise dönüştürmüş olduk. Sonuç itibariyle denklem takımımız şöyle olur.
5
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

1 1 0 0 𝑥
[2] = [0 1 0] [𝑦]
3 0 0 1 𝑧
Bu matris formatını açarsak x=1, y=2, z=3 olarak bulmuş oluruz.

Programlama (Matris Tersini alma)(Gauss Jordan yöntemi)


Matrisin tersinin alınması için geliştirilen programın kodları aşağıdadır. Bu kodları kullanımı dökümanın
sonundaki diğer kodlarla birlikte bağlantısıda verilmiştir.

C# Kodları

// MATRİS TERSİNİ ALMA---------------------


public double[,] MatrisTersiniAl (double[,] GirisMatrisi)
{
int MatrisBoyutu =Convert.ToInt16(Math.Sqrt(GirisMatrisi.Length)); //matris boyutu içindeki
eleman sayısı olduğu için kare matrisde karekökü matris boyutu olur.
double[,] CikisMatrisi = new double[MatrisBoyutu, MatrisBoyutu]; //A nın tersi alındığında bu
matris içinde tutulacak.

//--I Birim matrisin içeriğini dolduruyor


for (int i = 0; i < MatrisBoyutu; i++)
{
for (int j = 0; j < MatrisBoyutu; j++)
{
if (i == j)
CikisMatrisi[i, j] = 1;
else
CikisMatrisi[i, j] = 0;
}
}

//--Matris Tersini alma işlemi---------


double d, k;

for (int i = 0; i < MatrisBoyutu; i++)


{
d = GirisMatrisi[i, i];
6
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

for (int j = 0; j < MatrisBoyutu; j++)


{
if (d == 0)
{
d= 0.0001; //0 bölme hata veriyordu.
}
GirisMatrisi[i, j] = GirisMatrisi[i, j] / d;
CikisMatrisi[i, j] = CikisMatrisi[i, j] / d;
}
for (int x = 0; x < MatrisBoyutu; x++)
{
if (x != i)
{
k = GirisMatrisi[x, i];
for (int j = 0; j < MatrisBoyutu; j++)
{
GirisMatrisi[x, j] = GirisMatrisi[x, j] - GirisMatrisi[i, j] * k;
CikisMatrisi[x, j] = CikisMatrisi[x, j] - CikisMatrisi[i, j] * k;
}
}
}
}

return CikisMatrisi;
}

-------------------000-------------------

Kaldığımız yerden devam edersek, matris tersini almayı öğrendik. Şimdi aşağıdaki 4 nokta üzerinde perspektif
düzeltme yapacak matris denklemindeki axx katsayılarını bulalım. Bunun için bir örnek resim kullanalım ve
üzerindeki anahtar noktaların koordinatlarını paint programında okuyup dönüşüm matrisini bulalım.

Bu resimdeki 1,2,3,4 nolu noktaları sırayla a,b,c,d noktalarının olduğu köşelere doğru gerdirilecektir. Böylece
plakanın yazım alanı resmin tamamını kaplayacaktır. Fakat plakanın en boyu orantısı bozulacağı için a,b,c,d
noktalarının olduğu koordinatlar resmin içerisine sığdırmak yerine, istediğimiz herhangi bir dikdörtgenin köşeleri
olarak da atayabiliriz. Önce birinci uygulamayı bir yapalım. Bu 8 noktanın koordinatlarını paint gibi basit bir
programa atıp mouse ile üzerinde gezdirirsek koordinatları okuyabiliriz. Tabi burada resmin üzerine sonradan
eklenen çizgiler işlemlerde olmayacaktır. Yukarıdaki resmin üzerindeki noktaların koordinatları aşağıda gibi
okunmuştur. x2=806 değeri çerçevenin dışında bir nokta olarak belirlenmiştir.
1.nokta, x1= 47, y1=155 a noktası, X1 = 0, Y1=0
2.nokta, x2=806, y2=101 b noktası, X2 = 800, Y2=0

7
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

3.nokta, x3 = 46, y3=291 c noktası, X3 = 0, Y3=600


4.nokta, x4 = 726, y4=417 d noktası, X4 = 800, Y4=600

Bu değerleri aşağıdaki dönüşüm matrisimizde yerine yazalım.


𝑿𝟏 𝑥1 𝑦1 1 0 0 0 −𝑥1 𝑿𝟏 −𝑦1 𝑿𝟏 𝑎
11
𝒀𝟏 0 0 0 𝑥1 𝑦1 1 −𝑥1 𝒀𝟏 −𝑦1 𝒀𝟏 𝑎
12
𝑿𝟐 𝑥2 𝑦2 1 0 0 0 −𝑥2 𝑿𝟐 −𝑦2 𝑿𝟐 𝑎13
𝒀𝟐 0 0 0 𝑥2 𝑦2 1 −𝑥2 𝒀𝟐 −𝑦2 𝒀𝟐 𝑎21
=
𝑿𝟑 𝑥3 𝑦3 1 0 0 0 −𝑥3 𝑿𝟑 −𝑦3 𝑿𝟑 𝑎22
𝒀𝟑 0 0 0 𝑥3 𝑦3 1 −𝑥3 𝒀𝟑 −𝑦3 𝒀𝟑 𝑎23
𝑿𝟒 𝑥4 𝑦4 1 0 0 0 −𝑥4 𝑿𝟒 −𝑦4 𝑿𝟒 𝑎31
[𝑎 ]
[ 𝒀𝟒 ] [ 0 0 0 𝑥4 𝑦4 1 −𝑥4 𝒀𝟒 −𝑦4 𝒀𝟒 ] 32
8 noktanın koordinatı yerlerine yazıldığında denklem aşağıdaki gibi olur.
𝟎 47 155 1 0 0 0 −47 ∗ 𝟎 −155 ∗ 𝟎 𝑎11
𝟎 0 0 0 47 155 1 −47 ∗ 𝟎 −155 ∗ 𝟎 𝑎12
𝟖𝟎𝟎 806 101 1 0 0 0 −806 ∗ 𝟖𝟎𝟎 −101 ∗ 𝟖𝟎𝟎 𝑎13
𝟎 = 0 0 0 806 101 1 −806 ∗ 𝟎 −101 ∗ 𝟎 𝑎21
𝟎 46 291 1 0 0 0 −46 ∗ 𝟎 −291 ∗ 𝟎 𝑎22
𝟔𝟎𝟎 0 0 0 46 291 1 −46 ∗ 𝟔𝟎𝟎 −291 ∗ 𝟔𝟎𝟎 𝑎23
𝟖𝟎𝟎 726 417 1 0 0 0 −726 ∗ 𝟖𝟎𝟎 −417 ∗ 𝟖𝟎𝟎 𝑎31
[𝟔𝟎𝟎] [ 0 0 0 726 417 1 −726 ∗ 𝟔𝟎𝟎 −417 ∗ 𝟔𝟎𝟎 ] [𝑎32 ]
Bu matris denklemini , [C] = [B] [A] şeklinde gösterirsek B matrisinin tersini [B-1] yukarıdaki program ile
bulabiliriz. Bu durumda aşağıdaki sonucu buluruz.

-0,005547 -0,004954 0,002844 0,002039 0,004403 0,005187 -0,001699 -0,002272

-0,007394 -3,6E-05 2,1E-05 1,5E-05 0,007385 3,8E-05 -1,2E-05 -1,7E-05

2,406739 0,23849 -0,136889 -0,098176 -1,351657 -0,24969 0,081807 0,109375

-0,000809 -0,001922 0,000333 0,001351 0,000847 0,000607 -0,000371 -3,7E-05


[B-1]=
-0,011368 -0,008493 0,00468 0,000473 0,011902 0,008536 -0,005214 -0,000517

1,800114 2,406739 -0,741026 -0,136889 -1,884646 -1,351657 0,825558 0,081807

-3E-06 -6E-06 1E-06 2E-06 3E-06 6E-06 -2E-06 -3E-06

-8E-06 0 3E-06 0 9E-06 0 -4E-06 0

[A] = [B-1] [C]

𝑎11 𝑏11 𝑏12 𝑏13 𝑏14 𝑏15 𝑏16 𝑏17 𝑏18 𝑿𝟏


𝑎12 𝑏21 𝑏22 𝑏23 𝑏24 𝑏25 𝑏26 𝑏27 𝑏28 𝒀𝟏
𝑎13 𝑏31 𝑏32 𝑏33 𝑏34 𝑏35 𝑏36 𝑏37 𝑏38 𝑿𝟐
𝑎21 𝑏41 𝑏42 𝑏43 𝑏44 𝑏45 𝑏46 𝑏47 𝑏48 𝒀𝟐
𝑎22 = 𝑏51 𝑏52 𝑏53 𝑏54 𝑏55 𝑏56 𝑏57 𝑏58 𝑿𝟑
𝑎23 𝑏61 𝑏62 𝑏63 𝑏64 𝑏65 𝑏66 𝑏67 𝑏68 𝒀𝟑
𝑎31 𝑏71 𝑏72 𝑏73 𝑏74 𝑏75 𝑏76 𝑏77 𝑏78 𝑿𝟒
[𝑎32 ]
[𝑏81 𝑏82 𝑏83 𝑏84 𝑏85 𝑏86 𝑏87 𝑏88 ] [ 𝒀𝟒 ]
Matris formatını denklem şekline dönüştürürsek.

8
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

𝑎11 = 𝑏11 𝑿𝟏 + 𝑏12 𝒀𝟏 + 𝑏13 𝑿𝟐 + 𝑏14 𝒀𝟐 + 𝑏15 𝑿𝟑 + 𝑏16 𝒀𝟑 + 𝑏17 𝑿𝟒 + 𝑏18 𝒀𝟒


𝑎12 = 𝑏21 𝑿𝟏 + 𝑏22 𝒀𝟏 + 𝑏23 𝑿𝟐 + 𝑏24 𝒀𝟐 + 𝑏25 𝑿𝟑 + 𝑏26 𝒀𝟑 + 𝑏27 𝑿𝟒 + 𝑏28 𝒀𝟒
(...şeklinde devam eder...)

𝑎21 = 𝑏41 𝑿𝟏 + 𝑏42 𝒀𝟏 + 𝑏43 𝑿𝟐 + 𝑏44 𝒀𝟐 + 𝑏45 𝑿𝟑 + 𝑏46 𝒀𝟑 + 𝑏47 𝑿𝟒 + 𝑏48 𝒀𝟒


𝑎22 = 𝑏51 𝑿𝟏 + 𝑏52 𝒀𝟏 + 𝑏53 𝑿𝟐 + 𝑏54 𝒀𝟐 + 𝑏55 𝑿𝟑 + 𝑏56 𝒀𝟑 + 𝑏57 𝑿𝟒 + 𝑏58 𝒀𝟒
(...şeklinde devam eder...)

--------------------- 0000------------------------------

bxx matrisin tersinin katsayılarını bulduğumuza göre ve Xx,Yx koordinatlarını da biliyoruz buradan axx değerlerini
buluruz. Bu değerler aynı zamanda dönüşüm denklemindeki [A] matrisinin elemanlarıdır. Yani aşağıdaki
denklemdeki katsayılar matrisidir.

𝑿𝟏 𝑧 𝑎11 𝑎12 𝑎13 𝑥1


= 𝑎
[𝒀𝟏 𝑧 ] [ 21 𝑎22 𝑎23 ] [𝑦1 ]
𝑧 𝑎31 𝑎32 1 1

Bu denklemi resim üzerindeki tüm noktalara uygulamak için genelleştirirsek ve aynı zamanda programlamada
kullanacağımız indislere dönüştürürsek aşağıdaki şekilde olur. Programlarken diziler (0,0) değerinden başlar.

𝑿𝑧 𝑎00 𝑎01 𝑎02 𝑥


[𝒀𝑧 ] = [𝑎10 𝑎11 𝑎12 ] [𝑦]
𝑧 𝑎20 𝑎21 1 1

z = 𝑎20 x + 𝑎21 y + 1

𝑎00 x + 𝑎01 y + 𝑎02


𝐗=
z
𝑎10 x + 𝑎11 y + 𝑎12
𝐘=
z

Dikkat: Matrisleri programlarken indisler bir sayı aşağıdan başlar. Çünkü dizilerin başlangıç değerleri (0,0) dır.
Buna göre programda a11 matris elemanı a00 olarak gösterilir.

Artık bu formülleri kullanarak tüm belirlediğimiz alanı istediğimiz çerçeve içine sığdırabiliriz.

Programlama (Perspektif Düzeltme)


Aşağıdaki sınırlarda plakanın köşeleri (xx,yx-koordinatları), resmin sınırlarına (Xx,Yx) genişletilmiştir. Bu nedenle
plaka doğal görünümünün dışına çıkmıştır.

Plakayı daha gerçekci boyutlar görmek için dönüşeceği sınırları daha küçük tutmalıyız. (X1,Y1=0,178;
X2,Y2=800,178; X3,Y3=0,378; X4,Y4=800,378). Çerçeve 800x200 olarak belirlenmiştir.
9
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

Resim ne kadar büyük bir çerçeveye yerleştirilirse aradaki boşluklar (piksel kayıpları-alias) o kadar fazla
olmaktadır. Elde edilen resimler tekrar filtreden geçilip kayıp pikseller düzeltilmelidir. Eğer yerleştirilecek
çerçeve daha küçük seçilirse kayıp piksel azalmaktadır. Aşağıdaki örnek (400x100) boyutlarındadır. Burada
gösterilen resimler küçültülmüş boyutlardadır. Bu resimlerin her biri gerçekte 800x600 boyutlarındadır.

Yukarıdaki ilk örnekte plaka alanı (800x600) alana yerleştirilince kayıp piksel artmıştır (a resmi). Plaka 400x100
boyutlarına küçültüldüğünde kayıp pikseller daha az oluşmuştur (b resmi).

a) b)
private void btnPERSPEKTIF_Click(object sender, EventArgs e)
{
double x1 = Convert.ToDouble(txt_x1.Text);
double y1 = Convert.ToDouble(txt_y1.Text);
double x2 = Convert.ToDouble(txt_x2.Text);
double y2 = Convert.ToDouble(txt_y2.Text);
double x3 = Convert.ToDouble(txt_x3.Text);
double y3 = Convert.ToDouble(txt_y3.Text);
double x4 = Convert.ToDouble(txt_x4.Text);
double y4 = Convert.ToDouble(txt_y4.Text);

double X1 = Convert.ToDouble(txtX1.Text);
double Y1 = Convert.ToDouble(txtY1.Text);
double X2 = Convert.ToDouble(txtX2.Text);
double Y2 = Convert.ToDouble(txtY2.Text);
double X3 = Convert.ToDouble(txtX3.Text);
double Y3 = Convert.ToDouble(txtY3.Text);
double X4 = Convert.ToDouble(txtX4.Text);
double Y4 = Convert.ToDouble(txtY4.Text);
10
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

double[,] GirisMatrisi = new double[8, 8];

// { x1, y1, 1, 0, 0, 0, -x1 * X1, -y1 * X1 }


GirisMatrisi[0, 0] = x1;
GirisMatrisi[0, 1] = y1;
GirisMatrisi[0, 2] = 1;
GirisMatrisi[0, 3] = 0;
GirisMatrisi[0, 4] = 0;
GirisMatrisi[0, 5] = 0;
GirisMatrisi[0, 6] = -x1 * X1;
GirisMatrisi[0, 7] = -y1 * X1;

//{ 0, 0, 0, x1, y1, 1, -x1 * Y1, -y1 * Y1 }


GirisMatrisi[1, 0] = 0;
GirisMatrisi[1, 1] = 0;
GirisMatrisi[1, 2] = 0;
GirisMatrisi[1, 3] = x1;
GirisMatrisi[1, 4] = y1;
GirisMatrisi[1, 5] = 1;
GirisMatrisi[1, 6] = -x1 * Y1;
GirisMatrisi[1, 7] = -y1 * Y1;

//{ x2, y2, 1, 0, 0, 0, -x2 * X2, -y2 * X2 }


GirisMatrisi[2, 0] = x2;
GirisMatrisi[2, 1] = y2;
GirisMatrisi[2, 2] = 1;
GirisMatrisi[2, 3] = 0;
GirisMatrisi[2, 4] = 0;
GirisMatrisi[2, 5] = 0;
GirisMatrisi[2, 6] = -x2 * X2;
GirisMatrisi[2, 7] = -y2 * X2;

//{ 0, 0, 0, x2, y2, 1, -x2 * Y2, -y2 * Y2 }


GirisMatrisi[3, 0] = 0;
GirisMatrisi[3, 1] = 0;
GirisMatrisi[3, 2] = 0;
GirisMatrisi[3, 3] = x2;
GirisMatrisi[3, 4] = y2;
GirisMatrisi[3, 5] = 1;
GirisMatrisi[3, 6] = -x2 * Y2;
GirisMatrisi[3, 7] = -y2 * Y2;

//{ x3, y3, 1, 0, 0, 0, -x3 * X3, -y3 * X3 }


GirisMatrisi[4, 0] = x3;
GirisMatrisi[4, 1] = y3;
GirisMatrisi[4, 2] = 1;
GirisMatrisi[4, 3] = 0;
GirisMatrisi[4, 4] = 0;
GirisMatrisi[4, 5] = 0;
GirisMatrisi[4, 6] = -x3 * X3;
GirisMatrisi[4, 7] = -y3 * X3;

//{ 0, 0, 0, x3, y3, 1, -x3 * Y3, -y3 * Y3 }


GirisMatrisi[5, 0] = 0;
GirisMatrisi[5, 1] = 0;
GirisMatrisi[5, 2] = 0;
11
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

GirisMatrisi[5, 3] = x3;
GirisMatrisi[5, 4] = y3;
GirisMatrisi[5, 5] = 1;
GirisMatrisi[5, 6] = -x3 * Y3;
GirisMatrisi[5, 7] = -y3 * Y3;

//{ x4, y4, 1, 0, 0, 0, -x4 * X4, -y4 * X4 }


GirisMatrisi[6, 0] = x4;
GirisMatrisi[6, 1] = y4;
GirisMatrisi[6, 2] = 1;
GirisMatrisi[6, 3] = 0;
GirisMatrisi[6, 4] = 0;
GirisMatrisi[6, 5] = 0;
GirisMatrisi[6, 6] = -x4 * X4;
GirisMatrisi[6, 7] = -y4 * X4;

//{ 0, 0, 0, x4, y4, 1, -x4 * Y4, -y4 * Y4 }


GirisMatrisi[7, 0] = 0;
GirisMatrisi[7, 1] = 0;
GirisMatrisi[7, 2] = 0;
GirisMatrisi[7, 3] = x4;
GirisMatrisi[7, 4] = y4;
GirisMatrisi[7, 5] = 1;
GirisMatrisi[7, 6] = -x4 * Y4;
GirisMatrisi[7, 7] = -y4 * Y4;

//---------------------------------------------------------------------------
double[,] matrisBTersi = MatrisTersiniAl(GirisMatrisi);

//----------------------------------- A Dönüşüm Matrisi (3x3) -----------------


-
double a00 = 0, a01 = 0, a02 = 0, a10 = 0, a11 = 0, a12 = 0, a20 = 0, a21 = 0,
a22 = 0;

a00 = matrisBTersi[0, 0] * X1 + matrisBTersi[0, 1] * Y1 + matrisBTersi[0, 2] *


X2 + matrisBTersi[0, 3] * Y2 + matrisBTersi[0, 4] * X3 + matrisBTersi[0, 5] * Y3 +
matrisBTersi[0, 6] * X4 + matrisBTersi[0, 7] * Y4;
a01 = matrisBTersi[1, 0] * X1 + matrisBTersi[1, 1] * Y1 + matrisBTersi[1, 2] *
X2 + matrisBTersi[1, 3] * Y2 + matrisBTersi[1, 4] * X3 + matrisBTersi[1, 5] * Y3 +
matrisBTersi[1, 6] * X4 + matrisBTersi[1, 7] * Y4;
a02 = matrisBTersi[2, 0] * X1 + matrisBTersi[2, 1] * Y1 + matrisBTersi[2, 2] *
X2 + matrisBTersi[2, 3] * Y2 + matrisBTersi[2, 4] * X3 + matrisBTersi[2, 5] * Y3 +
matrisBTersi[2, 6] * X4 + matrisBTersi[2, 7] * Y4;

a10 = matrisBTersi[3, 0] * X1 + matrisBTersi[3, 1] * Y1 + matrisBTersi[3, 2] *


X2 + matrisBTersi[3, 3] * Y2 + matrisBTersi[3, 4] * X3 + matrisBTersi[3, 5] * Y3 +
matrisBTersi[3, 6] * X4 + matrisBTersi[3, 7] * Y4;
a11 = matrisBTersi[4, 0] * X1 + matrisBTersi[4, 1] * Y1 + matrisBTersi[4, 2] *
X2 + matrisBTersi[4, 3] * Y2 + matrisBTersi[4, 4] * X3 + matrisBTersi[4, 5] * Y3 +
matrisBTersi[4, 6] * X4 + matrisBTersi[4, 7] * Y4;
a12 = matrisBTersi[5, 0] * X1 + matrisBTersi[5, 1] * Y1 + matrisBTersi[5, 2] *
X2 + matrisBTersi[5, 3] * Y2 + matrisBTersi[5, 4] * X3 + matrisBTersi[5, 5] * Y3 +
matrisBTersi[5, 6] * X4 + matrisBTersi[5, 7] * Y4;

a20 = matrisBTersi[6, 0] * X1 + matrisBTersi[6, 1] * Y1 + matrisBTersi[6, 2] *


X2 + matrisBTersi[6, 3] * Y2 + matrisBTersi[6, 4] * X3 + matrisBTersi[6, 5] * Y3 +
matrisBTersi[6, 6] * X4 + matrisBTersi[6, 7] * Y4;
12
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

a21 = matrisBTersi[7, 0] * X1 + matrisBTersi[7, 1] * Y1 + matrisBTersi[7, 2] *


X2 + matrisBTersi[7, 3] * Y2 + matrisBTersi[7, 4] * X3 + matrisBTersi[7, 5] * Y3 +
matrisBTersi[7, 6] * X4 + matrisBTersi[7, 7] * Y4;
a22 = 1;
//------------------------- Perspektif düzeltme işlemi ------------------------
--------
PerspektifDuzelt(a00, a01, a02, a10, a11, a12, a20, a21, a22);
}

//================== Perspektif düzeltme işlemi =================


public void PerspektifDuzelt(double a00, double a01, double a02, double a10, double
a11, double a12, double a20, double a21, double a22)
{
Bitmap GirisResmi, CikisResmi;
Color OkunanRenk;

GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width;


int ResimYuksekligi = GirisResmi.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

double X, Y, z;

for (int x = 0; x < (ResimGenisligi); x++)


{
for (int y = 0; y < (ResimYuksekligi); y++)
{
OkunanRenk = GirisResmi.GetPixel(x, y);

z = a20 * x + a21 * y + 1;
X = (a00 * x + a01 * y + a02) / z;
Y = (a10 * x + a11 * y + a12) / z;

if (X > 0 && X < ResimGenisligi && Y > 0 && Y < ResimYuksekligi)


//Picturebox ın dışına çıkan kısımlar oluşturulmayacak.
CikisResmi.SetPixel((int)X, (int)Y, OkunanRenk);
}
}

pictureBox2.Image = CikisResmi;
}

Ödev 1. Perspektif alanı mouse ile seçme


Yukarıdaki örnek uygulamada 1,2,3,4 ve a,b,c,d noktalarını belirlemeyi mouse ile resim üzerine tıklayarak yapın.
Yani bu 8 tane nokta belirlenirken mouse kullanın. Buna göre perspektif düzeltme işlemini gerçekleştirin. Örnek
resim olarak bina cephelerindeki perspektif görünümlü reklam tabelalarını kullanın. Perspektif düzeltmesi
yapıldıktan sonra Alias oluşan noktalarda (hesaplama yapmadığı ve resim üzerinde boşlukları temsil eden siyah

13
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.com

noktaları) daha sonra düzeltmeye çalışın. Bu kısımlara geldiğinde etrafındaki 9 tane pikselin değerine bakın ve
ortadaki pikseli bu piksellerin ortalaması olarak aldırın. Buna benzer resmi daha da iyileştirecek bir yöntem
bulmaya çalışın.

Araştırma: Gaus Jordan yönteminin ne olduğunu araştıralım. Yukarıda geçen 8x8 matrislerin tersini almak için
programlamada bu yöntem mi kullanılmaktadır, değilse hangi yöntemi kullanıyor.

14
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

GÖRÜNTÜ İŞLEME - (5.Hafta)

RESİM YUMUŞATMA (BULANIKLAŞTIRMA-BLURRING) FİLTRELERİ


Görüntü işlemede, filtreler görüntüyü yumuşatmak yada kenarları belirginleştirmek için dijital filtreler
kullanılır. Bu bölümde resim yumuşatma ele alınacaktır. Bu amaçla aşağıdaki filtreler incelenecektir.
• Ortalama Filtre (Mean)
• Orta Değer Filtresi (Median)
• Gauss düzleştirme Filtresi (Gaussian Smoothing)
• Konservativ yumuşatma (Conservative Soomthing)
• Crimmins Parlaklık Giderme (Crimmins Speckle Removal)
• Frekans Filtreleri (Frequency Filters)
Filtrelemede, girdi görüntüsü f(i,j) filtre fonksiyonu ile h(i,j) ile konvolüsyon yapılarak işlem yapılır. Bu
ifade matematiksel olarak şu şekilde gösterilebilir.
𝑔(𝑖, 𝑗) = ℎ(𝑖, 𝑗) ʘ 𝑓(𝑖, 𝑗)
Konvolüsyon işlemi; bir çekirdek şablonun (matrisin/kernel) resim üzerindeki piksellerle 'kaydırma ve
çarpma' işlemi olarak tanımlanabilir. Bu işlemde çekirdek şablon resim üzerinde kaydırılır ve değeri resim
üzerindeki uygun piksellerle çarpılır.
Belli özel uygulamalar için çeşitli standart şablonlar vardır. Burada şablonun büyüklüğü ve şekli, işlemin
özelliklerini belirler. Örneğin, ortalama (mean) ve Laplace operatörünün şablonları (çekirdek matrisleri)
aşağıdaki gibidir.

ORTALAMA FİLTRESİ (Mean Filter -Box Blur)


Yaygın isimleri; Mean filtering (ortalama filtresi), Smoothing (yumuşatma), Averaging (ortalama), Box
filtering (kutu filtreleme).
Ortalama filtresi, görüntüleri yumuşatmanın basit ve uygulanması kolay bir yöntemidir. Diğer bir deyişle, bir
piksel ile diğerleri arasındaki değişim miktarını azaltmaktır. Genellikle görüntülerdeki gürültüyü azaltmak
için kullanılır.
Ortalama filtresi, bir görüntünün her bir piksel değerini komşularının ve kendisinin dahil olduğu ortalama
değer ile değiştirmektir. Bu durum, çevresindekileri temsil etmeyen piksel değerlerinin ortadan kalkmasına
yol açar. Ortalama filtresi bir konvolüsyon filtresidir. Konvolüsyon filtreleri çekirdek şablon (kernel)
temeline dayanır. Şekilde gösterildiği gibi çoğunlukla 3×3 kare çekirdek şablon kullanılır. Bazı yumuşatma
işlemlerinde daha büyük şablonlar (5×5, 7x7 gibi) kullanılabilir. Büyük şablonun tek bir taramadaki etkisine
benzer bir etki, küçük şablonun birden fazla geçişi ile de sağlanabilir.

1
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

Şekil. Ortalama filtresinde sıklıkla kullanılan 3×3 ortalama şablonu.


Ortalama filtresi, bir görüntüdeki gürültüyü azaltmak için kullanılan en basit yöntemdir. Ancak gürültü daha
az belirgin hale getirilirken, görüntüde yumuşatılmış olmaktadır. Kullanılan çekirdek şablonun (matrisin)
boyutu artırılırsa yumuşatma daha da artacaktır.
Ortalama filtrelemeyle ilgili iki ana sorun bulunmaktadır:
a) Resmi çok iyi temsil etmeyen değere sahip bir piksel, yakın bölgedeki tüm piksellerin ortalama değerini
önemli ölçüde etkiler. Buda resmin değişmesine sebep olur.
b) Filtre (şablon) bir kenar üzerinden geçerken, kenarın her iki tarafındaki pikseller için yeni değerler
üretecektir ve bu durum kenarın bulanıklaşmasına sebep olacaktır. Eğer keskin kenarların kaybolması
istenmiyorsa bu bir sorun olabilir.
Bu iki problemi gidermek için Ortalama filtresi (mean) yerine, Medyan filtresi (Median Filter)
geliştirilmiştir. Fakat bu filtrenin de hesaplama süresi uzun sürmektedir. Resmi yumuşatma için yaygın
kullanılan filtrelerden biri de "Gauss yumuşatma filtresi" (Gaussian smoothing filter) dir.
Programlama (Ortalama Filtresi-Mean Filter)

Normal resim 3x3 Şablon

5x5 Şablon 7x7 Şablon


2
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

public void meanFiltresi ()


{
Color OkunanRenk;
Bitmap GirisResmi, CikisResmi;
GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width;


int ResimYuksekligi = GirisResmi.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

int SablonBoyutu = Convert.ToInt32(textBox1.Text); //şablon boyutu 3 den büyük tek rakam


olmalıdır (3,5,7 gibi).
int x, y, i, j, toplamR, toplamG, toplamB, ortalamaR, ortalamaG, ortalamaB;

for (x = (SablonBoyutu - 1) / 2; x < ResimGenisligi - (SablonBoyutu - 1) / 2; x++)


{
for (y = (SablonBoyutu - 1) / 2; y < ResimYuksekligi - (SablonBoyutu - 1) / 2; y++)
{
toplamR = 0;
toplamG = 0;
toplamB = 0;

for (i = -((SablonBoyutu - 1) / 2) ; i <= (SablonBoyutu - 1) / 2 ; i++)


{
for (j = -((SablonBoyutu - 1) / 2); j <= (SablonBoyutu - 1) / 2; j++)
{
OkunanRenk = GirisResmi.GetPixel(x + i, y + j);

toplamR = toplamR + OkunanRenk.R;


toplamG = toplamG + OkunanRenk.G;
toplamB = toplamB + OkunanRenk.B;

}
}

ortalamaR = toplamR / (SablonBoyutu * SablonBoyutu);


ortalamaG = toplamG / (SablonBoyutu * SablonBoyutu);
ortalamaB = toplamB / (SablonBoyutu * SablonBoyutu);

CikisResmi.SetPixel(x, y, Color.FromArgb(ortalamaR, ortalamaG, ortalamaB));


}
}

pictureBox2.Image = CikisResmi;
}
Yukarıda verilen örnek resim filtrenin özelliklerini görmek için yeterli olmaz. Yumuşatma filtreleri daha çok
resim üzerindeki gürültüyü azaltmak için kullanılır. Aşağıdaki resimler Mean filtresinin gürültülü bir resim
üzerindeki etkisini göstermektedir. Sırayla normal gürültülü resim, 3x3, 5x5 ve 7x7 şablon (matris)
kullanılan resimlerdir.

3
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

Normal resim 3x3 Şablon

5x5 Şablon 7x7 Şablon

Aynı resim üzerinde 3 defa 3x3 şablonu ile Mean filtresini uygularsak aşağıdaki gibi sonuç alırız. Bu
sonucun 5x5 şablonuna yakın bir sonuç verdiğini görebiliriz. Her iki uygulamada da işlem gören piksel
sayısı yakın bir değer olmuş olur. (3x3=9)x3=27 piksel. 5x5=25 piksel.

4
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

5x5 Şablon 3 defa 3x3 şablonu uygulanmış resim

Araştırma: Çekirdek matris resim üzerinde ilerlerken her seferinde eski resmin piksellerine bakmaktadır.
Oysa rengi değişmiş olan piksellerin rengi de kullanılabilir. Böyle uygulama durumunda resim de nasıl bir
değişiklik görürüz. Deneyerek bulmaya çalışın.

MEDYAN FİLTRESİ (ORTA DEĞER FİLTRESİ-MEDİAN FİLTER)


Bu filtrenin yaygın kullanılan isimleri; Medyan filtresi (Orta Değer filtresi) (Median filtering), Sıralama
filtresi (Rank filtering)
Medyan filtresi, normal olarak mean filtresi gibi bir resimdeki gürültüyü azaltmak için kullanılır. Ancak
resim üzerindeki detayların kaybolmaması noktasında mean filtresinden çok daha iyi sonuç verir.
Medyan filtre de mean filtresi gibi her pikselin değerini hesaplamak için yakınındaki komşularına bakar. Medyan
filtresinde piksel değeri komşu piksel değerlerinin ortalaması ile değiştirmek yerine (mean filtresi), komşu
pikselleri sıralayıp sıranın ortasındaki değeri alır. Eğer incelenen bölge (şablonun içerisi) çift sayıda piksel varsa,
orta değer olarak, ortada bulunan iki pikselin ortalaması kullanılır.
Aşağıdaki şekilde ortadaki piksele göre işlemlerimizi yaparsak bu pikselin değeri olan 150 sayısı çevresindeki
pikselleri iyi bir şekilde temsil etmediğini görebiliriz. Bu pikselin değerini değiştirirken öncelikle çevresindeki
piksellerin değerini bir sıraya dizelim. Bunlar (115, 119, 120, 123, 124, 125, 126, 127,150) değerlerinden oluşur.
Bu değerlerin en ortasında ise 124 sayısı vardır. Buna göre 150 rakamı 124 sayısı ile değiştirilir. Burada 124
sayısı medyan sayısı (orta değer) olmuş olur.
Burada kullanılan şablon 3x3 piksel boyutlarındadır. Daha büyük şablonların kullanılması daha fazla
pürüzsüzleştirme (yumuşatma) etkisi üretir.

5
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

Medyan filtrenin Mean filtresine nazaran iki avantajı vardır.


• Orta değeri (median) kullanmak, ortalama değeri kullanmaktan (mean) daha güçlü olarak şablonu temsil
eder. Temsil yeteneği uzak bir piksel sıralanan dizinin uçlarında kalacağından (hiç bir zaman ortada
bulunmayacaktır) oradaki komşuların genel temsilini etkilemesi imkansız hale gelmiş olur.
• Medyan değer (orta değer), komşu piksellerin birinin değeri olması gerektiği için, kenar boyunca hareket
ettiğinde gerçekçi olmayan piksel değerleri oluşturmaz. Bu nedenle, medyan filtre, keskin kenarları
ortalama filtreden (mean) daha iyi korur. Örnekleyecek olursa, siyah ve beyazdan oluşan bir sınırda
ortadaki değer ya siyah olur yada beyaz olur. İkisinin ortalaması olan gri olmayacaktır. Böylece kenar
üzerindeki keskinlik kaybolmamış olacaktır.

Programlama (Medyan Filtresi)

Normal resim 3x3 Şablon

6
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

5x5 Şablon 7x7 Şablon


public void medianFiltresi ()
{
Color OkunanRenk;
Bitmap GirisResmi, CikisResmi;
GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width;


int ResimYuksekligi = GirisResmi.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

int SablonBoyutu = 0;
try
{
SablonBoyutu = Convert.ToInt32(textBox1.Text);
}
catch
{
SablonBoyutu = 3;
}
int ElemanSayisi = SablonBoyutu * SablonBoyutu;

int[] R = new int[ElemanSayisi];


int[] G = new int[ElemanSayisi];
int[] B = new int[ElemanSayisi];
int[] Gri = new int[ElemanSayisi];

int x, y, i, j;

for (x = (SablonBoyutu - 1) / 2; x < ResimGenisligi - (SablonBoyutu - 1) / 2; x++)


{
for (y = (SablonBoyutu - 1) / 2; y < ResimYuksekligi - (SablonBoyutu - 1) / 2; y++)
{
//Şablon bölgesi (çekirdek matris) içindeki pikselleri tarıyor.
int k = 0;
for (i = -((SablonBoyutu - 1) / 2); i <= (SablonBoyutu - 1) / 2; i++)
{
for (j = -((SablonBoyutu - 1) / 2); j <= (SablonBoyutu - 1) / 2; j++)
{
OkunanRenk = GirisResmi.GetPixel(x + i, y + j);

7
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

R[k] = OkunanRenk.R;
G[k] = OkunanRenk.G;
B[k] = OkunanRenk.B;

Gri[k] = Convert.ToInt16(R[k] * 0.299 + G[k] * 0.587 + B[k] * 0.114); //Gri ton formülü

k++;
}
}

//Gri tona göre sıralama yapıyor. Aynı anda üç rengide değiştiriyor.


int GeciciSayi = 0;

for (i = 0; i < ElemanSayisi; i++)


{
for (j = i + 1; j < ElemanSayisi; j++)
{
if (Gri[j] < Gri[i])
{
GeciciSayi = Gri[i];
Gri[i] = Gri[j];
Gri[j] = GeciciSayi;

GeciciSayi = R[i];
R[i] = R[j];
R[j] = GeciciSayi;

GeciciSayi = G[i];
G[i] = G[j];
G[j] = GeciciSayi;

GeciciSayi = B[i];
B[i] = B[j];
B[j] = GeciciSayi;
}
}
}

//Sıralama sonrası ortadaki değeri çıkış resminin piksel değeri olarak atıyor.
CikisResmi.SetPixel(x, y, Color.FromArgb(R[(ElemanSayisi - 1) / 2], G[(ElemanSayisi - 1) /
2], B[(ElemanSayisi - 1) / 2]));
}
}

pictureBox2.Image = CikisResmi;
}

Medyan filtresinin dezavantajı olarak şundan bahsedilebilir. Resim üzerinde büyük boyutlarda gürültü varsa,
Medyan filtresi küçük matrislerle (şablonla) gürültüyü tam olarak kaldıramaz. Bu gibi durumlarda daha
büyük matrisler kullanmak gerekir yad a bir kaç kez aynı filtreden geçirmek gerekebilir.
Bir diğer dezevantajı ise hesaplama zamanın uzun olmasıdır. Çünkü komşu piksellerin değerlerini alıp
bunları sıralamaya tabi tutar. Bazı akıllı algoritmalar ile sıralama hızı artırılabilir. Örneğin şablon resim
üzerinde gezerken bir birçok pikselin değeri bir adımdan diğerine aynı kalmaktadır.

8
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

Normal resim 3x3 Şablon

5x5 Şablon 7x7 Şablon

GAUSS BULANIKLAŞTIRMA/YUMUŞATMA FİLTRESİ (Gaussian Smoothing- Gaussian blur)


Gauss yumuşatma operatörü, görüntüleri 'bulanıklaştırmak', ayrıntı ve gürültüyü ortadan kaldırmak için
kullanılan 2 boyutlu konvolüsyon (çekirdek matris ile resim üzerindeki piksellerin çarpımı işlemi)
operatörüdür. Bu anlamda, ortalama (Mean) filtreye benzer. Ancak Gauss aşağıda resmi verilen "çan
şeklindeki" grafikle temsil edilebilecek farklı bir çekirdek şablon (matris) kullanır.
Gauss'un çan şeklindeki grafiğini veren formül 2 boyutlu düzlem ve 3 boyutlu uzay için yazılırsa aşağıdaki
şekilde gösterilebilir.

9
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

1 𝑥2
𝐺(𝑥) = 𝑒 − 2𝜎
√2𝜋 𝜎

1 𝑥 2 +𝑦 2

𝐺(𝑥) = 𝑒 2𝜎2
√2𝜋 𝜎 2

Burada σ dağılımın standart sapmasıdır. Ayrıca, dağılımın ortalamasının sıfır olduğu varsayılmıştır (yani, x
= 0 çizgisine ortalanmıştır). 2 boyutlu ve 3 boyutlu grafik eksenel olarak simetrik değerlere sahiptir.
İki boyutlu grafiği Standart sapma σ=1 için x=∓2 aralığında excel de çizecek olursak aşağıdaki grafiği elde
ederiz.

3 boyutluğu grafiği çizmek için Word içerisine yine microsoft'un bir eklentisi olan Mathematics programını
(https://www.microsoft.com/en-us/download/confirmation.aspx?id=17786) adresinden indirip kuralım.
Word'ü kapatıp açtığımızda ilgili sekme gözükecektir. Ardından denklemimizi sayfada yazıp seçersek
10
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

menüden Plot in 3D seçip grafiği çizdirebiliriz. Grafik üzerinde bazı ayarları (çizim aralıklarını vs seçip
istenilen grafiğin durumunu görebiliriz.

a) Standart sapma σ=1 için çizilen grafik b) Standart sapma σ=2 için çizilen grafik
Dikkat edilirse standart sapma değeri arttıkça grafik daha yayvan hale gelmektedir. z değerinin 0 yakın bir
değerden başlaması için x ve y değerlerinin daha büyük değer aralığını almasını gerektirir (Burada σ=2 için -
4,+4 aralığı alınmıştır) . Dolayısı ile standart sapma değeri (σ) arttıkça onu temsil eden matrisleride daha
büyük seçmek uygun olacaktır.
Standart sapma σ=1 için matris değerlerimizi hesaplayalım. Bunun için 5x5 bir matris oluşturalım.
Dolayısıyla x ve y değer aralığımızı -2,-1,0,1,2 olarak belirleyelim.

Ölçek:
1/0,007306897=
x y σ 136,856991
-2 -2 1 0,398943084 0,018315639 0,007306897 1
-1 -2 1 0,398943084 0,082084999 0,032747242 4,48168907
0 -2 1 0,398943084 0,135335283 0,053991075 7,389056099
1 -2 1 0,398943084 0,082084999 0,032747242 4,48168907
2 -2 1 0,398943084 0,018315639 0,007306897 1
-2 -1 1 0,398943084 0,082084999 0,032747242 4,48168907
-1 -1 1 0,398943084 0,367879441 0,146762959 20,08553692
0 -1 1 0,398943084 0,60653066 0,241971212 33,11545196
1 -1 1 0,398943084 0,367879441 0,146762959 20,08553692
2 -1 1 0,398943084 0,082084999 0,032747242 4,48168907
11
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

-2 0 1 0,398943084 0,135335283 0,053991075 7,389056099


-1 0 1 0,398943084 0,60653066 0,241971212 33,11545196
0 0 1 0,398943084 1 0,398943084 54,59815003
1 0 1 0,398943084 0,60653066 0,241971212 33,11545196
2 0 1 0,398943084 0,135335283 0,053991075 7,389056099
-2 1 1 0,398943084 0,082084999 0,032747242 4,48168907
-1 1 1 0,398943084 0,367879441 0,146762959 20,08553692
0 1 1 0,398943084 0,60653066 0,241971212 33,11545196
1 1 1 0,398943084 0,367879441 0,146762959 20,08553692
2 1 1 0,398943084 0,082084999 0,032747242 4,48168907
-2 2 1 0,398943084 0,018315639 0,007306897 1
-1 2 1 0,398943084 0,082084999 0,032747242 4,48168907
0 2 1 0,398943084 0,135335283 0,053991075 7,389056099
1 2 1 0,398943084 0,082084999 0,032747242 4,48168907
2 2 1 0,398943084 0,018315639 0,007306897 1

Bu değerler matris formatına dönüştürülürse aşağıdaki Gauss yumuşatma operatörünün çekirdek matrisi elde
edilmiş olur.

Diğer sayılarda ona göre en yakın tam sayıya yuvarlandığında bu tablo elde edilir. Gauss formülündeki
katsayılar bu mantıkla değiştirilerek farklı değerlerde matrislerde elde edilebilir. Tablo yanındaki çarpım
değerleri matristeki elemanların toplamını gösterir. Burada olduğu gibi uygun bir Gauss çekirdek matrisi
oluşturulduktan sonra ortadaki piksel, resim üzerindeki hedef piksel üzerinde olmak üzere, komşu pikseller
de matristeki komşu değerler ile çarpılır ve sol taraftaki toplam değere (273, 112, 16 şeklinde verilen
değerler) bölünür.

Burada olduğu gibi konvolüsyon işlemi 3 boyutlu grafikten türetilen 2 boyutlu matrisle (kare matris)
yapılabileceği gibi, 2 boyutlu grafikten türetilen 1-boyutlu vektör matrisle, iki ayrı işlemle yapılabilir. 1-
boyutlu vektör matrise örnek aşağıda verilmiştir (1x7 matris). Buradaki 1x7 lik matris 2 boyutlu gauss
12
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

grafiğinden elde edilmiştir. Matristeki değerler en uçtaki değer 1 olacak şekilde ölçeklenirse yanında
verildiği şekilde çekirdek matris elde edilir. Bu matrisin en ortadaki elemanı işlem yapılan piksel üzerinde
olmak üzere önce x ekseninde yatay olarak tüm resimdeki piksellerle çarpılabilir, ardından dikeyde y ekseni
üzerindeki tüm piksellerle çarpılarak konvolüsyon işlemi yapılabilir.

Büyük çekirdek matris kullanarak hesaplama yapmak yerine, daha küçük matrisle resim üzerinden geçmek
(konvolüsyon yapmak) de mümkündür. Bu tür bir işlem paralel donanımlar kurarak hesaplama için daha
uygun olur.
Gauss'un resim düzgünleştirme etkisi, bir görüntüyü ortalama filtreye benzer şekilde bulanıklaştırmaktır.
Düzeltme derecesi Gaussian'ın standart sapması ile belirlenir. Daha büyük standart sapma değeri, ortaya
çıkan grafiği daha geniş hale getirir. Bundan türetilen çekirdek matrisinde doğru bir temsil yapabilmesi için
daha büyük boyutta olmasını gerektirir.
Gauss, her piksel bölgesinin ağırlıklı ortalamasını çıkarır. Merkez piksel değerine doğru yaklaştıkça
ağırlıklandırma artar. Bu durum, ortalama filtrenin (Mean) (her yeri eşit ağırlıklandırma yapar) aksine daha
ince bir düzeltme sağlar, kenarları benzer büyüklükteki bir ortalama filtreden daha iyi korur.
Gauss yumuşatma filtresinin kullanmanın gerekçelerinden biri de, resim üzerindeki uzaysal-mekansal
frekans bileşenleri korumaktır (yani çok sık aralıkla resim üzerindeki değişimleri korumasıdır). Çoğu diğer
filtre alçak geçirgen filtre gibi davranır (yap hep ya hiç kuralı gibi). Her iki filtrede yüksek frekansları
zayıflatır (örn: keskin kenarları). Ancak Ortalama filtresi frekans tepkimesi olarak salınımlar gösterir. Gauss
filtresi ise salınım göstermez. Aşağıdaki şekiller Ortalama filtre (5x5 boyutunda) ve Gauss filtrenin (standart
sapması σ=3) frekans tepkilerini göstermektedir.

Gauss filtrenin daha büyük matrislerle (standart sapmalarla) pürüzsüzleştirme etkisini görmek için şu
örnekleri inceleyin.

Gauss Filtresi Programlama


Aşağıdaki program 5x5 lik yukarıda şekli verilen { 1, 4, 7, 4, 1, 4, 20, 33, 20, 4, 7, 33, 55, 33, 7, 4, 20, 33,
20, 4, 1, 4, 7, 4, 1 } matrisini kullanarak uygulanmıştır. Soldaki orjinal resimdir.

13
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

private void gaussFiltresiToolStripMenuItem_Click(object sender, EventArgs e)


{

Color OkunanRenk;
Bitmap GirisResmi, CikisResmi;
GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width;


int ResimYuksekligi = GirisResmi.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

int SablonBoyutu = 5; //Çekirdek matrisin boyutu


int ElemanSayisi = SablonBoyutu * SablonBoyutu;

int x, y, i, j, toplamR, toplamG, toplamB, ortalamaR, ortalamaG, ortalamaB;


int[] Matris = { 1, 4, 7, 4, 1, 4, 20, 33, 20, 4, 7, 33, 55, 33, 7, 4, 20, 33, 20, 4, 1, 4, 7, 4, 1 };
int MatrisToplami = 1 + 4 + 7 + 4 + 1 + 4 + 20 + 33 + 20 + 4 + 7 + 33 + 55 + 33 + 7 + 4 + 20 +
33 + 20 + 4 + 1 + 4 + 7 + 4 + 1;

14
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

//int[] Matris = { 1, 2, 4, 2, 1, 2, 6, 9, 6, 2, 4, 9, 16, 9, 4, 2, 6, 9, 6, 2, 1,


2, 4, 2, 1 };
//int MatrisToplami = 1 + 2 + 4 + 2 + 1 + 2 + 6 + 9 + 6 + 2 + 4 + 9 + 16 + 9 + 4 + 2
+ 6 + 9 + 6 + 2 + 1 + 2 + 4 + 2 + 1;

for (x = (SablonBoyutu - 1) / 2; x < ResimGenisligi - (SablonBoyutu - 1) / 2; x++) //Resmi


taramaya şablonun yarısı kadar dış kenarlardan içeride başlayacak ve bitirecek.
{
for (y = (SablonBoyutu - 1) / 2; y < ResimYuksekligi - (SablonBoyutu - 1) / 2; y++)
{
toplamR = 0;
toplamG = 0;
toplamB = 0;

//Şablon bölgesi (çekirdek matris) içindeki pikselleri tarıyor.


int k = 0; //matris içindeki elemanları sırayla okurken kullanılacak.
for (i = -((SablonBoyutu - 1) / 2); i <= (SablonBoyutu - 1) / 2; i++)
{
for (j = -((SablonBoyutu - 1) / 2); j <= (SablonBoyutu - 1) / 2; j++)
{
OkunanRenk = GirisResmi.GetPixel(x + i, y + j);

toplamR = toplamR + OkunanRenk.R * Matris[k];


toplamG = toplamG + OkunanRenk.G * Matris[k];
toplamB = toplamB + OkunanRenk.B * Matris[k];

k++;
}

}
ortalamaR = toplamR / MatrisToplami;
ortalamaG = toplamG / MatrisToplami;
ortalamaB = toplamB / MatrisToplami;

CikisResmi.SetPixel(x, y, Color.FromArgb(ortalamaR, ortalamaG, ortalamaB));

}
}
pictureBox2.Image = CikisResmi;

}
Görüldüğü gibi Gauss filtresi kenarları korumada daha başarılıdır. Fakat Tuz-biber ekilmiş gürültülü resimlerde
çok da başarılı sayılmaz (Bu tip resimlerde Medyan filtresinin başarılı olduğunu hatırlayalım). Gauss filtresinin
9x9, 15x15 örneklerini de siz deneyin. Ayrıca aynı resim için Mean ve Medyan filtresi ile karşılaştırmalar
yapınız.

Ödev 1: Örnek 4 tane resim tespit edin. Bir tanesi insan yüzü, saç ve kirpiklerin olduğu bir resim olsun. Bir tanesi
üzeride tekrar eden çizgilerin olduğu bir resim olsun (Izgara benzeri şeyler olsun). Bir taneside bir manzara resmi
olsun. Bir tanede üzerinde tuz-biber noktaları oluşturulmuş bir resim olsun. 3 farklı Algoritmayı (Mean, Median,
Gauss) algoritmayı 3x3, 5x5, 7x7 ve 9x9 matrisleri kullanarak bu 4 resim üzerinde deneyin. Ortaya çıkan
sonuçları yorumlayın. En iyi hangi algoritmalar hangi matriste sonuç verdi bulun.

15
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

Ödev 2: İnternetten bulanıklaştırma ile ilgili başka bir algoritma bulun. Yada tamamen kendi mantığınıza göre bir
algoritma geliştirin (ders notlarında anlatılmayan bir yöntem olması gerekir). Bu algoritmanın performansını
Mean, Median ve Gauss ile karşılaştırın. Örnek başka blur algoritmaları: Konservativ yumuşatma (Conservative
Soomthing), Crimmins Parlaklık Giderme (Crimmins Speckle Removal), Frekans Filtreleri (Frequency Filters)
vs.. daha başka vardır araştırın.

Ödev 3: İçerisinde reklam olan bir resmin köşelerine tıklayın. Sadece o bölgeyi buzlu cama dönüştürsün
(bulanıklaştırsın) ve reklamı gizlesin.

Ödev 4: Gauss algoritmasında standart sapmanın etkisinin ne olduğunu programlayarak farklı resimler üzerinde
gösterin ve yorumlayın.

Ödev 5: İçerisinde bina olan bir resmi açın. Resim üzerinde binanın dış kenarların mouse ile tıklayarak bir
çerçeve çizin. Çok sayıda nokta olacaktır. Ardından Ortalama (mean) algoritmasını çalıştırın. Tüm resmi tararken
binanın dışında kalan kısımları bulanıklaştırsın. Binanın içerisindeki bölgeye gelince resim net olarak kalsın.
Böylelikle baktığımız nesneyi net olarak, arka planı ise bulanık görmüş oluruz.
Çoklu nokta şeklinde yapamayanlar, dikdörtgen çerçeve şeklinde bölgeyi seçsinler. Bu şekilde yapanlar daha
düşük puan alır.

Ödev 6: Blur (bulanıklaştırma) aracı kullanarak bir resim üzerinde mouse takip eden bulur işlemi yaptırın. Bunun
için aşağıdaki adımları takip edin.
a) Mouse ın etrafında büyüklüğü ayarlanabilir belli bir bölge olsun. Örneğin açılır menüden 50 piksel
seçilirse mouse etrafında 50x50 lik kare bir şekilde dolaşsın. Bu alanın içi bulanıklaşsın.

b) Kişi ister bu şekli Kare yada Daire olarak değiştirebilsin. Bu bölge Kare yada Daire olarak seçilebilsin.
Bu bölgenin içerisi mouse hareket ettikçe, bulanıklaşsın.

c) Ayrıca bu aracın kenarları üzerinde geçişli bir bulanık oluşturmak için bir ayar daha eklensin. Örneğin
burada %100 seçilirse Dairenin merkezinden kenara kadar yavaş yavaş bulur azalarak gitsin. %50
seçilirse darenin yarısından sonra yavaş yavaş bulur azalsın.

d) Bulurun yoğunluğunun ayarlanabildiği bir seçenek daha ekleyin. Aşağıda Intensity olarak gösterilmiş. Bu
ayarı kullanmak için kullanılan çekirdek matrsi boyutunu artırarak gerçekleştirebilirsiniz. 7x7 lik matris
kullanımı 3x3 lük matristen daha fazla yoğunluk bulur yapar.

16
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

e) Kullanılan algoritma açılır menüden, yada radyo buton listesinden seçilebilsin. Örneğin; Mean
algoritması, Medyan algoritması, Gauss algoritması gibi .

Ödev 7: Bulanıklaştırma işlemi yaparken resim üzerinde gezdirilen matrisin içindeki renk değerlerini tarayın. Bu
renk değerlerinden en fazla hangi renk var ise o rengi yandaki resim üzerine atasın. Algoritmanın kodları Medyan
algoritmasına benzerdir. O kodları kullanın. Algoritmada kullanılan matrisin büyüklüğü dışarıdan girilebilsin.
3x3, 5x5, 7x7, 9x9 olmak üzere çeşitli büyüklükte matrisler kullanarak performansını ölçün.
Bu şekilde yapılan bulanıklaştırma resmini Ortalama (Mean) ve Orda Değer (Median) algoritmaları ile
karşılaştırın. (Bu iki algoritmanın kodları zaten notlarda var). Farklı resimler üzerinde deneyerek sizin
geliştirdiğiniz algoritmanın hangi resimlerde daha mantıklı bulanıklaştırma yaptığını bulun.
Örnek: Aşağıda 5x5 bir matrisin içindeki sayılara baktığımızda. Tabii renkli resimde 3 kanal var. Siz Medyan
filtresinde olduğu gibi Gri renk üzerinden sıralama yaparak en fazla renk sayısı hangisi ise onu atayabilirsiniz.
Sonuçların mantıklı çıkıp çıkmayacağını görün bakalım.
[1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 7, 7, 8, 8, 8, 8 9, 9, 9, 9 ] =(En fazla değer 3 tür. Piksele 3 atanır)

Ödev 8: Gauss algoritmasında kullanılan matrisin değerlerini oluştururken bir tepe şeklinde geometriden değerler
alınıyordu. Bu şekilde oluşan yükseltilere göre tabandaki matris oluşturuluyordu. Bu sefer Tepe şeklinde değilde
Pramit şeklinde (Mısır piramitlerini göz önüne getirin) bir yükseltiden tabandaki Matrisin değerlerini oluşturun.
Ona göre resim üzerinde bir bulanıklaştırma yapın.
Bu uygulamada matrisde iç içe halkaların hepsi aynı sayıları alır. En dış halka 1 ise daha iç halka diyelim 3
onunda içindeki 5, ortadaki de 7 gibi değerler alır. Yani sayılar lineer (doğrusaldır). Farklı yükseklikte Pramit için
matrisi değiştirerek sonuçları gözlemleyin.

17
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

Ek Açıklama: Standart Sapma Nedir?


Her ne kadar görüntü işleme ile ilgisi bulunmasa da burada geçtiği için standart sapmanın ne olduğunu
anlamaya çalışalım.
Tanımı: Sayılardan oluşan bir dizideki her bir elemanın, o sayıların aritmetik ortalaması ile farkının
karelerinin, dizideki eleman sayısının bir eksiğine bölümünün kareköküne standart sapma denir. Formülüze
edersek aşağıdaki şekilde gösterebiliriz.
Dizideki elemanları x1, x2, ..., xn ile gösterirsek bu elemanların ortalaması ve standart sapması aşağıdaki
şekilde olur.
𝑥1 + 𝑥2 + 𝑥3 + ⋯ 𝑥𝑛
𝑂𝑟𝑡𝑎𝑙𝑎𝑚𝑎(𝑂) =
𝑛

(𝑥1 − 𝑂)2 + (𝑥2 − 𝑂)2 + (𝑥3 − 𝑂)2 + ⋯ (𝑥𝑛 − 𝑂)2


𝑆𝑡𝑎𝑛𝑑𝑎𝑟𝑡 𝑆𝑎𝑝𝑚𝑎 = √
𝑛−1

Standart sapmanın anlamı nedir? Elimizde iki farklı veri grubu olsun. Bunların her ikisininde aritmetik
ortalaması aynı olsun. Bu verilerin ortalamaları aynı ise bunları karşılaştırmak için neye bakabiliriz. Bunun
için merkezi yayılma durumuna bakabiliriz. Yani verilerin ortalamadan ne kadar uzakta yada yakında
toplandığı bize bir fikir verebilir. Buna standart sapma denir.
• Standart sapma verilerin aritmetik ortalamaya göre nasıl bir yayılım gösterdiğini anlatır.
• Aritmetik ortalamaları aynı olan farklı veri gruplarından; açıklığı küçük olanın standart sapması küçük,
açıklığı büyük olanın standart sapması büyüktür.
• Standart sapması küçük olması bir veri grubundaki değerlerin birbirine yakın olduğunu gösterir, büyük
olması ise veri grubundaki değerlerin birbirinden uzak olduğunu gösterir.
• Standart sapmanın küçük olması, ortalamadan sapmanın az olduğunu gösterir buda riskin az olduğu
yönünde yorumlanabilir. büyük olması durumunda ise tam tersidir.
Örnek: İki öğrencinin bir hafta içinde okudukları kitap sayfa sayısı 5 gün içinde şu şekilde gerçekleşmiş
olsun. A={10,25,15,20,10} B={15,10,35,5,15}. Bu iki öğrencinin günlük kitap okuma ortalamalarına
bakacak olursak her ikisi de aynı ortalamaya sahip (ortalama 16 sayfa kitap okumuşlardır). Peki bu iki
öğrenci aynı performansa mı sahiptir? Ortalamaları aynı ise, aynı performansa sahip diyebiliriz fakat durum
öyle değildir. En düzenli ve istikrarlı okuyan hangisi ise onu daha performanslı saymak gerekir. Bunun
içinde günlük okumalarının ortalamadan ne kadar saptığını ölçmemiz gerekir. Bu amaçla Standart
sapmasını hesaplamalıyız. Hesaplayalım.
Dizimizdeki eleman sayısı n=5 dir. 5 gün boyunca okunan değerler ölçülmüştür.
A nın Ortalaması: (10+25+15+20+10) / 5=16
B nin Ortalaması: (15+10+35+5+15) / 5=16
(16−10)2 +(16−25)2 +(16−15)2 +(16−20)2 +(16−10)2
A nın Standart Sapması: √ (5−1)
= 6,5

(16−15)2 +(16−10)2 +(16−35)2 +(16−5)2 +(16−15)2


B nin Standart Sapması: √ (5−1)
= 11,4

Bu değerleri yorumlarsak, her iki öğrencinin ortalama okudukları kitap sayısı aynıdır ama A öğrencinin
standart sapması düşüktür. Bu da kitap okuma konusunda daha istikrarlı olduğunu gösterir. Bunu
öğrencilerin okudukları sayfa sayılarındaki değişimlere bakarak da anlayabilirdik.

18
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

GÖRÜNTÜ İŞLEME - (6.Hafta)

GÖRÜNTÜ NETLEŞTİRME ALGORİTMALARI


1. YÖNTEM: KENAR GÖRÜNTÜSÜNÜ KULLANARAK RESMİ NETLEŞTİRME
Bu algoritma orjinal görüntüden, görüntünün yumuşatılmış halini çıkararak belirgin kenarların görüntüsünü
ortaya çıkarır. Daha sonra orjinal görüntü ile belirginleşmiş kenarların görüntüsünü birleştirerek, kenarları
keskinleşmiş görüntüyü (netleşmiş görüntü) elde eder. Görüntünün netleştirilmesi fotogrametri ve baskı
endüstrisinde yaygın olarak kullanılır.
g(x,y) çıkış görüntüsü, f(x,y) giriş görüntüsü ve fsmooth(x,y) de bu görünün yumuşatılmış hali olmak üzere bu işlem
aşağıdaki şekilde gösterilebilir.
𝑔(𝑥, 𝑦) = 𝑓(𝑥, 𝑦) − 𝑓𝑠𝑚𝑜𝑜𝑡ℎ (𝑥, 𝑦)
𝑓𝑠ℎ𝑎𝑟𝑝 (𝑥, 𝑦) = 𝑓(𝑥, 𝑦) + 𝑘 ∗ 𝑔(𝑥, 𝑦)
Burada k bir ölçekleme sabitidir. k için makul değerler 0,2-0,7 arasında değişir. k büyüdükçe keskinleştirme
miktarı artar.

Filtrenin frekans cevabını inceleyerek işlemi daha iyi anlayabiliriz. Eğer bizim elimizde aşağıda Şekil a daki gibi
bir sinyal varsa, bu sinyal Şekil b’de olduğu gibi lowpass filtreden geçirilirse, yani düşük frekanslar geçirilerek
resmin yumuşatılması sağlanırsa, ortaya Şekil c’deki gibi highpass görüntü yani yüksek frekansların geçtiği
keskin kenarların ortaya çıktığı bir görüntü elde edilir. Bu keskin kenarlar, orjinal görüntü ile birleştirilirse
netleştirilmiş (kenarları keskinlşetirilmiş) görüntü oluşur (Şekil d).

Şekil. Keskinleştirme filtresi için frekans cevabı ile kenar görüntüsü hesaplama

Keskinleştirme filtresi konvolüsyon işlemi ile yapılır. Yani çekirdek bir matris kullanılarak, resim alanı üzerinde
gezdirilir ve gerekli çarpma işlemleri ile yeni resim elde edilir. Görüntünün yumuşatılmış versiyonunu
oluşturmak için 3x3 lük Ortalama filtresi (mean filter) kullanılabilir. Ardından yumuşatılmış görüntü, orjinal
1
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

görüntüden piksel değerleri üzerinden çıkarılır. Bu esnada ortaya çıkan değerler negatif yada 255 i geçebilir. Bu
durumda değerleri normalize etmek gerekir.
Değerleri normalize etme: Matematiksel işlemler sonunda görüntüdeki R,G,B değerleri 0-255 değerlerinin
dışına çıkarsa tüm resmi aynı orantıya tabi tutarak değerleri yeniden normalize etmek gerekir.
Resim içerisindeki limit değerleri a,b ile, bu değerlerin olması gereken aralık olan 0,255 sayılarını da c,d ile,
normalize edilecek değeri Pin, normalize olmuş halinide Pout ile gösterirsek, bu işlemi aşağıdaki şekilde
formülüze edebiliriz. Dikkat edilirse bu formül verilen aralıklarda değerleri orantı kurarak bir gerdirme işlemidir.
Aşağıdaki resimde üçgenlerdeki benzerliği kullanarak formülü bulabiliriz.

(𝑑 − 𝑐) (𝑃𝑜𝑢𝑡 − 𝑐) 𝑑−𝑐
= → 𝑃𝑜𝑢𝑡 = (𝑃𝑖𝑛 − 𝑎) ( )+𝑐
(𝑏 − 𝑎) (𝑃𝑖𝑛 − 𝑎) 𝑏−𝑎
Örneklersek; Keskinleştirme işlemi yapıldıktan sonra resim içindeki üst ve alt sınırlar yani a ve b değerleri -30 ile
330 değerlerini alsın. Bu takdirde sınırlarımız ve aradaki herhangi bir 120 değeri şu şekilde hesaplanır.

255 − 0
𝑃𝑜𝑢𝑡 = (120 − (−30)) ( ) + 0 = 106
330 − (−30)
Not: Burada normalleştirme öncesi üst ve alt sınırlardan biri (a ve b değerlerinden biri) 0 ve 255 değerlerini
aşmaz ise (her ikiside aşmıyorsa zaten normalleştirmeye gerekte yoktur!), çıkış resmindeki düzeltilmiş üst ve alt
sınırlar olan d ve c sayıları 0 ve 255 alınamaz. Bu durumda normalleşmiş resmindeki d ve c sayıları giriş
resmindeki a ve b değerleri ile aynı alınmalıdır. Diğer türlü orijinal resimde hiç beyaz yada siyah bölge yokken,
çıkış resminde bu bölgeler ortaya çıkmaya başlar. (dikkat! Netleştirilen resimde her iki uçta 0-255 aşmıyorsa
zaten normalleştirmeye de ihtiyaç yoktur. Sınırlardan biri 0 yada 255 aşıyorsa ve diğeri aşmıyorsa, aşmayan taraf
önceki değeri olarak alınır. Yani buradaki örnekte -30 yerine bu a değeri +10 olsaydı o zaman c değeri +10
alınmalı. Bu takdirde normalleştirme için 10-330 aralığının 10-255 aralığı olarak yapılmasını gerektirir.

2
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

Programlama (Görüntü Netleştirme)

Orjinal Resim Mean 9x9 matris ile Bulanıklaştırma

Kenar Görüntüsü Mean 9x9 matris ile netleşmiş Görüntü

3
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

Orjinal Resim Gauss (5x5) matrisi ile netleştirilmiş görüntü


Burada orjinal resim daha başlangıçta bulanık ise, kullanılan matrisin boyutu artırılmalıdır. Gauss işlemi daha
hassas bulanıklaştırma yaptığından etkisi, ince resimlerde daha iyi gözükecektir.
Not: Aşağıdaki kodlarda normalleştirme limit değerleri kullanarak yapılmadı. Basit düzeyde sınırı geçen değerler
(0-255) sınırlarına çekildi. İlgili programlama (normalleştirme) ödevlerde istenmiştir.

//NETLEŞTİRME-------------------------------
private void netlestirmeToolStripMenuItem_Click_1(object sender, EventArgs e)
{
Bitmap OrjinalResim = new Bitmap(pictureBox1.Image);

Bitmap BulanikResim = MeanFiltresi();


//Bitmap BulanikResim = GaussFiltresi();

Bitmap KenarGoruntusu = OrjianalResimdenBulanikResmiCikarma(OrjinalResim,


BulanikResim);
Bitmap NetlesmisResim = KenarGoruntusuIleOrjinalResmiBirlestir(OrjinalResim,
KenarGoruntusu);

pictureBox2.Image = NetlesmisResim;
}

//**************************************************************************************************

public Bitmap OrjianalResimdenBulanikResmiCikarma(Bitmap OrjinalResim, Bitmap


BulanikResim)
{

Color OkunanRenk1, OkunanRenk2, DonusenRenk;


Bitmap CikisResmi;

int ResimGenisligi = OrjinalResim.Width;


int ResimYuksekligi = OrjinalResim.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

4
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

int R, G, B;
double Olcekleme = 2; //Keskin kenaları daha iyi görmek için değerini artırıyoruz.
for (int x = 0; x < ResimGenisligi; x++)
{
for (int y = 0; y < ResimYuksekligi; y++)
{
OkunanRenk1 = OrjinalResim.GetPixel(x, y);
OkunanRenk2 = BulanikResim.GetPixel(x, y);

R =Convert.ToInt16(Olcekleme * Math.Abs(OkunanRenk1.R - OkunanRenk2.R));


G = Convert.ToInt16(Olcekleme * Math.Abs (OkunanRenk1.G - OkunanRenk2.G));
B = Convert.ToInt16(Olcekleme * Math.Abs (OkunanRenk1.B - OkunanRenk2.B));

//===============================================================
//Renkler sınırların dışına çıktıysa, sınır değer alınacak. (Dikkat: Normalizasyon
yapılmamıştır. )
if (R > 255) R = 255;
if (G > 255) G = 255;
if (B > 255) B = 255;

if (R < 0) R = 0;
if (G < 0) G = 0;
if (B < 0) B = 0;
//================================================================
DonusenRenk = Color.FromArgb(R, G, B);
CikisResmi.SetPixel(x, y, DonusenRenk);

}
}

return CikisResmi;
}

//**************************************************************************************************

public Bitmap KenarGoruntusuIleOrjinalResmiBirlestir(Bitmap OrjinalResim, Bitmap


KenarGoruntusu)
{

Color OkunanRenk1, OkunanRenk2, DonusenRenk;


Bitmap CikisResmi;

int ResimGenisligi = OrjinalResim.Width;


int ResimYuksekligi = OrjinalResim.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

int R, G, B;

for (int x = 0; x < ResimGenisligi; x++)


{
for (int y = 0; y < ResimYuksekligi; y++)
{
OkunanRenk1 = OrjinalResim.GetPixel(x, y);
OkunanRenk2 = KenarGoruntusu.GetPixel(x, y);

R = OkunanRenk1.R + OkunanRenk2.R;
5
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

G = OkunanRenk1.G + OkunanRenk2.G;
B = OkunanRenk1.B + OkunanRenk2.B;

//===============================================================
//Renkler sınırların dışına çıktıysa, sınır değer alınacak. //DİKKAT: Burada sınırı aşan
değerler NORMALİZASYON yaparak programlanmalıdır.
if (R > 255) R = 255;
if (G > 255) G = 255;
if (B > 255) B = 255;

if (R < 0) R = 0;
if (G < 0) G = 0;
if (B < 0) B = 0;
//================================================================

DonusenRenk = Color.FromArgb(R, G, B);


CikisResmi.SetPixel(x, y, DonusenRenk);

}
}

return CikisResmi;
}

İKİNCİ YÖNTEM (Konvolüsyon yöntemi (çekirdek matris) ile netleştirme)


Aşağıdaki çekirdek matris kullanarak da Netleştirme yapılabilir. Bu matriste temel mantık üzerinde işlem yapılan
pikselin kenarlarındaki 4 tane piksele bakar (Köşelere bakmıyor, sıfırla çarpıyor, onları toplama katmıyor) bu
piksellerin değerini aşağıya indirir, üzerinde bulunduğu pikselin değerini yukarı çıkarır. Eğer her tarafı aynı olan
bir bölgede ise sonuç değişmez. Fakat bir sınır bölgesine gelirse üzerine bastığın pikselin değerini yükseltir.
Böylece sınır olan yerler daha parlak gözükür. Bu anlatılanları kendiniz örnek piksel değerleri deneyin. Matris
değerleri ile piksel değerleri çarpılıp toplandıktan sonra matris toplamına da bölmek gerekir (yani buradaki 1/3
sayısı bunu anlatıyor).

Kullanım şekli;

6
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

private void netlestirme2ToolStripMenuItem_Click(object sender, EventArgs e)


{
Color OkunanRenk;
Bitmap GirisResmi, CikisResmi;
GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width;


int ResimYuksekligi = GirisResmi.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

int SablonBoyutu = 3;
int ElemanSayisi = SablonBoyutu * SablonBoyutu;

int x, y, i, j, toplamR, toplamG, toplamB;

int R, G, B;
int[] Matris = { 0, -2, 0, -2, 11, -2, 0,-2,0};
int MatrisToplami = 0 + -2 + 0 + -2 + 11 + -2 + 0 + -2 +0;

for (x = (SablonBoyutu - 1) / 2; x < ResimGenisligi - (SablonBoyutu - 1) / 2; x++) //Resmi


taramaya şablonun yarısı kadar dış kenarlardan içeride başlayacak ve bitirecek.
{
for (y = (SablonBoyutu - 1) / 2; y < ResimYuksekligi - (SablonBoyutu - 1) / 2; y++)
{
toplamR = 0;
toplamG = 0;
toplamB = 0;

//Şablon bölgesi (çekirdek matris) içindeki pikselleri tarıyor.


int k = 0; //matris içindeki elemanları sırayla okurken kullanılacak.
for (i = -((SablonBoyutu - 1) / 2); i <= (SablonBoyutu - 1) / 2; i++)
{
for (j = -((SablonBoyutu - 1) / 2); j <= (SablonBoyutu - 1) / 2; j++)
7
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

{
OkunanRenk = GirisResmi.GetPixel(x + i, y + j);

toplamR = toplamR + OkunanRenk.R * Matris[k];


toplamG = toplamG + OkunanRenk.G * Matris[k];
toplamB = toplamB + OkunanRenk.B * Matris[k];

k++;
}

}
R = toplamR / MatrisToplami;
G = toplamG / MatrisToplami;
B = toplamB / MatrisToplami;

//===========================================================
//Renkler sınırların dışına çıktıysa, sınır değer alınacak.
if (R > 255) R = 255;
if (G > 255) G = 255;
if (B > 255) B = 255;

if (R < 0) R = 0;
if (G < 0) G = 0;
if (B < 0) B = 0;
//===========================================================

CikisResmi.SetPixel(x, y, Color.FromArgb(R, G, B));

}
}
pictureBox2.Image = CikisResmi;

Normalleştirme Yapılmış Kodlar

Orijinal Resim
private void btnKeskinlestirmeMatris_Click(object sender, EventArgs e)
{
Color OkunanRenk;
Bitmap GirisResmi, CikisResmi;
GirisResmi = new Bitmap(pictureBox1.Image);

8
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

int ResimGenisligi = GirisResmi.Width;


int ResimYuksekligi = GirisResmi.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

int SablonBoyutu = 3;
int ElemanSayisi = SablonBoyutu * SablonBoyutu;

int x, y, i, j, toplamR, toplamG, toplamB;

int R, G, B;
int[] Matris = { 0, -2, 0, -2, 11, -2, 0, -2, 0 };
int MatrisToplami = 3;

int EnBuyukR = 0;
int EnBuyukG = 0;
int EnBuyukB = 0;

int EnKucukR = 0;
int EnKucukG = 0;
int EnKucukB = 0;

for (x = (SablonBoyutu - 1) / 2; x < ResimGenisligi - (SablonBoyutu - 1) / 2; x++)


//Resmi taramaya şablonun yarısı kadar dış kenarlardan içeride başlayacak ve bitirecek.
{
for (y = (SablonBoyutu - 1) / 2; y < ResimYuksekligi - (SablonBoyutu - 1) / 2;
y++)
{
toplamR = 0;
toplamG = 0;
toplamB = 0;

//Şablon bölgesi (çekirdek matris) içindeki pikselleri tarıyor.


int k = 0; //matris içindeki elemanları sırayla okurken kullanılacak.
for (i = -((SablonBoyutu - 1) / 2); i <= (SablonBoyutu - 1) / 2; i++)
{
for (j = -((SablonBoyutu - 1) / 2); j <= (SablonBoyutu - 1) / 2; j++)
{
OkunanRenk = GirisResmi.GetPixel(x + i, y + j);

toplamR = toplamR + OkunanRenk.R * Matris[k];


toplamG = toplamG + OkunanRenk.G * Matris[k];
toplamB = toplamB + OkunanRenk.B * Matris[k];

k++;
}

}
R = toplamR / MatrisToplami;
G = toplamG / MatrisToplami;
B = toplamB / MatrisToplami;

//===========================================================
//Renkler sınırların dışına çıktıysa, sınır değer alınacak.

if (R > 255)
{
if (EnBuyukR < R)
EnBuyukR = R;
//R = 255;

}
if (G > 255)
9
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

{
if (EnBuyukG < G)
EnBuyukG = G;
//G = 255;
}

if (B > 255)
{
if (EnBuyukB < B)
EnBuyukB = B;
//B = 255;
}

//------------------------
if (R < 0)
{
if (EnKucukR > R)
EnKucukR = R;
//R = 0;

}
if (G < 0)
{
if (EnKucukG > G)
EnKucukG = G;
//G = 0;
}

if (B < 0)
{
if (EnKucukB > B)
EnKucukB = B;
//B = 0;
}
//===========================================================

//CikisResmi.SetPixel(x, y, Color.FromArgb(R, G, B));

}
}
txtX1.Text = EnBuyukR.ToString();
txtX2.Text = EnBuyukG.ToString();
txtX3.Text = EnBuyukB.ToString();

txtY1.Text = EnKucukR.ToString();
txtY2.Text = EnKucukG.ToString();
txtY3.Text = EnKucukB.ToString();

int EnBuyuk=0, EnKucuk=0;

if (EnBuyukR > EnBuyuk)


EnBuyuk = EnBuyukR;

if (EnBuyukG > EnBuyuk)


EnBuyuk = EnBuyukG;

if (EnBuyukB > EnBuyuk)


EnBuyuk = EnBuyukB;

if (EnKucukR > EnKucuk)


EnKucuk = EnKucukR;

10
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

if (EnKucukG > EnKucuk)


EnKucuk = EnKucukG;

if (EnKucukB > EnKucuk)


EnKucuk = EnKucukB;

Bitmap NormallesmisNetResim = ResmiNormallestir(GirisResmi, SablonBoyutu,


ResimGenisligi, ResimYuksekligi, EnBuyuk, EnKucuk);

pictureBox4.Image = NormallesmisNetResim; }

public Bitmap ResmiNormallestir(Bitmap GirisResmi, int SablonBoyutu, int ResimGenisligi,


int ResimYuksekligi, int EnBuyuk, int EnKucuk)
{
int toplamR = 0;
int toplamG = 0;
int toplamB = 0;

Bitmap CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

int x, y, i, j;

int R, G, B;
int[] Matris = { 0, -2, 0, -2, 11, -2, 0, -2, 0 };
int MatrisToplami = 3;

for (x = (SablonBoyutu - 1) / 2; x < ResimGenisligi - (SablonBoyutu - 1) / 2; x++)


//Resmi taramaya şablonun yarısı kadar dış kenarlardan içeride başlayacak ve bitirecek.
{
for (y = (SablonBoyutu - 1) / 2; y < ResimYuksekligi - (SablonBoyutu - 1) / 2;
y++)
{
toplamR = 0;
toplamG = 0;
toplamB = 0;

//Şablon bölgesi (çekirdek matris) içindeki pikselleri tarıyor.


int k = 0; //matris içindeki elemanları sırayla okurken kullanılacak.
for (i = -((SablonBoyutu - 1) / 2); i <= (SablonBoyutu - 1) / 2; i++)
{
for (j = -((SablonBoyutu - 1) / 2); j <= (SablonBoyutu - 1) / 2; j++)
{
Color OkunanRenk = GirisResmi.GetPixel(x + i, y + j);

toplamR = toplamR + OkunanRenk.R * Matris[k];


toplamG = toplamG + OkunanRenk.G * Matris[k];
toplamB = toplamB + OkunanRenk.B * Matris[k];

k++;
}

}
R = toplamR / MatrisToplami;
G = toplamG / MatrisToplami;
B = toplamB / MatrisToplami;

//NORMALİZASYON------------------------
int YeniR = (255 * (R - EnKucuk)) / (EnBuyuk - EnKucuk) ;
int YeniG = (255 * (G - EnKucuk)) / (EnBuyuk - EnKucuk) ;
int YeniB = (255 * (B - EnKucuk)) / (EnBuyuk - EnKucuk) ;

11
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

if (YeniR > 255) YeniR = 255;


if (YeniG > 255) YeniG = 255;
if (YeniB > 255) YeniB = 255;

if (YeniR < 0) YeniR = 0;


if (YeniG < 0) YeniG = 0;
if (YeniB < 0) YeniB = 0;
//===========================================================

CikisResmi.SetPixel(x, y, Color.FromArgb(YeniR, YeniG, YeniB));

}
}

return CikisResmi;
}

---------------------
Ödev 1: Netleştirme işleminde resmi bulanıklaştırırken kullanılan buradaki Mean yönteminin dışında Median ve
Gauss yöntemlerini kullanarakda netleştirme yapın.

Ödev 2: Bulanık bir resmi netleştirirken daha büyük ölçekli matrislere ihtiyaç olacaktır. Böyle bir resim üzerinde
kullanılan matris boyutunu aşama aşama artırarak resmin netliğinde nasıl bir etkisi olduğunu gösterin.
Ödev 4: Yukarıdaki tüm uygulamaları Normalizasyon yaparak düzenleyin. Eğer sınırlar 0-255 dışına çıkıyorsa
ve elimizdeki resimde hiç beyaz yada siyah yoksa yani (30 – 230) gibi bir değerde ise Dışarı çıkan bu sınırlar
resmin en uç noktaları arasında normalize edilmelidir.

Ödev 5: Bir resmin üzerindeki bir bölgeyi seçmek için köşe noktalarına mouse tıklayalım. Tıkladığımız her
noktanının arasına bir çizgi çizsin. Tüm bölgeyi kapattıktan sonra, çerçevenin iç bölgesinde netleştirme
uygulasın, dış bölgesinde ise Bulanıklaştırma uygulasın. Hangi algoritma ile netleştirme, hangi ile bulanıklaştırma
uygulayacağını ise yan taraftaki menüden kişi seçebilsin. Bunun için RadioButton seçeneği kullanılabilir.
Çoklu nokta şeklinde yapamayanlar, dikdörtgen çerçeve şeklinde bölgeyi seçsinler. Bu şekilde yapanlar daha
düşük puan alır.

Ödev 6: Sharpen (netleştirme) aracı kullanarak bir resim üzerinde mouse takip eden bulur işlemi yaptırın. Bunun
için aşağıdaki adımları takip edin.
a) Mouse ın etrafında büyüklüğü ayarlanabilir belli bir bölge olsun. Örneğin açılır menüden 50 piksel
seçilirse mouuse etrafında 50x50 lik kare bir şekilde dolaşsın. Bu alanın içi netleşsin.

b) Kişi ister bu şekli Kare yada Daire olarak değiştirebilsin. Bu bölge Kare yada Daire olarak seçilebilsin.
Bu bölgenin içerisi mouse hareket ettikçe, bulanıklaşsın.

12
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

c) Ayrıca bu aracın kenarları üzerinde geçişli bir netlik oluşturmak için bir ayar daha eklensin. Örneğin
burada %100 seçilirse Dairenin merkezinden kenara kadar yavaş yavaş netlik azalarak gitsin. %50
seçilirse darenin yarısından sonra yavaş yavaş netlik azalsın.

d) Netliğin yoğunluğunun ayarlanabildiği bir seçenek daha ekleyin. Aşağıda Intensity olarak gösterilmiş.

e) Kullanılan algoritma açılır menüden, yada radyo buton listesinden seçilebilsin. Örneğin; Kenar bulma
algoritması yada Matris algoritması gibi.

Ödev 7: Aşağıdaki gibi bir resmin üzerinde belirlenen bölgenin iç kısmında netleştirme, dış kısmında
bulanıklaştırmayı otomatik olarak yapan kodları geliştirin. Bunu gerçekleştiremeyenlerde dikdörtgen şeklinde bir
çerçevenin içerisine ve dışarısına algoritmaları uygulasın. Hangi algoritmaların uygulanacağı menülerden
seçilebilsin. Ayrıca iç ve dış tarafın bulanık/net olması değiştirilebilsin. Belirlenen bölgenin kenarlarına bir çizgi
çizdirirseniz daha anlaşılır olacaktır.

13
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

GÖRÜNTÜ İŞLEME - (7.Hafta)

KENAR BULMA ALGORİTMALARI


Bu konuda bir çok algoritma olmasına rağmen en yaygın kullanılan ve etkili olan Sobel algoritması burada
anlatılacaktır.
Sobel KenarBulma Algoritması
Görüntüyü siyah beyaza çevirdikten sonra eğer kenar bulma algoritmalarını kullanmak isterseniz bir kaç seçenekten
en popüleri sobel kenar bulma filtresidir. Aşağıdaki çekirdek matrisler (konvolüsyon matrisleri) dikey, yatay ve
köşegen şeklindeki kenarları bulmak için kullanılır. Sobel operatörü bir resmin kenarlarına karşılık gelen alansal
yüksek frekans bölgelerini (keskin kenarları) ortaya çıkarır. Teorik olarak, operatör aşağıda gösterildiği gibi 3×3
konvolüsyon matrisinden oluşur.

Şekil. Sobel konvolüsyon matrisi


Bu matrisler, yatay ve dikey olarak görünen kenarlar için ayrı ayrı olacak şekilde düzenlenmiştir.
Matrisler giriş görüntüsüne birbirinden bağımsız uygulanabilir. Böylece her bir yön için pikselin değeri
ayrı ayrı ölçülmüş olur. Daha sonra çapraz duran kenarların mutlak değerini bulmak ve yönünü (açısını)
bulmak için bu değerler aşağıdaki formüllerle birleştirilebilir. Piksel mutlak değeri şu şekilde
hesaplanabilir.
|𝐺| = √𝐺𝑥 2 + 𝐺𝑦 2
Piksel değerini daha hızlı hesaplama için şu formülde kullanılabilir.
|𝐺| = |𝐺𝑥| + |𝐺𝑦|
Ortaaya çıkan kenarın yön açısı (piksel ızgarasına göre) x ve y yönlerindeki değerlerine bakarak şu şekilde bulunur.
|𝐺𝑥|
𝜃 = arctan ( )
|𝐺𝑦|
(Gx dikey çizgiyi bulur, Gy yatay çizgiyi bulur. Tan karşı kenarın komşu kenara oranı olduğu için formül bu şekilde yazıldı)

Bu durumda 0 derece yatay duran çizgileri, 90 derece ise dikey duran çizgileri gösterecektir. Eğik duran çizgilerde
diğer açıları oluşturacaktır. Burada sıfır derece çizgide alt kısım siyahtan, üst kısım beyaza doğru geçişi gösterir. 0
derecenin bir benzeri olan yine yatay duran çizgi 180 derecede ise üst kısım siyah bölgeden alt kısım beyaz bölgeye
doğru bir geçişi gösterecektir. Açılar saatin tersi yönüne göre ölçülür.
Burada Gx konvolüsyon matrisi tek başına kullanılırsa yatayda renk değişimini bulacağından, ortaya çıkan çizgileri
dikey olarak görürüz. Benzer şekilde Gy konvolüsyon matrisi de tek başına kullanılırsa aşağıdan yukarıya doğru
renk geçişini (siyahtan-beyaza) göstereceğinden ortaya çıkan çizgiler yatay olacaktır. Resim üzerindeki çizgileri
yatay yada dikey görmek yerine kendi doğal duruşlarını görmek istersek, her iki konvolüsyon matrisini yukarıda
formülü verilen hesaplama ile toplayabiliriz. Benzer şekilde yukarıda verilen karaköklü formülü de kullanabiliriz.
Eğer resim üzerinde belli açılardaki çizgileri ortaya çıkarmak istersek verilen açı formülü ile hesaplama yaparak bu
çizgileri de belirleyebiliriz.

1
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

İki matrisi aynı anda kullanmak için ve matris üzerindeki noktaları aşağıdaki şekilde temsil etmek için hesaplama
yaparak deneyelim.

Buradaki her bir çekirdek matrisin hesabı şu şekilde hesaplanır.


|𝐺𝑥| = |−𝑃1 + 𝑃3 − 2𝑃4 + 2𝑃6 − 𝑃7 + 𝑃9 |
|𝐺𝑦| = |𝑃1 + 2𝑃2 + 𝑃3 − 𝑃7 − 2𝑃8 − 𝑃9 |
Bu çekirdek matris kullanılarak pikselin sobel değeri yaklaşık formül kullanılarak şu şekilde hesaplanır:
|𝐺| = |𝐺𝑥| + |𝐺𝑦|
Diğer formül kullanıldığında ise şu şekilde olacaktır.

|𝐺| = √𝐺𝑥 2 + 𝐺𝑦 2
Burada renkli resimde renk değerleri 3 kanal olduğunda tek kanal üzerinden işlem yapmak için Gri renk değerleri
üzerinden işlem yapmak gerekir. Aşağıdaki programda Gri renk için 3 kanalın ortalması alınmıştır. Gerekirse Gri
renk formülleri de kullanılabilir (daha önceki konularda geçti).

Programlama (Sobel Filtresi)

1. Kodlama
private void mnuSobel_Click(object sender, EventArgs e)
{
Bitmap GirisResmi, CikisResmiXY, CikisResmiX, CikisResmiY;
GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width;


int ResimYuksekligi = GirisResmi.Height;

CikisResmiX = new Bitmap(ResimGenisligi, ResimYuksekligi);


CikisResmiY = new Bitmap(ResimGenisligi, ResimYuksekligi);
CikisResmiXY = new Bitmap(ResimGenisligi, ResimYuksekligi);

2
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

int SablonBoyutu = 3;
int ElemanSayisi = SablonBoyutu * SablonBoyutu;

int x, y;

Color Renk;
int P1, P2, P3, P4, P5, P6, P7, P8, P9;

for (x = (SablonBoyutu - 1) / 2; x < ResimGenisligi - (SablonBoyutu - 1) / 2; x++) //Resmi


taramaya şablonun yarısı kadar dış kenarlardan içeride başlayacak ve bitirecek.
{
for (y = (SablonBoyutu - 1) / 2; y < ResimYuksekligi - (SablonBoyutu - 1) / 2; y++)
{

Renk = GirisResmi.GetPixel(x - 1, y - 1);


P1 = (Renk.R + Renk.G + Renk.B) / 3;

Renk = GirisResmi.GetPixel(x, y - 1);


P2 = (Renk.R + Renk.G + Renk.B) / 3;

Renk = GirisResmi.GetPixel(x + 1, y - 1);


P3 = (Renk.R + Renk.G + Renk.B) / 3;

Renk = GirisResmi.GetPixel(x - 1, y);


P4 = (Renk.R + Renk.G + Renk.B) / 3;

Renk = GirisResmi.GetPixel(x, y);


P5 = (Renk.R + Renk.G + Renk.B) / 3;

Renk = GirisResmi.GetPixel(x + 1, y);


P6 = (Renk.R + Renk.G + Renk.B) / 3;

Renk = GirisResmi.GetPixel(x - 1, y + 1);


P7 = (Renk.R + Renk.G + Renk.B) / 3;

Renk = GirisResmi.GetPixel(x, y + 1);


P8 = (Renk.R + Renk.G + Renk.B) / 3;

Renk = GirisResmi.GetPixel(x + 1, y + 1);


P9 = (Renk.R + Renk.G + Renk.B) / 3;

//Hesaplamayı yapan Sobel Temsili matrisi ve formülü.


int Gx = Math.Abs(-P1 + P3 - 2 * P4 + 2 * P6 - P7 + P9); //Dikey çizgiler
int Gy = Math.Abs(P1 + 2 * P2 + P3 - P7 - 2 * P8 - P9); //Yatay Çizgiler

//if (Gx > 100)


// Gx = 255;
//else
// Gx = 0;

//if (Gy > 100)


// Gy = 255;
//else
// Gy = 0;

int Gxy = Gx + Gy;

//if (Gxy > Esikleme)


// Gxy = 255;
//else
// Gxy = 0;

//Renkler sınırların dışına çıktıysa, sınır değer alınacak. Negatif olamaz,


formüllerde mutlak değer vardır.
if (Gx > 255) Gx = 255;
if (Gy > 255) Gy = 255;
3
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

if (Gxy > 255) Gxy = 255;

//int TetaRadyan = 0;
//if (Gy != 0)
// TetaRadyan = Convert.ToInt32(Math.Atan(Gx / Gy));
//else
// TetaRadyan = Convert.ToInt32(Math.Atan(Gx));

//int TetaDerece = Convert.ToInt32((TetaRadyan * 360) / (2 * Math.PI));

//if (TetaDerece >= 0 && TetaDerece < 45)


// CikisResmiXY.SetPixel(x, y, Color.FromArgb(0, 0, 0));

//if (TetaDerece >= 45 && TetaDerece < 90)


// CikisResmiXY.SetPixel(x, y, Color.FromArgb(0, 255, 0));

//if (TetaDerece >= 90 && TetaDerece < 135)


// CikisResmiXY.SetPixel(x, y, Color.FromArgb(0, 0, 255));

//if (TetaDerece >= 135 && TetaDerece < 180)


// CikisResmiXY.SetPixel(x, y, Color.FromArgb(255, 255, 0));

CikisResmiX.SetPixel(x, y, Color.FromArgb(Gx, Gx, Gx));


CikisResmiY.SetPixel(x, y, Color.FromArgb(Gy, Gy, Gy));

CikisResmiXY.SetPixel(x, y, Color.FromArgb(Gxy, Gxy, Gxy));

}
}
pictureBox2.Image = CikisResmiXY;
pictureBox3.Image = CikisResmiX;
pictureBox4.Image = CikisResmiY;
}

2. Kodlama

private void SOBEL_KENAR2_Click(object sender, EventArgs e)


{
Color OkunanRenk;
Bitmap GirisResmi, CikisResmiX, CikisResmiY, CikisResmiXY;
GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width;


int ResimYuksekligi = GirisResmi.Height;

CikisResmiX = new Bitmap(ResimGenisligi, ResimYuksekligi);


CikisResmiY = new Bitmap(ResimGenisligi, ResimYuksekligi);
CikisResmiXY = new Bitmap(ResimGenisligi, ResimYuksekligi);

int SablonBoyutu = 3;
int ElemanSayisi = SablonBoyutu * SablonBoyutu;

int x, y, i, j;
int Gri = 0;

int[] MatrisX = { -1, 0, 1, -2, 0, 2, -1, 0, 1 };

int[] MatrisY = { 1, 2, 1, 0, 0, 0, -1, -2, -1 };

int RenkX, RenkY, RenkXY;


4
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

for (x = (SablonBoyutu - 1) / 2; x < ResimGenisligi - (SablonBoyutu - 1) / 2; x++) //Resmi


taramaya şablonun yarısı kadar dış kenarlardan içeride başlayacak ve bitirecek.
{
for (y = (SablonBoyutu - 1) / 2; y < ResimYuksekligi - (SablonBoyutu - 1) / 2; y++)
{
int toplamGriX = 0, toplamGriY = 0;

//Şablon bölgesi (çekirdek matris) içindeki pikselleri tarıyor.


int k = 0; //matris içindeki elemanları sırayla okurken kullanılacak.

for (i = -((SablonBoyutu - 1) / 2); i <= (SablonBoyutu - 1) / 2; i++)


{
for (j = -((SablonBoyutu - 1) / 2); j <= (SablonBoyutu - 1) / 2; j++)
{
OkunanRenk = GirisResmi.GetPixel(x + i, y + j);

Gri = (OkunanRenk.R + OkunanRenk.G + OkunanRenk.B) / 3;

toplamGriX = toplamGriX + Gri * MatrisX[k];

toplamGriY = toplamGriY + Gri * MatrisY[k];

k++;
}

RenkX = Math.Abs(toplamGriX);
RenkY = Math.Abs(toplamGriY);
RenkXY = Math.Abs(toplamGriX) + Math.Abs(toplamGriY);

//===========================================================
//Renkler sınırların dışına çıktıysa, sınır değer alınacak.
if (RenkX > 255) RenkX = 255;
if (RenkY > 255) RenkY = 255;
if (RenkXY > 255) RenkXY = 255;

if (RenkX < 0) RenkX = 0;


if (RenkY < 0) RenkY = 0;
if (RenkXY < 0) RenkXY = 0;

//===========================================================

CikisResmiX.SetPixel(x, y, Color.FromArgb(RenkX, RenkX, RenkX));


CikisResmiY.SetPixel(x, y, Color.FromArgb(RenkY, RenkY, RenkY));
CikisResmiXY.SetPixel(x, y, Color.FromArgb(RenkXY, RenkXY, RenkXY));
}
}
pictureBox2.Image = CikisResmiX;
pictureBox3.Image = CikisResmiY;
pictureBox4.Image = CikisResmiXY;
}

5
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

Prewitt Kenar Bulma Algoritması


Bu algoritma Sobel'e benzer ve aşağıdaki gibi biraz farklı çekirdek matris kullanır. Elde edilen sonuçlar resmin her
yerinde aynı değildir.

Prewitt Kenar Bulma algoritmasının çekirdek matrisleri


Ödev: Bu algoritmalar Gri renk için ortalama formülü kullanılmıştır. Gri tonlama için daha gelişmiş olan formülleri
kullanarak deneyin.
|𝐺| = |𝐺𝑥| + |𝐺𝑦|
Piksel değerini daha hızlı hesaplama için şu formülde kullanılabilir.

|𝐺| = √𝐺𝑥 2 + 𝐺𝑦 2
Ortaaya çıkan kenarın yön açısı (piksel ızgarasına göre) x ve y yönlerindeki değerlerine bakarak şu şekilde bulunur.
|𝐺𝑥|
𝜃 = arctan ( )
|𝐺𝑦|
Programlama (Prewitt Algoritması)

private void mnuPrewitt_Click(object sender, EventArgs e)


{
Bitmap GirisResmi, CikisResmi;
GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width;


int ResimYuksekligi = GirisResmi.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

6
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

int SablonBoyutu = 3;
int ElemanSayisi = SablonBoyutu * SablonBoyutu;

int x, y;

Color Renk;
int P1, P2, P3, P4, P5, P6, P7, P8, P9;

for (x = (SablonBoyutu - 1) / 2; x < ResimGenisligi - (SablonBoyutu - 1) / 2; x++) //Resmi


taramaya şablonun yarısı kadar dış kenarlardan içeride başlayacak ve bitirecek.
{
for (y = (SablonBoyutu - 1) / 2; y < ResimYuksekligi - (SablonBoyutu - 1) / 2; y++)
{

Renk = GirisResmi.GetPixel(x - 1, y - 1);


P1 = (Renk.R + Renk.G + Renk.B) / 3;

Renk = GirisResmi.GetPixel(x, y - 1);


P2 = (Renk.R + Renk.G + Renk.B) / 3;

Renk = GirisResmi.GetPixel(x + 1, y - 1);


P3 = (Renk.R + Renk.G + Renk.B) / 3;

Renk = GirisResmi.GetPixel(x - 1, y);


P4 = (Renk.R + Renk.G + Renk.B) / 3;

Renk = GirisResmi.GetPixel(x, y);


P5 = (Renk.R + Renk.G + Renk.B) / 3;

Renk = GirisResmi.GetPixel(x + 1, y);


P6 = (Renk.R + Renk.G + Renk.B) / 3;

Renk = GirisResmi.GetPixel(x - 1, y + 1);


P7 = (Renk.R + Renk.G + Renk.B) / 3;

Renk = GirisResmi.GetPixel(x, y + 1);


P8 = (Renk.R + Renk.G + Renk.B) / 3;

Renk = GirisResmi.GetPixel(x + 1, y + 1);


P9 = (Renk.R + Renk.G + Renk.B) / 3;

int Gx = Math.Abs(-P1 + P3 - P4 + P6 - P7 + P9); //Dikey çizgileri Bulur


int Gy = Math.Abs(P1 + P2 + P3 - P7 - P8 - P9); //Yatay Çizgileri Bulur.

int PrewittDegeri = 0;
PrewittDegeri = Gx;
PrewittDegeri = Gy;

PrewittDegeri = Gx + Gy; //1. Formül


//PrewittDegeri = Convert.ToInt16(Math.Sqrt(Gx * Gx + Gy * Gy)); //2.Formül

//Renkler sınırların dışına çıktıysa, sınır değer alınacak.


if (PrewittDegeri > 255) PrewittDegeri = 255;

//Eşikleme: Örnek olarak 100 değeri kullanıldı.


//if (PrewittDegeri > 100)
//PrewittDegeri = 255;
//else
//PrewittDegeri = 0;

CikisResmi.SetPixel(x, y, Color.FromArgb(PrewittDegeri, PrewittDegeri, PrewittDegeri));

}
}
pictureBox2.Image = CikisResmi;
7
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

Robert Cross Kenar Bulma Algoritması


Basit ve hızlı bir algoritmadır. Resim üzerindeki 2 boyutlu geçişleri ölçer. Keskin kenarları ortaya çıkarır. Gri resim
üzerinde işlem yapar. 2x2 lik matris kullandığından çok bulanık resimlerde kenarları bulamaz. Bulmuş olduğu
kenarlarıda çok ince olarak gösterir.
Aşağıdaki 2x2 lik aralarında 90 açı bulunan iki matrisle işlemleri yürütür. Kullanım olarak Sobel’e benzer.

Robert Cross konvolisyon matrisleri

Sobel’de matrislerin yönleri x ve y eksenleri yönünde idi. Burada ise Resmin ızgarasına 45 açıyla durmaktadır.
Kullanılacak formüller burada yine Gx ve Gy şeklinde gösterilmiştir fakat bu yönlerin ızgaraya 45 ve 135 derece
ile durduğunu kabul edelim.
Bunun için aşağıdaki iki formülü kullanabiliriz. İkinci formül daha hızlı çalışır.

|𝐺𝑥| = |𝑃1 − 𝑃4 |
|𝐺𝑦| = |𝑃2 − 𝑃3 |
Olmak üzere
|𝐺| = |𝐺𝑥| + |𝐺𝑦|

|𝐺| = √𝐺𝑥 2 + 𝐺𝑦 2

Formülleri kullanılabilir. Oluşan kenarın resim ızgarasına olan açısı aşağıdaki formülle bulunabilir (Dikkat formülü
deneyerek teyid edin!).
𝐺𝑦
𝜃 = arctan ( ) + 45
𝐺𝑥
Bu operatörde 4 piksel olduğundan çıkış pikselin hangisine denk geldiği belirsizdir. Aslında yarım piksellik bir
kaymadan söz edilebilir. Programlarken referans pikseli sol üst köşedeki ilk piksel alınmıştır.

8
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

Programlama (Robert Cross)

Dikkat bu uygulamada zeminle öndeki nesne arasındaki fark arttıkça kenarlar daha belirgin olmaktadır. Sebebini
yorumlamaya çalışın.
private void mnuRobertCross_Click(object sender, EventArgs e)
{
Bitmap GirisResmi, CikisResmi;
GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width;


int ResimYuksekligi = GirisResmi.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

int x, y;

Color Renk;
int P1, P2, P3, P4;

for (x = 0; x < ResimGenisligi - 1; x++) //Resmi taramaya şablonun yarısı kadar dış
kenarlardan içeride başlayacak ve bitirecek.
{
for (y = 0; y < ResimYuksekligi - 1; y++)
{

Renk = GirisResmi.GetPixel(x , y);


P1 = (Renk.R + Renk.G + Renk.B) / 3;

Renk = GirisResmi.GetPixel(x +1, y);


P2 = (Renk.R + Renk.G + Renk.B) / 3;

Renk = GirisResmi.GetPixel(x , y + 1);


P3 = (Renk.R + Renk.G + Renk.B) / 3;

Renk = GirisResmi.GetPixel(x + 1, y + 1);


P4 = (Renk.R + Renk.G + Renk.B) / 3;

int Gx = Math.Abs(P1 - P4 ); //45 derece açı ile duran çizgileri bulur.


int Gy = Math.Abs(P2 - P3); //135 derece açı ile duran çizgileri bulur.

int RobertCrossDegeri = 0;
RobertCrossDegeri = Gx;
RobertCrossDegeri = Gy;

RobertCrossDegeri = Gx + Gy; //1. Formül


//RobertCrossDegeri = Convert.ToInt16(Math.Sqrt(Gx * Gx + Gy * Gy)); //2.Formül

//Renkler sınırların dışına çıktıysa, sınır değer alınacak.


9
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

if (RobertCrossDegeri > 255) RobertCrossDegeri = 255; //Mutlak değer kullanıldığı için


negatif değerler oluşmaz.

//Eşikleme
//if (RobertCrossDegeri > 50)
// RobertCrossDegeri = 255;
//else
// RobertCrossDegeri = 0;

CikisResmi.SetPixel(x, y, Color.FromArgb(RobertCrossDegeri, RobertCrossDegeri,


RobertCrossDegeri));

}
}
pictureBox2.Image = CikisResmi;

Compass Kenar Bulma Algoritması


Compass algoritması da Sobel ve Robert Cross gibi kenarların her iki tarafındaki renk geçiş farkını kullanan
alternatif bir algoritmadır.
Bu algoritma 8 farklı yönü verecek şekilde çekirdek matrisi döndürüp en yüksek piksel değerini veren matris ile o
pikselin değerini oluşturur. Böylece kenarın ilerleme yönünü en iyi bulan matrisi deneyerek kullanmış olmaktadır.
Hangi açıdaki matrisin kullanıldığı ise o kenara ait ilerleme yönünü de vermiş olmaktadır.
Önceki algoritmalar Gx ve Gy şeklinde birbirine dik iki yönü kullanırken ve ara açıları bu iki yönün birleşimi ile
bulurken, burada 8 adet yönün kullanılması (G0, G45, G90, G135, G180, G225, G270, G315) kenarların yönünü daha hassas
olarak vermekte ve o yöndeki kenarlar daha belirgin gösterilmektedir. Önceki Gx ve Gy algoritmaları bir 360
derecelik daireyi ancak dik kenarların geçtiği kısımlarda daha belirgin gösterirken, bu algoritma 45 derecelik açılar
halinde yönleri bulduğu için daire tüm yönlerde çok daha belirgin olarak gözükecektir. Algoritmanın işlem süresi
8 adet matrisi resim üzerinde gezdirdiği için daha yavaştır. Algoritmanın matematiksel anlamış şu şekilde
gösterilebilir.
|𝐺| = max (|𝐺𝑖 |: 𝑖 = 1 𝑡𝑜 𝑛)
Burada n adet çekirdek matris için hesaplanan |Gi| değerleri içinde en büyük değeri veren matris o pikselin değerini
oluşturacaktır. Kullanılan 8 adet 45 açılarla duran matrisler şu şekilde belirlenebilir.

-1 -1 -1 -1 -1 +1 -1 +1 +1 +1 +1 +1
+1 -2 +1 -1 -2 +1 -1 -2 +1 -1 -2 +1
+1 +1 +1 +1 +1 +1 -1 +1 +1 -1 -1 +1
00 450 900 1350
+1 +1 +1 +1 +1 +1 +1 +1 -1 +1 -1 -1
+1 -2 +1 +1 -2 -1 +1 -2 -1 +1 -2 -1
-1 -1 -1 +1 -1 -1 +1 +1 -1 +1 +1 +1
1800 2250 2700 3150

Buradaki kullanılan Compass algoritması olarak kullanılan çekirdek matrisin haricinde aşağıda 2 açıdaki örnekleri
verilen algoritmalarda Compass mantığı ile kullanılabilir. Hatırlanırsa Sobel algoritması yukarıda 900 ve 00 derece
olarak kullanılmıştı. Burada verilen 1350 açı değerinde ve yukarıdaki örnek uygulamalarda nasıl yapıldığı
10
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

incelenerek diğer 8 adet açıdaki matrisleri oluşturulabilir. Bunları kendiniz oluşturunuz. Ayrıca bu örneklerden
Kirsch ve Robinson matrislerini yukarıda Sobel konusunda verildiği şekilde Gx ve Gy mantığı ile kenar bulma
işlemleri için deneyin. Sobel, Kirsch ve Robinson algoritmalarını iki eksende kullanıldığında hangisi daha iyi sonuç
vermektedir gözlemleyin.

00 1350
-1 0 1 0 1 2
Sobel -2 0 2 -1 0 1
-1 0 1 -2 -1 0

-3 -3 5 -3 5 5
Kirsch -3 0 5 -3 0 5
-3 -3 5 -3 -3 -3

-1 0 1 0 1 1
Robinson -1 0 1 -1 0 1
-1 0 1 -1 -1 0

Dikkat! bu algoritmanın programlaması Ödevlerde istendiğinden buraya konulmamıştır. Diğer programlama


örneklerine bakarak benzer şekilde programlanabilir. Fakat burada 8 tane matris olduğundan her matrisi yukarıdaki
örneklerde verilen şekilde programlamak kodları uzatır. O nedenle matris değerlerini çift boyutlu bir dizide tutarak
programlamak gerekir. Örneğin C# daki List (Listeler dizisi) kullanarak yapabilirsiniz. Yada 2 boyutlu bir dizi
tutarak da olabilir.

Aşındırma ve Genişletme Yöntemi ile Kenar Belirleme İşlemi


Bu yöntem bir sonraki notlarda Aşındırma ve Genişletme yöntemi anlatıldığından, oradaki notların sonuna
konulmuştur.
Orijinal Resim ile Bulanık Resim Farkından Kenar Belirleme İşlemi
Bu konu iki önce notlar içinde işlenmişti.
Orijinal Resim ile Netleştirilmiş Resim Farkından Kenar Belirleme İşlemi
Bu konuyu deneyerek görmeye çalışın.

11
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

Ödevler
Ödev 1: Aşağıdaki kenar bulma algoritmalarının programlarını yazınız. 5 tane farklı tarzlarda resim üzerinde en
iyi kenar bulan algoritma hangisidir (Bakış açısına göre yada aranan özelliğe göre değişebilir ama sizin kendi
yorumunuz olsun) karşılaştırın. Örneğin manzara resminde en iyi kenar bulan Sobeldir, İnsa yüzü görüntüsünde en
iyi kenar bulan Aşındırma algoritaması gibi yorumlar yapın ve bunları görsel olarak gösterin. Programlayacağınız
algoritmalar;
a) Sobel
b) Prewitt
c) Cany (bu algoritma ders notlarında yoktur. Araştırın programını kendiniz yazın. Diğerlerinin kodları
notlarda vardır. Sadece kendinize uyarlayın.)
d) Bulanıklaştırma ile kenar bulma (6 notlarda)
e) Aşındırma ile kenar bulma (8 notlarda)
Ödev 2: Çelik kontrüksiyon şeklinde aşağıdaki örneklere benzer yapıların üzerindeki çizgilerin açılarını bulup
bunları renklendirin. Bu işlem için Sobel ve Compass algoritmalarını kullanın. Hangi renklerin hangi açıyı
gösterdiğini anlayabilmek için kenarda bir grafik oluşturun yani resmin dış tarafında belirlediğiniz renkleri gösteren
ve kaç derece açıya karşılık geldiğini gösteren bir grafik olsun. (her adım 10 derece şeklinde gösterilebilir. 360
derece açıların hepsini göstersin).

Ödev 3: 6 ve 7 nolu dökümanlardaki kodları hazır olarak verilmiş olan tüm algoritmaları kendi yazdığınız
program içerisinde deneyin. Her algoritmanın en iyi sonuç verdiği örnek resimler bularak uygulamasını gösterin.
Denediğiniz her algoritmayı hangi resimlerde daha iyi sonuç verdiğinin sebebini yorumlayarak birer cümle ile
açıklayın.
Ödev 4: Compas algoritmasını farklı 3 matris türüyle deneyerek renkli çizgileri kaliteli bir şekilde programı
yazınız.

12
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

Ödev 5: Siyah zemin üzerine düz bir çizgi çizdirin. Kenar bulma algoritmalarından Sobel kullanarak (2 matris ile)
bu çizginin açısını buldurun. Açı değerini Textbox içerisine yazdırın. Aynı açı bulma işini Compass algoritması ile
(8 matris kullanarak) tekrar hesaplatın. Hangisi daha hassas hesaplamaktadır karşılaştırın.
Birde resim üzerine düz olmayan yaklaşık olarak düz giden fakat dağınık bir şekilde duran resmin içerisindeki
görüntünün açısını hesaplatın. Böylece net bir çizgide ne kadar doğru hesaplıyor bulun. Ayrıca dağınık bir çizgide
ortalama açıyı bulabiliyor mu gösterin. Örnek resimler aşağıdaki gibi olabilir.

Açı:48 Açı:35 gibi


Ödev 6: Aşağıdaki örnek programın çalışma mantığını bulun ve kullanılan matris ve yapı ortaya çıkarın. Buradaki
kodlarda değişken adlarını daha anlaşılır, kelimelerden oluşacak şekilde yeniden düzenleyin. Program içerisinde
kullanılan Listeler dizi yapısının nasıl çalıştığını anlatın. (Tek boyutlu listeler İTP 3 nolu notlarda vardır). Matris
değerleri için bu yapıyı diğer Ödevlerde de programlayarak, kullanabildiğinizi gösterin.

13
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

14
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

Yukarıdaki kodların, bizim kodlara dönüştürülmüş hali. Kodlar Compass Algoritması mantığında çalışıyor. 9*9
boyutunda 8 tane matris arasında bir pixel için en büyük değeri bulup, eşikleme yaparak o pikselin değerini
belirliyor.
// ---------------------------------- DÖNÜŞTÜRÜLEN PROGRAM BLOGU -------------------------------
-------------
private void toolStripButton2_Click(object sender, EventArgs e)
{
Bitmap GirisResmi, CikisResmi;
GirisResmi = new Bitmap(pictureBox1.Image);
int ResimGenisligi = GirisResmi.Width;
int ResimYuksekligi = GirisResmi.Height;
CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);
int x, y;
Color Renk;
int P1, P2, P3, P4, P5, P6, P7, P8, P9;
int GM, G;
//int[,] Matris = { { -3, -3, 5, -3, 0, 5, -3, -3, 5 }, { -3, 5, 5, -3, 0, 5, -3, -3, -3 },
{ 5, 5, 5, -3, 0, -3, -3, -3, -3 }, { 5, 5, -3, 5, 0, -3, -3, -3, -3 }, { 5, -3, -3, 5, 0, 3, 5,
15
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

-3, -3 }, { -3, -3, -3, 5, 0, -3, 5, 5, -3 }, { -3, -3, -3, -3, 0, -3, 5, 5, 5 }, { -3, -3, -3,
-3, 0, 5, -3, 5, 5 } }; // Kirsch Matrisi
//int[,] Matris = { { -1, -1, -1, 1, -2, 1, 1, 1, 1 }, { -1, -1, 1, -1, -2, 1, 1, 1, 1 }, {
-1, 1, 1, -1, -2, 1, -1, 1, 1 }, { 1, 1, 1, -1, -2, 1, -1, -1, 1 }, { 1, 1, 1, 1, -2, 1, -1, -1,
-1 }, { 1, 1, 1, 1, -2, -1, 1, -1, -1 }, { 1, 1, -1, 1, -2, -1, 1, 1, -1 }, { 1, -1, -1, 1, -2,
-1, 1, 1, 1 } }; // Compass Matrisi
//int[,] Matris = { { -1, 0, 1, -2, 0, 2, -1, 0, 1 }, { 0, 1, 2, -1, 0, 1, -2, -1, 0 }, { 1,
2, 1, 0, 0, 0, -1, -2, -1 }, { 2, 1, 0, 1, 0, -1, 0, -1, -2 }, { 1, 0, -1, 2, 0, -2, 1, 0, -1 },
{ 0, -1, -2, 1, 0, -1, 2, 1, 0 }, { -1, -2, -1, 0, 0, 0, 1, 2, 1 }, { -2, -1, 0, -1, 0, 1, 0, 1,
2 } }; // Sobel Matrisi;
int[,] Matris = { { -1, 0, 1, -1, 0, 1, -1, 0, 1 }, { 0, 1, 1, -1, 0, 1, -1, -1, 0 }, { 1,
1, 1, 0, 0, 0, -1, -1, -1 }, { 1, 1, 0, 1, 0, -1, 0, -1, -1 }, { 1, 0, -1, 1, 0, -1, 1, 0, -1 },
{ 0, -1, -1, 1, 0, -1, 1, 1, 0 }, {-1, -1, -1, 0, 0, 0, 1, 1, 1 }, {-1, -1, 0, -1, 0, 1, 0, 1, 1
} }; // Robinson Matrisi

for (x = 1; x < ResimGenisligi - 1; x++) //Resmi taramaya şablonun yarısı kadar dış
kenarlardan içeride başlayacak ve bitirecek.
{
for (y = 1; y < ResimYuksekligi - 1; y++)
{
Renk = GirisResmi.GetPixel(x - 1, y - 1);
P1 = (Renk.R + Renk.G + Renk.B) / 3;
Renk = GirisResmi.GetPixel(x, y - 1);
P2 = (Renk.R + Renk.G + Renk.B) / 3;
Renk = GirisResmi.GetPixel(x + 1, y - 1);
P3 = (Renk.R + Renk.G + Renk.B) / 3;
Renk = GirisResmi.GetPixel(x - 1, y);
P4 = (Renk.R + Renk.G + Renk.B) / 3;
Renk = GirisResmi.GetPixel(x, y);
P5 = (Renk.R + Renk.G + Renk.B) / 3;
Renk = GirisResmi.GetPixel(x + 1, y);
P6 = (Renk.R + Renk.G + Renk.B) / 3;
Renk = GirisResmi.GetPixel(x - 1, y + 1);
P7 = (Renk.R + Renk.G + Renk.B) / 3;
Renk = GirisResmi.GetPixel(x, y + 1);
P8 = (Renk.R + Renk.G + Renk.B) / 3;
Renk = GirisResmi.GetPixel(x + 1, y + 1);
P9 = (Renk.R + Renk.G + Renk.B) / 3;
GM = 0;

for (int i = 0; i < 8; i++)


{
G = Math.Abs(P1 * Matris[i, 0] + P2 * Matris[i, 1] + P3 * Matris[i, 2] + P4 *
Matris[i, 3] + P5 * Matris[i, 4] + P6 * Matris[i, 5] + P7 * Matris[i, 6] + P8 * Matris[i, 7] +
P9 * Matris[i, 8]);
if (G > GM) GM = G;
}
if (GM > 50)
CikisResmi.SetPixel(x, y, Color.Yellow);
else
CikisResmi.SetPixel(x, y, Color.Black);
}
}
pictureBox2.Image = CikisResmi;
}

Araştırma:
Aşağıdaki linkte verilen gelişmiş kırpma işleminde Sobel Filtresi kullanılmaktadır. Bu kırpma işleminde kullanılan
algoritmayı programlayın.
http://www.cescript.com/2015/07/icerik-tabanli-imge-olcekleme.html
16
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

Yukarıdaki enerji haritası yardımıyla farklı teknikler kullanılarak boyut indirgemesi yapılabilir. Bunlardan biri her
satırdan, o satırın en düşük enerjili piksel değerini silmektir. Ancak böyle bir silme işlemi her satırda farklı
sütunlardan pikseller sileceğinden görüntüde kaymalara/bozulmalara neden olacaktır. Kaymaları engellemek için
kullanılacak bir diğer yöntem ise her seferinde en düşük enerjili sütunu kaldırmaktır. Bu durumda ise imge
içerisinde bazı önemli nesnelerin silinebilmesi söz konusudur. Bildiride önerilen ve yukarıdaki olumsuzlukları
gideren yöntem en düşük enerjili yolu silmeyi önermektedir. Enerjili yolu (seam), görüntünün tepesinden başlayıp
tabanında son bulan ve her satırdan tek bir kez geçen eğrilere verilen isimdir. Amacımız imge boyunu azaltırken
oluşacak bilgi kaybını en aza indirmek olduğundan, olası tüm yollar içerisinden en düşük enerjili yolun bulunarak
silinmesi gerekmektedir.
Ancak arama uzayımız imgenin genişliği ile doğrusal, yüksekliği ile üstel büyüdüğünden, olası tüm yolların
bulunup en düşük enerjili eğrinin seçilmesi verimli olmamaktadır. Amacımız, bu yollar içerisinden en düşük enerjili
olanı bulmak olduğundan, dinamik programlamayı kullanarak görüntü boyu ile doğrusal karmaşıklıkta problemi
çözebiliriz. Algoritma uzun ve karmaşık olduğundan detayları bir sonraki yazıya bırakıyorum. Şimdilik bulunan bu
yolun path dizisinde saklandığını ve bu dizinin y' inci elemanı, eğrinin x koordinatını (x = path[y]) içerdiğini
bilmemiz yeterli.

******************************************************

17
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

Canny Edge Detector

Common Names: Canny edge detector


Brief Description

The Canny operator was designed to be an optimal edge detector (according to particular
criteria --- there are other detectors around that also claim to be optimal with respect to
slightly different criteria). It takes as input a gray scale image, and produces as output an
image showing the positions of tracked intensity discontinuities.

How It Works

The Canny operator works in a multi-stage process. First of all the image is smoothed by
Gaussian convolution. Then a simple 2-D first derivative operator (somewhat like
the Roberts Cross) is applied to the smoothed image to highlight regions of the image with
high first spatial derivatives. Edges give rise to ridges in the gradient magnitude image. The
algorithm then tracks along the top of these ridges and sets to zero all pixels that are not
actually on the ridge top so as to give a thin line in the output, a process known as non-
maximal suppression. The tracking process exhibits hysteresis controlled by two
thresholds: T1 and T2, with T1 > T2. Tracking can only begin at a point on a ridge higher
than T1. Tracking then continues in both directions out from that point until the height of the
ridge falls below T2. This hysteresis helps to ensure that noisy edges are not broken up into
multiple edge fragments.

Guidelines for Use

The effect of the Canny operator is determined by three parameters --- the width of the
Gaussian kernel used in the smoothing phase, and the upper and lower thresholds used by
the tracker. Increasing the width of the Gaussian kernel reduces the detector's sensitivity to
noise, at the expense of losing some of the finer detail in the image. The localization error in
the detected edges also increases slightly as the Gaussian width is increased.

Usually, the upper tracking threshold can be set quite high, and the lower threshold quite
low for good results. Setting the lower threshold too high will cause noisy edges to break up.

18
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

Setting the upper threshold too low increases the number of spurious and undesirable edge
fragments appearing in the output.

One problem with the basic Canny operator is to do with Y-junctions i.e. places where three
ridges meet in the gradient magnitude image. Such junctions can occur where an edge is
partially occluded by another object. The tracker will treat two of the ridges as a single line
segment, and the third one as a line that approaches, but doesn't quite connect to, that line
segment.

We use the image

to demonstrate the effect of the Canny operator on a natural scene.

Using a Gaussian kernel with standard deviation 1.0 and upper and lower thresholds of 255
and 1, respectively, we obtain

Most of the major edges are detected and lots of details have been picked out well --- note
that this may be too much detail for subsequent processing. The `Y-Junction effect'
mentioned above can be seen at the bottom left corner of the mirror.

The image

is obtained using the same kernel size and upper threshold, but with the lower threshold
increased to 220. The edges have become more broken up than in the previous image, which
is likely to be bad for subsequent processing. Also, the vertical edges on the wall have not
been detected, along their full length.

The image

19
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

is obtained by lowering the upper threshold to 128. The lower threshold is kept at 1 and the
Gaussian standard deviation remains at 1.0. Many more faint edges are detected along with
some short `noisy' fragments. Notice that the detail in the clown's hair is now picked out.

The image

is obtained with the same thresholds as the previous image, but the Gaussian used has a
standard deviation of 2.0. Much of the detail on the wall is no longer detected, but most of
the strong edges remain. The edges also tend to be smoother and less noisy.

Edges in artificial scenes are often sharper and less complex than those in natural scenes,
and this generally improves the performance of any edge detector.

The image

shows such an artificial scene, and

is the output from the Canny operator.

The Gaussian smoothing in the Canny edge detector fulfills two purposes: first it can be
used to control the amount of detail that appears in the edge image and second, it can be
used to suppress noise.

To demonstrate how the Canny operator performs on noisy images we use

20
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

which contains Gaussian noise with a standard deviation of 15. Neither the Roberts
Cross nor the Sobel operator are able to detect the edges of the object while removing all the
noise in the image. Applying the Canny operator using a standard deviation of 1.0 yields

All the edges have been detected and almost all of the noise has been removed. For
comparison,

is the result of applying the Sobel operator and thresholding the output at a value of 150.

We use

to demonstrate how to control the details contained in the resulting edge image. The image

is the result of applying the Canny edge detector using a standard deviation of 1.0 and an
upper and lower threshold of 255 and 1, respectively. This image contains many details;
however, for an automated recognition task we might be interested to obtain only lines that
correspond to the boundaries of the objects. If we increase the standard deviation for the
Gaussian smoothing to 1.8, the Canny operator yields

Now, the edges corresponding to the uneveness of the surface have disappeared from the
image, but some edges corresponding to changes in the surface orientation remain. Although
21
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

these edges are `weaker' than the boundaries of the objects, the resulting pixel values are the
same, due to the saturation of the image. Hence, if we scale down the image before the edge
detection, we can use the upper threshold of the edge tracker to remove the weaker edges.
The image

is the result of first scaling the image with 0.25 and then applying the Canny operator using
a standard deviation of 1.8 and an upper and lower threshold of 200 and 1, respectively. The
image shows the desired result that all the boundaries of the objects have been detected
whereas all other edges have been removed.

Although the Canny edge detector allows us the find the intensity discontinuities in an
image, it is not guaranteed that these discontinuities correspond to actual edges of the object.
This is illustrated using

We obtain

by using a standard deviation of 1.0 and an upper and lower threshold of 255 and 1,
respectively. In this case, some edges of the object do not appear in the image and many
edges in the image originate only from reflections on the object. It is a demanding task for
an automated system to interpret this image. We try to improve the edge image by
decreasing the upper threshold to 150, as can be seen in

22
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

We now obtain most of the edges of the object, but we also increase the amount of noise.
The result of further decreasing the upper threshold to 100 and increasing the standard
deviation to 2 is shown in

Common Variants

The problem with Y-junctions mentioned above can be solved by including a model of such
junctions in the ridge tracker. This will ensure that no spurious gaps are generated at these
junctions.

Interactive Experimentation

You can interactively experiment with this operator by clicking here.

Exercises

1. Adjust the parameters of the Canny operator so that you can detect the edges of

while removing all of the noise.

2. What effect does increasing the Gaussian kernel size have on the magnitudes of the
gradient maxima at edges? What change does this imply has to be made to the tracker
thresholds when the kernel size is increased?
3. It is sometimes easier to evaluate edge detector performance after thresholding the
edge detector output at some low gray scale value (e.g. 1) so that all detected edges
are marked by bright white pixels. Try this out on the third and fourth example
images of the clown mentioned above. Comment on the differences between the two
images.
4. How does the Canny operator compare with the Roberts Cross and Sobel edge
detectors in terms of speed? What do you think is the slowest stage of the process?
5. How does the Canny operator compare in terms of noise rejection and edge detection
with other operators such as the Roberts Cross and Sobel operators?
6. How does the Canny operator compare with other edge detectors on simple artificial
2-D scenes? And on more complicated natural scenes?
23
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

7. Under what situations might you choose to use the Canny operator rather than the
Roberts Cross or Sobel operators? In what situations would you definitely not choose
it?

References

R. Boyle and R. Thomas Computer Vision: A First Course, Blackwell Scientific


Publications, 1988, p 52.

J. Canny A Computational Approach to Edge Detection, IEEE Transactions on Pattern


Analysis and Machine Intelligence, Vol. 8, No. 6, Nov. 1986.

E. Davies Machine Vision: Theory, Algorithms and Practicalities, Academic Press, 1990,
Chap. 5.

R. Gonzalez and R. Woods Digital Image Processing, Addison-Wesley Publishing


Company, 1992, Chap. 4.

Local Information

Specific information about this operator may be found here.

More general advice about the local HIPR installation is available in the Local
Information introductory section.

24
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

25
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

Canny Kenar Bulma Algoritması

//CANNY ALGORITMASI ***********************************


private void toolStripButton3_Click(object sender, EventArgs e)
{
Bitmap newBitmap = (Bitmap)pictureBox1.Image;
Bitmap newBitmap1 = new Bitmap(newBitmap.Width, newBitmap.Height);
newBitmap1 = MakeGrayscale(newBitmap);
newBitmap1 = MakeSmooth(newBitmap1);
newBitmap1 = DetectEdge(newBitmap1);
pictureBox2.Image = newBitmap1;

private Bitmap MakeGrayscale(Bitmap original)


{
try
{
Color originalColor;
Color newColor;
Bitmap newBitmap = new Bitmap(original.Width, original.Height);
for (int i = 0; i < original.Width; i++)
for (int j = 0; j < original.Height; j++)
{
originalColor = original.GetPixel(i, j);
int grayScale = (int)((originalColor.R * 0.3) + (originalColor.G * 0.59) +
(originalColor.B * 0.11));
newColor = Color.FromArgb(grayScale, grayScale, grayScale);
newBitmap.SetPixel(i, j, newColor);
}
return newBitmap;
}
catch
{
throw new NotImplementedException();
}
}
private Bitmap MakeSmooth(Bitmap original)
{
int runningSum = 0;
int tempSum = 0;
int xcoord;
int ycoord;
Color newColor;
int[,] kernel = new int[5, 5] {
{1, 4, 7, 4, 1},
{4, 16, 26, 16, 4},
{7, 26, 41, 26, 7},
{4, 16, 26, 16, 4},
{1, 4, 7, 4, 1}
};
Color[,] pixels = new Color[5, 5];
Bitmap newBitmap = new Bitmap(original.Width, original.Height);
for (int i = 0; i < original.Width; i++)
for (int j = 0; j < original.Height; j++)
{
for (int x = -2; x < 3; x++)
for (int y = -2; y < 3; y++)
{
xcoord = i + x;
ycoord = j + y;
if (xcoord < 0 || xcoord > original.Width - 1)
xcoord = i - x;
if (ycoord < 0 || ycoord > original.Height - 1)

26
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

ycoord = j - y;
pixels[x + 2, y + 2] = original.GetPixel(xcoord, ycoord);
}
for (int k = 0; k < 5; k++)
for (int l = 0; l < 5; l++)
tempSum += kernel[k, l] * pixels[k, l].R;
runningSum = tempSum / 273;
newColor = Color.FromArgb(runningSum, runningSum, runningSum);
newBitmap.SetPixel(i, j, newColor);
tempSum = 0;
runningSum = 0;
}
return newBitmap;
}
private Bitmap DetectEdge(Bitmap original)
{
Bitmap newBitmap = new Bitmap(original.Width, original.Height);
int xleft;
int xright;
int ytop;
int ybot;
double gx;
double gy;
double tempAngle;
Color color1, color2;
double[,] magnitudes = new double[original.Width, original.Height];
double[,] angles = new double[original.Width, original.Height];
bool[,] isEdge = new bool[original.Width, original.Height];
double maxMag = 0;
for (int i = 0; i < original.Width; i++)
for (int j = 0; j < original.Height; j++)
{
xleft = i - 1;
xright = i + 1;
ytop = j - 1;
ybot = j + 1;
if (xleft < 0)
xleft = xright;
if (xright > original.Width - 1)
xright = xleft;
if (ytop < 0)
ytop = ybot;
if (ybot > original.Height - 1)
ybot = ytop;
color1 = original.GetPixel(xright, j);
color2 = original.GetPixel(xleft, j);
gx = (color1.R - color2.R) / 2;
color1 = original.GetPixel(i, ybot);
color2 = original.GetPixel(i, ytop);
gy = (color1.R - color2.R) / 2;
magnitudes[i, j] = Math.Abs(gx) + Math.Abs(gy);
if (magnitudes[i, j] > maxMag)
maxMag = magnitudes[i, j];
tempAngle = Math.Atan(gy / gx);
tempAngle = tempAngle * 180 / Math.PI;
if ((tempAngle >= 0 && tempAngle < 22.5) || (tempAngle > 157.5 && tempAngle <= 180)
|| (tempAngle <= 0 && tempAngle > -22.5) || (tempAngle < -157.5 && tempAngle >= -180))
tempAngle = 0.0;
else if ((tempAngle > 22.5 && tempAngle < 67.5) || (tempAngle < -22.5 && tempAngle >
-67.5))
tempAngle = 45.0;
else if ((tempAngle > 67.5 && tempAngle < 112.5) || (tempAngle < -67.5 && tempAngle
> -112.5))
tempAngle = 90.0;
else if ((tempAngle > 112.5 && tempAngle < 157.5) || (tempAngle < -112.5 &&
tempAngle > -157.5))
27
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

tempAngle = 135.0;
angles[i, j] = tempAngle;
}
for (int i = 0; i < original.Width; i++)
for (int j = 0; j < original.Height; j++)
{
if ((i - 1 < 0 || i + 1 > original.Width - 1 || j - 1 < 0 || j + 1 > original.Height
- 1))
{
isEdge[i, j] = false;
}
else if (angles[i, j] == 0.0)
{
if (magnitudes[i, j] > magnitudes[i - 1, j] && magnitudes[i, j] > magnitudes[i +
1, j])
isEdge[i, j] = true;
else
isEdge[i, j] = false;
}
else if (angles[i, j] == 90.0)
{
if (magnitudes[i, j] > magnitudes[i, j - 1] && magnitudes[i, j] > magnitudes[i,
j + 1])
isEdge[i, j] = true;
else
isEdge[i, j] = false;
}
else if (angles[i, j] == 135.0)
{
if (magnitudes[i, j] > magnitudes[i - 1, j - 1] && magnitudes[i, j] >
magnitudes[i + 1, j + 1])
isEdge[i, j] = true;
else
isEdge[i, j] = false;
}
else if (angles[i, j] == 45.0)
{
if (magnitudes[i, j] > magnitudes[i + 1, j - 1] && magnitudes[i, j] >
magnitudes[i - 1, j + 1])
isEdge[i, j] = true;
else
isEdge[i, j] = false;
}
}
double lowerThreshold = maxMag * 0.10;
for (int i = 0; i < original.Width; i++)
for (int j = 0; j < original.Height; j++)
{
if (isEdge[i, j] && magnitudes[i, j] > lowerThreshold)
{
if (angles[i, j] == 0.0)
{
if (angles[i, j] == angles[i - 1, j] || angles[i, j] == angles[i + 1, j])
{
if (magnitudes[i - 1, j] > lowerThreshold)
newBitmap.SetPixel(i - 1, j, Color.White);
else
newBitmap.SetPixel(i - 1, j, Color.Black);
if (magnitudes[i + 1, j] > lowerThreshold)
newBitmap.SetPixel(i + 1, j, Color.White);
else
newBitmap.SetPixel(i + 1, j, Color.Black);
}
}
else if (angles[i, j] == 90.0)
{
28
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

if (angles[i, j] == angles[i, j - 1] || angles[i, j] == angles[i, j + 1])


{
if (magnitudes[i, j - 1] > lowerThreshold)
newBitmap.SetPixel(i, j - 1, Color.White);
else
newBitmap.SetPixel(i, j - 1, Color.Black);
if (magnitudes[i, j + 1] > lowerThreshold)
newBitmap.SetPixel(i, j + 1, Color.White);
else
newBitmap.SetPixel(i, j + 1, Color.Black);
}
}
else if (angles[i, j] == 135.0)
{
if (angles[i, j] == angles[i - 1, j - 1] || angles[i, j] == angles[i + 1, j
+ 1])
{
if (magnitudes[i - 1, j - 1] > lowerThreshold)
newBitmap.SetPixel(i - 1, j - 1, Color.White);
else
newBitmap.SetPixel(i - 1, j - 1, Color.Black);
if (magnitudes[i + 1, j + 1] > lowerThreshold)
newBitmap.SetPixel(i + 1, j + 1, Color.White);
else
newBitmap.SetPixel(i + 1, j + 1, Color.Black);
}
}
else if (angles[i, j] == 45.0)
{
if (angles[i, j] == angles[i + 1, j - 1] || angles[i, j] == angles[i - 1, j
+ 1])
{
if (magnitudes[i + 1, j - 1] > lowerThreshold)
newBitmap.SetPixel(i + 1, j - 1, Color.White);
else
newBitmap.SetPixel(i + 1, j - 1, Color.Black);
if (magnitudes[i - 1, j + 1] > lowerThreshold)
newBitmap.SetPixel(i - 1, j + 1, Color.White);
else
newBitmap.SetPixel(i - 1, j + 1, Color.Black);
}
}
}
else
newBitmap.SetPixel(i, j, Color.Black);
}
return newBitmap;
}

Araştırma: Sobel Filtresi ile ilgili olarak aşağıda yazılmış olan kodları inceleyiniz. Yazılan bu programın notlarda
geçen anlatımdan farkı nedir? Programlama tarzından çıkarılabilecek bilgiler nelerdir?

//SOBEL FİLTRESİ******************************
private void btnSobelFiltresi_Click(object sender, EventArgs e)
{
Bitmap sobelResim = SobelUygula();
pictureBox5.Image = sobelResim;
btnResmiDonustur.Enabled = true;
}

private Bitmap SobelUygula()


{

29
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

Bitmap temp = new Bitmap(pictureBox2.Image);


BitmapData tempData = temp.LockBits(new Rectangle(0, 0, temp.Width, temp.Height),
ImageLockMode.ReadWrite,
PixelFormat.Format24bppRgb);
uzunlukX = pictureBox2.Image.Width;
uzunlukY = pictureBox2.Image.Height;

dizi = new int[uzunlukX, uzunlukY];


//progressBar1.Maximum = pictureBox2 .Image.Width * pictureBox2 .Image.Height;

unsafe
{
byte* ptrAdres = (byte*)tempData.Scan0; //bağlantı adresini al
int kalan = tempData.Stride - tempData.Width * 3;
for (int i = 0; i < tempData.Height; i++)
{
for (int j = 0; j < tempData.Width; j++)
{
dizi[j, i] = (int)((double)ptrAdres[0] * 0.11 + (double)ptrAdres[1] * 0.59 +
(double)ptrAdres[2] * 0.3); //red green blue değerleriyle gri için matrisi oluştur
ptrAdres += 3; // 3 byte ileri git. bir pixel de 3 byte lık bilgi var
if ((i % 5) == 0)//her on satırda bir göstergeyi güncelle
{
progressBar1.Value = i * pictureBox2.Image.Height + j;
Application.DoEvents();
}
}
ptrAdres += kalan;
}
}
dizi = Filitre_SobelSatir_Sutun(dizi);
int max = 0;

for (int y = 0; y < dizi.GetLength(0); y++)


{
for (int x = 0; x < dizi.GetLength(1); x++)
{
if (dizi[y, x] < 0)
{
dizi[y, x] *= -1;
}
if (dizi[y, x] > max)
{
max = dizi[y, x];
}
}
}

for (int y = 0; y < dizi.GetLength(0); y++)


{
for (int x = 0; x < dizi.GetLength(1); x++)
{
dizi[y, x] = Convert.ToInt32((dizi[y, x] * 255));
dizi[y, x] = Convert.ToInt32((dizi[y, x] / max));
}
}
progressBar1.Visible = false;
return ResmiCiz(dizi);

private Bitmap ResmiCiz(int[,] dizi)


{
Bitmap tmp = new Bitmap(uzunlukX, uzunlukY);
30
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

for (int y = 0; y < uzunlukY; y++)


{
for (int x = 0; x < uzunlukX; x++)
{
tmp.SetPixel(x, y, Color.FromArgb(dizi[x, y], dizi[x, y], dizi[x, y]));
}
}
return tmp;
}

public int[,] Filitre_SobelSatir_Sutun(int[,] resim)


{
int[,] resim1 = Filitrele(Sobel_SatirMask, resim);
int[,] resim2 = Filitrele(Sobel_SutunMask, resim);
int[,] resim3 = Filitrele(Sobel_SatirSutunMask_L, resim);
int[,] resim4 = Filitrele(Sobel_SatirSutunMask_R, resim);

int boy = resim.GetLength(0);


int en = resim.GetLength(1);

int[,] tmp = new int[boy, en];

for (int y = 1; y < boy - 1; y++)


{
for (int x = 1; x < en - 1; x++)
{
tmp[y, x] = Convert.ToInt32(Math.Sqrt((resim1[y, x]) * (resim1[y, x]) +
(resim2[y, x]) * (resim2[y, x])) +
Math.Sqrt((resim3[y, x]) * (resim3[y, x]) +
(resim4[y, x]) * (resim4[y, x])));
}
}
return tmp;
}

public int[,] Filitrele(int[,] maske, int[,] resim)


{
int boy = resim.GetLength(0);
int en = resim.GetLength(1);

int[,] temp = new int[boy, en];

for (int y = 1; y < boy - 1; y++)


{
for (int x = 1; x < en - 1; x++)
{
temp[y, x] = ((maske[0, 0] * resim[y - 1, x - 1]) + (maske[0, 1] * resim[y - 1, x])
+ (maske[0, 2] * resim[y - 1, x + 1]) +
(maske[1, 0] * resim[y, x - 1]) + (maske[1, 1] * resim[y, x]) +
(maske[1, 2] * resim[y, x + 1]) +
(maske[2, 0] * resim[y + 1, x - 1]) + (maske[2, 1] * resim[y + 1,
x]) + (maske[2, 2] * resim[y + 1, x + 1]));
}
}
return temp;
}

Ödev 1: Kenar bulma algoritması ile bir cismin kenarlarını tespit edin. Bu kapalı alan içinde kalan yüzeyin ağırlık
merkezini bulan algoritmayı geliştirin.

Ödev 2: Aynı yöntemi kullanarak Cismin Alanı kaç piksel kare olduğunu tespit edin.

31
Karabük Üniversitesi, Mühendislik Fakültesi.......................................................................................................www.IbrahimCayiroglu.c om

Ödev 3: Aynı yöntemle cimsin çevre uzunluğunun kaç piksel oldunu bulun

Ödev 4: Yukarıdaki ödevleri piksel uzunluğu ile mm yi ölçekleyerek yani görüntü içerisinde her mm nin kaç piksel
ile ifade edildiğini bularak tüm hesaplamaları mm cinsinden bulun. Bunun için görüntü alanına bir cetvel yada
kumpas koyarak ölçeği oradan çıkarabilirsiniz. Yada Ölçüsü bilinen bir şekil koyarak onunla kıyaslama yaparak
program kendisi otomatik bulsun.

32
Karabük Üniversitesi, Mühendislik Fakültesi............................................................................................... ........www.IbrahimCayiroglu.com

GÖRÜNTÜ İŞLEME - (8.Hafta)

RESMİ AŞINDIRMA/GENİŞLETME ve ALT BÖLGELERE AYIRMA


ALAN AŞINDIRMA YADA GENİŞLETME (Morfolojik İşlemler/Biçimsel İşlemler)
Bir resim üzerindeki alanları bulmak bazen bölgeleri net olarak çıkarmak için yetmez. Birbirine çok ince bir çizgi
ile bağlı olan alanlar aslında farklı alanlar olabilir. Yada bir bölge üzerinde çok sayıda hatalı duran küçük alanlar
aslında bölgenin içerisinde olabilir. Gürültülü bir görüntü olabilir. Böyle bir durumda çok ince bağlanmış
bölgeleri birinden ayırmak istiyorsak o ince çizgileri eritmek, kaybetmek isteyebiliriz. Yada alan içindeki çok
küçük kısımları kapatıp büyük olan alana dahil etmek isteyebiliriz. Bu tür bir uygulama için Morfolojik işlemler
dediğimiz, şekil yada biçimi değişmek için yaptığımız uygulamalara ihtiyaç vardır.
Morfolojik görüntü işleme teknikleri, şekillerin biçimsel yapısı ile ilgilenerek nesneleri ayırt etmemize ve
gruplayabilmemize olanak sağlar. Yöntem gri seviye görüntüler üzerinde de çalışsa da genellikle siyah-beyaz
(ikili) görüntüler üzerinde kullanılır. Morfolojik filtreler genelde iki temel işlemden türetilmiştir. Bunlar erosion
(aşındırma, daraltma) ve dilation (genişletme) işlemleridir. Aşındırma ikili bir görüntüde bulunan nesnelerin
boyutunu seçilen yapısal elemente bağlı olarak küçültürken, genişletme nesnenin alanını artırır.
Bu işlemlerden aşındırma işlemi birbirine ince bir gürültü ile bağlanmış iki veya daha fazla nesneyi birbirinden
ayırmak için kullanılırken, genişletme işlemi ise aynı nesnenin bir gürültü ile ince bir şekilde bölünerek ayrı iki
nesne gibi görünmesini engellemek için kullanılır. Aslında bu iki işlem birbirinin tersidir. Resim üzerindeki
alanlarda bu işlemlerden birini uyguladığımızda komşu diğer alanlar zıttı olan işleme tabi tutulmuş olur. Yani
aşındırma uygularken komşu alanda genişletme uygulanmış olur.
İşlemin nasıl yapıldığını anlamak için aşağıdaki resimler üzerinde anlatalım. Bunun için resmin üzerinde +
şeklinde 5 tane pikselden oluşan bir şablon gezdireceğiz. Ortadaki 5. piksel, resim üzerinde işlem yaptığımız
piksele karşılık gelir.
• Bu 5 tane piksel resim üzerine konulduktan sonra, beş pikselin tamamı beyaz alanlara basıyorsa, yani
5 pikselin hepsinin karşılığı olan beyaz ise o zaman üzerinde işlem yapılan piksel beyaz olarak
işaretlenir.
• Eğer bu 5 pikselden herhangi biri siyah bir pikselin üzerine denk geldiyse o zaman ortadaki pikselin
değeri siyah yapılır.
Dikkat edilirse bu işlem ile siyah bölge genişletilirken (dilation), beyaz bölge aşındırılmış (erosion) olmaktadır.
Bu işlemde piksellerin tamamının beyazla örtüşmesi Fit, herhangi birinin örtüşmesi ise Hit olarak literatürde
adlandırılır. Özetle bu işlem (aşındırma ve genişletme işlemi) bölger üzerinde Açma ve Kapama işlemlerine
neden olacaktır. Tekrar anlatacak olursak şu sonuçlara ulaşılır.
Açma İşlemi(Opening): Burada anlatılan yöntem kullanılarak görüntü üzerinde küçük parçaların kaybolması
sağlanabilir. Bu işlem için önce Aşındırma (erosion) uygulanırsa görüntünün kenarlarındaki çok küçük parçalar
kaybolacaktır. Ama bu durumda genel alan küçülmüş olur. Küçülen alanı tekrar eski haline getirmek için
Genişletme (dilation) işlemi uygulanır. Böylece resmin genelindeki birinci seviye küçük parçalar kaybolmuş olur.
Yeterli olmaz ise bir kez daha aynı işlem uygulanır. Bu işlem gürültü nedeniyle birbirine bitişik olarak bulunan
alanları ayrıştırmak için uygun olacaktır.
Kapama İşlemi(Closing): Açma işleminde uygulanan adımların tersten uygulanmasıdır. Böylece görüntü
içerisindeki ayrık parçalar birbirine yaklaşır. Önce genişletme işlemi uygulanarak birbirine yakın alanlar
birleştirilmiş olur. Aradaki gürültülü alanlar kaybolmuş olur. Fakat bu genel alanın büyümesine yol açar. Eski
haline getirmek için tekrar aşındırma uygulanırsa kenarlardan kırpılacaktır. Ortadaki kapanan bölgeler büyük
alana birleştiği için tekrar ayrılamayacaktır.

1
Karabük Üniversitesi, Mühendislik Fakültesi............................................................................................... ........www.IbrahimCayiroglu.com

Dikkat. Burada gezici şablonun bir satırlık hareketi gösterilmiştir. Her satır bittiğinde bir alt satıra inilmeli. Bir alt
satıra indiğinde piksellerin yeni değerleri üzerinden işlem yaparsa siyah bölge gittikçe genişler ve her taraf siyah
olur. Bu olayın olmaması için daima piksellerin eski değerleri üzerinden işlem yapılmalıdır.

Aşındırma ve Genişletme Yöntemi ile Kenar Belirleme İşlemi


Bu yöntemlerden herhangi biri kullanılarak bir resmin üzerindeki kenarlar ortaya çıkarılabilir. Bunun için resmi
önce siyah-beyaz iki renge dönüştürürsek (burada eşik belirlenerek ne kadarı siyah, ne kadarının beyaz olacağına
karar verilir) Ardından örneğin beyaz kısımlara genişletme uygulanırsa beyaz alan dışarıya doğru 1 piksellik
genişlemiş olacaktır. Ardından elde edilen bu resim, bir önceki orjinal siyah-beyaz resimden çıkarılırsa, aynı renk
değerine sahip noktalar 0 sonucunu verirken, farklı renk değerine sahip pikseller o anki değerini verecektir. En
dış hattaki genişleyen pikseller ancak farklı renk oluşturacağından bu kısımlar beyaz olarak ortaya çıkacaktır.
Burada dikkat edilirse renkli resim üzerinde cismin alanlarının kenarı bulunmuyor. Sadece siyah beyaza
dönüşmüş resmin kenarları bulunuyor. Bu nedenle resim üzerindeki her bölgenin kenarını bulamaz. Renkli
resimdeki tüm kontraslı kenarlar bulunması isteniyor, daha önceki notlarda anlatılan Sobel gibi farklı
algoritmaları kullanmak gerekir.
Bu uygulamada genişletme işlemi uygulanırken, 1 piksellik genişletme yapılırsa ortaya çıkan kenar görüntüsüde 1
piksellik olacaktır. Eğer genişletme 2 piksel olarak yapılırsa bu sefer kenarlar daha belirgin 2 piksel olarak
gözükecektir. Yada 1 piksellik kenar görüntüsüne sahip resim, genişletme işlemine tabi tutulursa, kenarlar daha
kalın olarak gözükecektir.
Peki bu uygulamada kenar bulmak için Genişletme yerine Aşındırma uyugulansaydı ne olurdu? Bu durumda tek
değişen ortaya çıkan kenarlar orjinal kenarın iç kısmında oluşurdu. Genişletme işleminde kenarlar alının dışında
oluşur. Yani kenar görüntüsü orjinal görüntüden bir 1 piksel daha büyüktür.

2
Karabük Üniversitesi, Mühendislik Fakültesi............................................................................................... ........www.IbrahimCayiroglu.com

Programlama

Orijinal Resim Gri Resim

128 Eşikle oluşturulmuş Siyah Beyaz Resim Genişletme uygulanmış Resim.


Genişleyen kenarlar kırmızı gösterilmiş.

3
Karabük Üniversitesi, Mühendislik Fakültesi............................................................................................... ........www.IbrahimCayiroglu.com

Orijinal siyah beyaz resimle genişleyen resmi çıkardığımızda sınırları bulmuş oluruz. İkinci resim Orijinal siyah
beyaz resme Sobel uygulandığında elde edilen görüntüdür. Genişletme ve Çıkarma yöntemi ile kenarlar daha net
olarak elde edilmiştir.

Orijinal renkli resme Sobel uyguladığında elde edilen görüntü.


private void BEYAZLARI_GENİŞLET_Click(object sender, EventArgs e)
{
Color KendiRengi, KomsuRengi;
Bitmap GirisResmi, CikisResmi;

GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width;


int ResimYuksekligi = GirisResmi.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

int x, y, i, j;

int SablonBoyutu = 3;
int ElemanSayisi = SablonBoyutu * SablonBoyutu;

//***********************BEYAZLARI ERİTECEK- SİYAHLARI GENİŞLETECEK


for (x = (SablonBoyutu - 1) / 2; x < ResimGenisligi - (SablonBoyutu - 1) / 2; x++) //Resmi
taramaya şablonun yarısı kadar dış kenarlardan içeride başlayacak ve bitirecek.
{
for (y = (SablonBoyutu - 1) / 2; y < ResimYuksekligi - (SablonBoyutu - 1) / 2; y++)
{
bool KomsulardaBeyazRenkVar = false;
KendiRengi = GirisResmi.GetPixel(x, y);

if (KendiRengi.R < 128) //Kendi rengi siyahsa, komşuları tara beyaz bulabilecek
misin?
{

for (i = -((SablonBoyutu - 1) / 2); i <= (SablonBoyutu - 1) / 2; i++)


{
for (j = -((SablonBoyutu - 1) / 2); j <= (SablonBoyutu - 1) / 2; j++)
{
KomsuRengi = GirisResmi.GetPixel(x + i, y + j);

if (KomsuRengi.R > 128) //Komsu rengi beyaz ise


KomsulardaBeyazRenkVar = true;

}
4
Karabük Üniversitesi, Mühendislik Fakültesi............................................................................................... ........www.IbrahimCayiroglu.com

if (KomsulardaBeyazRenkVar == true) //Madem komsularda beyaz renk var, o zaman


kendi rengini de beyaz yap.
{
CikisResmi.SetPixel(x, y, Color.FromArgb(255, 255, 255));
//CikisResmi.SetPixel(x, y, Color.FromArgb(255, 0, 0));
}
else //komşularda siyah yok ise kendi rengi yine aynı beyaz kalmalı.
{
CikisResmi.SetPixel(x, y, Color.FromArgb(0, 0, 0));

}
}
else //Kendi rengi beyaz ise beyaz kal..
{
CikisResmi.SetPixel(x, y, Color.FromArgb(255, 255, 255));

}
}

pictureBox2.Image = CikisResmi;

private void SİYAHLARI_GENİŞLET_Click(object sender, EventArgs e)


{
Color KendiRengi, KomsuRengi;
Bitmap GirisResmi, CikisResmi;

GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width;


int ResimYuksekligi = GirisResmi.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

int x, y, i, j;

int SablonBoyutu = 3;
int ElemanSayisi = SablonBoyutu * SablonBoyutu;

//***********************BEYAZLARI ERİTECEK- SİYAHLARI GENİŞLETECEK


for (x = (SablonBoyutu - 1) / 2; x < ResimGenisligi - (SablonBoyutu - 1) / 2; x++) //Resmi
taramaya şablonun yarısı kadar dış kenarlardan içeride başlayacak ve bitirecek.
{
for (y = (SablonBoyutu - 1) / 2; y < ResimYuksekligi - (SablonBoyutu - 1) / 2; y++)
{
bool KomsulardaSiyahVar = false;
KendiRengi = GirisResmi.GetPixel(x, y);

if (KendiRengi.R > 128)


{

for (i = -((SablonBoyutu - 1) / 2); i <= (SablonBoyutu - 1) / 2; i++)


{
for (j = -((SablonBoyutu - 1) / 2); j <= (SablonBoyutu - 1) / 2; j++)
{
KomsuRengi = GirisResmi.GetPixel(x + i, y + j);

if (KomsuRengi.R < 128)


KomsulardaSiyahVar = true;

5
Karabük Üniversitesi, Mühendislik Fakültesi............................................................................................... ........www.IbrahimCayiroglu.com

if (KomsulardaSiyahVar == true) //Madem komsularda beyaz renk var, o zaman kendi


rengini de beyaz yap.
{
CikisResmi.SetPixel(x, y, Color.FromArgb(0, 0, 0));
//CikisResmi.SetPixel(x, y, Color.FromArgb(255, 0, 0));
}
else //komşularda siyah yok ise kendi rengi yine aynı beyaz kalmalı.
{
CikisResmi.SetPixel(x, y, Color.FromArgb(255, 255, 255));

}
}
else //Kendi rengi beyaz ise beyaz kal..
{
CikisResmi.SetPixel(x, y, Color.FromArgb(0, 0, 0));

}
}

pictureBox2.Image = CikisResmi;
}

public Bitmap OrjinalResimdenGenislemisResmiCikar(Bitmap SiyahBeyazResim, Bitmap


GenislemisResim)
{

Bitmap CikisResmi;

int ResimGenisligi = SiyahBeyazResim.Width;


int ResimYuksekligi = SiyahBeyazResim.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

int x, y;

int Fark;

for (x =0; x < ResimGenisligi; x++) //Resmi taramaya şablonun yarısı kadar dış kenarlardan
içeride başlayacak ve bitirecek.
{
for (y = 0; y < ResimYuksekligi; y++)
{
Color OrjinalRenk = SiyahBeyazResim.GetPixel(x, y);
Color GenislemisResimRenk = GenislemisResim.GetPixel(x, y);

int OrjinalGri = (OrjinalRenk.R + OrjinalRenk.G + OrjinalRenk.B) / 3;


int GenislemisGri = (GenislemisResimRenk.R + GenislemisResimRenk.G +
GenislemisResimRenk.B) / 3;

Fark = Math.Abs(OrjinalGri - GenislemisGri);

CikisResmi.SetPixel(x, y, Color.FromArgb(Fark, Fark, Fark));


}
}

return CikisResmi;
}

6
Karabük Üniversitesi, Mühendislik Fakültesi............................................................................................... ........www.IbrahimCayiroglu.com

RESMİN İÇİNDEKİ ALANLARI BULMA


(Bağlantılı Bileşen Etiketleme) (Çoklu Geçiş Metodu)(Connected Components Labeling)
Bir resim üzerindeki aynı renk koduna sahip bölgelerin ortaya çıkarılması, birbirinden ayrılması o resim
üzerindeki alan özelliklerini tespit edilmesini sağlayacaktır. Tespit edilen her bölge, yada grup aynı renge
boyanabilir yada aynı numara ile etiketlenebilir. Böylece sonraki işlemlerde bu alanlar üzerinde gerekli
tanımlama işlemleri yapılabilir.
Bu amaçla "bağlantılı bileşen etiketleme" algoritması kullanılabilir. Bu algoritmanın bir çok farklı yöntemleri
olsa da burada kolay olan Çift-Geçiş metodu incelenecektir. Bu amaçla komşuluk ilişkisi olarak ele alınan
pikselin çevresindeki 8 piksel (3x3 matris şeklinde) yada 4 piksel (+ şeklinde, köşeler yok) incelemeye alınabilir.
Siyah ve beyaz iki renkten oluşan bir resim için algoritmayı şu şekilde tanımlayabiliriz.
--------------- 000 --------------
Tüm beyaz piksellere atanan değerler değişmeyene kadar dön
{
Eğer ele alınan piksel rengi (ortadaki piksel) beyaz ise burayı işlet (siyah ise pas geçecektir)
{
- Ortadaki pikselin tüm komuşlarına bak (8 adet yada 4 adet komşu, hangisi uygulanıyorsa)
- Tüm komşular siyah ise ve bu piksele etiket atanmamışsa bu yeni bir pikseldir. Piksele yeni bir etiket
ata. Diğer piksele geç. (aşağıdaki resimde bu örnek gözükmüyor).
- Komşulardan en az biri beyaz ise ve etiket atanmamışsa, o zaman kendine yeni bir etiket numarası
ata. (Aşağıdaki ilk resimde sarının etrafında 4 tane beyaz var ve hiç birinde etiket yok. O zaman ilk
numara olan 1 bir sonraki resimde atanmış oldu)
- Kendisi etiketsiz ve komşulardan en az biri etiketli ise (etiketli olanlar beyaz renklidir) bu yeni
piksele (ortadaki piksele) çevredeki en küçük değere sahip etiketi ata. (Aşağıdaki 2. resimde sarının
etrafında numara olan en küçük hücre 1 dir. O zaman en küçük olan bu değer kendisine atanacaktır.
3. Resimde bu göserilmiş oluyor.
- Kendisi etiketli ise ve komşuları da etiketli ise, kendisine en düşük komşunun değerini ata. Yani her
durumda komşuların en küçük değeri atanıyor. Kendisinin etiketli olabilmesi için resim bir defa
baştan sona taranmış olmalı (ilk geçiş gerçekleşmiş olmalı). Aşağıdaki resimler ilk geçişi
göstermektedir (sarının her seferinde ortası boş).
}
}
--------------- 000 --------------

7
Karabük Üniversitesi, Mühendislik Fakültesi............................................................................................... ........www.IbrahimCayiroglu.com

Burada verilen örnekler ilk geçişi göstermektedir. Dikkat edilirse üst sağ köşedeki piksellerde 1 ve 2 rakamları
komşuluk olarak yanyana gelmiştir. İkinci bir geçiş daha yapılacak olursa buradaki piksellerden 2 rakamları 1
rakamına dönüşecektir ve böylece üstteki birbirine komşu pikseller aynı numara ile etiketlenmiş olacaktır. Aynı
numaralı etiketler farklı renklere boyanabilir yada etiketleme yapmak yerine yeni renk kodu atanabilir. Böylece
işlem sonunda bölgeler birbirinden net olarak ayrılmış olacaktır.

8
Karabük Üniversitesi, Mühendislik Fakültesi............................................................................................... ........www.IbrahimCayiroglu.com

Program (Bağımsız alanları tespit etme)

a) Orjinal resim b)Beyaz kenarlar ortaya çıksın diye negatifi alındı

c) 200 eşik değeri ile siyah beyaz yapıldı d) Her yaprak alanı ayrı ayrı tespit edildi.
private void BOLGE_BULMA_Click(object sender, EventArgs e)
{

Bitmap GirisResmi, CikisResmi;

int KomsularinEnKucukEtiketDegeri = 0;

GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width;


int ResimYuksekligi = GirisResmi.Height;
CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

int PikselSayisi = ResimGenisligi * ResimYuksekligi;

9
Karabük Üniversitesi, Mühendislik Fakültesi............................................................................................... ........www.IbrahimCayiroglu.com

Bitmap SiyahBeyazResim = ResmiGriTonaDonusturEsiklemeYap(GirisResmi);

GirisResmi = SiyahBeyazResim;
pictureBox2.Image = SiyahBeyazResim;

int x, y, i, j, EtiketNo = 0;

int[,] EtiketNumarasi = new int[ResimGenisligi, ResimYuksekligi]; //Resmin her pikselinin


etiket numarası tutulacak.

//Tüm piksellerin Etiket numarasını başlangıçta 0 olarak atayacak. Siyah ve beyaz farketmez.
Zaten ileride beyaz olanlara numara verilecek.
for (x = 0; x < ResimGenisligi; x++)
{
for (y = 0; y < ResimYuksekligi; y++)
{
EtiketNumarasi[x, y] = 0;
}
}

int IlkDeger = 0, SonDeger = 0;


bool DegisimVar = false; //Etiket numaralarında değişim olmayana kadar dönmesi için sonsuz
döngüyü kontrol edecek.

int Esikleme = 0;
try
{
Esikleme = Convert.ToInt16(textBox1.Text);
}
catch
{
Esikleme = 128;
}

do //etiket numaralarında değişim kalmayana kadar dönecek.


{
DegisimVar = false;
//------------------------- Resmi tarıyor ----------------------------
for (y = 1; y < ResimYuksekligi - 1; y++) //Resmin 1 piksel içerisinden başlayıp,
bitirecek. Çünkü çekirdek şablon en dış kenardan başlamalı.
{
for (x = 1; x < ResimGenisligi - 1; x++)
{
//Resim siyah beyaz olduğu için tek kanala bakmak yeterli olacak. Sıradaki
piksel beyaz ise işlem yap. Beyaz olduğu 255 yerine 128 kullanarak yapıldı.
if (GirisResmi.GetPixel(x, y).R > Esikleme)
{

//işlem öncesi ele alınan pikselin etiket değerini okuyacak. İşlemler


bittikten sonra bu değer değişirse, sonsuz döngü için işlem yapılmış demektir.
IlkDeger = EtiketNumarasi[x, y];

//Komşular arasında en küçük etiket numarasını bulacak.


KomsularinEnKucukEtiketDegeri = 0;

for (j = -1; j <= 1; j++) //Çekirdek şablon 3x3 lük bir matris. Dolayısı ile
x,y nin -1 den başlayıp +1 ne kadar yer kaplar.
{
for (i = -1; i <= 1; i++)
{

if (EtiketNumarasi[x + i, y + j] != 0 &&
KomsularinEnKucukEtiketDegeri == 0) //hücrenin etiketi varsa ve daha hiç en küçük atanmadı ise
ilk okuduğu bu değeri en küçük olarak atayacak.
{
10
Karabük Üniversitesi, Mühendislik Fakültesi............................................................................................... ........www.IbrahimCayiroglu.com

KomsularinEnKucukEtiketDegeri = EtiketNumarasi[x + i, y + j];


}
else if (EtiketNumarasi[x + i, y + j] <
KomsularinEnKucukEtiketDegeri && EtiketNumarasi[x + i, y + j] != 0 &&
KomsularinEnKucukEtiketDegeri != 0) //En küçük değer ve okunan hücreye etiket atanmışsa,
içindeki değer en küçük değerden küçük ise o zaman en küçük o hücrenin değeri olmalıdır.
{
KomsularinEnKucukEtiketDegeri = EtiketNumarasi[x + i, y + j];
}
}
}

if (KomsularinEnKucukEtiketDegeri != 0) //Beyaz komşu buldu ve içlerinde en


küçük etiket değerine sahip numara da var. O zaman orta piksele o numarayı ata.
{
EtiketNumarasi[x, y] = KomsularinEnKucukEtiketDegeri;
}
else if (KomsularinEnKucukEtiketDegeri == 0) //Komşuların hiç birinde etiket
numarası yoksa o zaman yeni bir numara ata
{
EtiketNo = EtiketNo + 1;
EtiketNumarasi[x, y] = EtiketNo;
}

SonDeger = EtiketNumarasi[x, y]; //İşlem öncesi ve işlem sonrası değerler


aynı ise ve butün piksellerde hep aynı olursa artık değişim yok demektir.

if (IlkDeger != SonDeger)
DegisimVar = true;

}
}
} while (DegisimVar == true); // Etiket numarlarında değişik kalmayana kadar dön.

// Etiket değerine bağlı resmi renklendirecek-----------------------


// Pikseller üzerine yazılmış numaraları diziye atıyor. Dizi boyutu resimdeki piksel
sayısınca oluyor.
int[] DiziEtiket = new int[PikselSayisi];

i = 0;
for (x = 1; x < ResimGenisligi - 1; x++)
{
for (y = 1; y < ResimYuksekligi - 1; y++)
{
i++;
DiziEtiket[i] = EtiketNumarasi[x, y];
}
}

//Dizideki etiket numaralarını sıralıyor. Hazır fonksiyon kullanıyor.


Array.Sort(DiziEtiket);

//Tekrar eden etiket numaraarını çıkarıyor. Hazır fonksiyon kullanıyor. Tekil numaraları
diziye atıyor.
int[] TekrarsizEtiketNumaralari = DiziEtiket.Distinct().ToArray();

//DİKKAT BURADA RenkDizisi ihtiyaç değil gibi. Renk adedi direk Tekrarsız numaralardan
alınabilir.
int[] RenkDizisi = new int[TekrarsizEtiketNumaralari.Length]; //Tekil numaralar aynı boyutta
renk dizisini oluşturuyor.

for (j = 0; j < TekrarsizEtiketNumaralari.Length; j++)


{
11
Karabük Üniversitesi, Mühendislik Fakültesi............................................................................................... ........www.IbrahimCayiroglu.com

RenkDizisi[j] = TekrarsizEtiketNumaralari[j]; //sıradaki ilk renge, ait olacağı etiketin


kaç numara olacağını atıyor.
}

int RenkSayisi = RenkDizisi.Length; //kaç tane numara varsa o kadar renk var demektir.

Color[] Renkler = new Color[RenkSayisi];


Random Rastgele = new Random();
int Kirmizi, Yesil, Mavi;

for (int r = 0; r < RenkSayisi; r++) //sonraki renkler.


{
Kirmizi = Rastgele.Next(5, 25) * 10; //Açık renkler elde etmek ve 10 katları şeklinde
olmasını sağlıyor. yani 150-250 arasındaki sayıları atıyor.
Yesil = Rastgele.Next(5, 25) * 10;
Mavi = Rastgele.Next(5, 25) * 10;

Renkler[r] = Color.FromArgb(Kirmizi, Yesil, Mavi); //Renkler dizisi Color tipinde


renkleri tutan bir dizidir.
}

//Color[] Renkler= { Color.Black, Color.Blue, Color.Red, Color.Orange, Color.LightPink,


Color.LightYellow, Color.LimeGreen, Color.MediumPurple, Color.Olive, Color.Magenta,
Color.Maroon, Color.AliceBlue, Color.AntiqueWhite, Color.Aqua, Color.LightBlue, Color.Azure,
Color.White };

for (x = 1; x < ResimGenisligi - 1; x++) //Resmin 1 piksel içerisinden başlayıp, bitirecek.


Çünkü çekirdek şablon en dış kenardan başlamalı.
{
for (y = 1; y < ResimYuksekligi - 1; y++)
{
int RenkSiraNo = Array.IndexOf(RenkDizisi, EtiketNumarasi[x, y]); //Dikkat: önemli
bir komut. Dizinin değerinden sıra numarasını alıyor. int[] array = { 2, 3, 5, 7, 11, 13 }; int
index = Array.IndexOf(array, 11); // returns 4

if (GirisResmi.GetPixel(x, y).R < Esikleme) //Eğer bu pikselin rengi siyah ise aynı
pikselin CikisResmi resmide siyah yapılacak.
{
CikisResmi.SetPixel(x, y, Color.Black);
}
else
{
CikisResmi.SetPixel(x, y, Renkler[RenkSiraNo]);
}
}
}
pictureBox3.Image = CikisResmi;
txtKirmizi.Text = RenkSayisi.ToString();
}

public Bitmap ResmiGriTonaDonusturEsiklemeYap(Bitmap GirisResmi)


{
Color OkunanRenk, DonusenRenk;

Bitmap CikisResmi;

int ResimGenisligi = GirisResmi.Width; //GirisResmi global tanımlandı. İçerisine görüntü


yüklendi.
int ResimYuksekligi = GirisResmi.Height;
CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi); //Cikis resmini oluşturuyor.
Boyutları giriş resmi ile aynı olur. Tanımlaması globalde yapıldı.

int i = 0, j = 0; //Çıkış resminin x ve y si olacak.


12
Karabük Üniversitesi, Mühendislik Fakültesi............................................................................................... ........www.IbrahimCayiroglu.com

int R = 0, G = 0, B = 0;

for (int x = 0; x < ResimGenisligi; x++)


{
for (int y = 0; y < ResimYuksekligi; y++)
{
OkunanRenk = GirisResmi.GetPixel(x, y);

R = OkunanRenk.R;
G = OkunanRenk.G;
B = OkunanRenk.B;

int Gri = Convert.ToInt16(R * 0.3 + G * 0.6 + B * 0.1);

int Esikleme = 0;
try
{
Esikleme = Convert.ToInt16(textBox1.Text);
}
catch
{
Esikleme = 128;
}

//Esikleme kısmı
if (Gri > Esikleme)
Gri = 255;
else
Gri = 0;

DonusenRenk = Color.FromArgb(Gri, Gri, Gri);


CikisResmi.SetPixel(x, y, DonusenRenk);
}
}
return CikisResmi;
}

-------------- 000--------------
Ödev1: Bir bant üzerinde akan ceviz ve fındıkları büyüklüklerinden ayırt edebilen ve fotograf alanı içerisinde kaç
tane ceviz ve kaç tane fındık olduğunu tespit eden bir program yazınız. Bunun için zemini beyaz bir alan haline
getirip üzerindeki ceviz ve fındıkların kenar çizgilerini oluşturabilirsiniz. Oluşan alanın içerisindeki küçük
noktasal gölgeleri yok edebilirsiniz. Daha sonra her bir alanı yukarıdaki algoritmayı kullanarak renklendirip,
alanın içerisindeki aynı renkli piksellerin sayısına bakarak hangisi ceviz, hangisi fındık sayıları ile birlikte
bulmaya çalışın. Bir kağıt üzerine fındık ve ceviz koyup kendi çektiğiniz fotograflar üzerinde bunu yapabilirsiniz.
Kendiniz başka yöntemlerde bulabilirsiniz. Normalde sınıflandırma için özel algoritmalar da vardır. Araştırıp
onlarıda kullanabilirsiniz. Algoritmanızın çalıştığını göstermek için en az 5 fotograf üzerinde denemesini yapın
ve gösterin.

13
Karabük Üniversitesi, Mühendislik Fakültesi............................................................................................... ........www.IbrahimCayiroglu.com

Ödev 2-Resimde ön planı tespit edip arka plandan çıkarma: Bir resim sahnesinde arka plandaki bölgeyi
çıkaracak bir kodlama yapın. Örneğin düz bir duvarın önünde bir fotograf çekilen bir kişinin görüntüsünü arka
plandan ayırın. Arka plana da bir manzara resmi yerleştirin. Her iki resmi birleştirin. Böylece kişi manzara
önünde resim çektirmiş gibi olsun. Bu işlem için öndeki resmin sınırlarını net bir şekilde bulabilecek bir renkte
uygun resim olması gerekir. Kendi bakış açınızla çıkabilecek sorunları nasıl çözersiniz araştırın.

Ödev 3-Tuz Biber Görüntüsünü Düzeltme Algoritması: Tuz-biber görüntüsü olan bir resmi alıp üzerindeki
noktaları aşıındırma ve genişletme şablonlarını kullanarak yok etmeye çalışın. İki ayrı (9 luk kare şablon, 5 lik
Artı şablon) şablonla da deneyin. Hangisinin daha iyi yok ettiğini gösterin.
Bu uygulamayı Medyan filtresini kullanarak da deneyin. Medyan filtresi ile Aşındırma-Genişletme filtrelerinin
Tuz-Biber görüntüsü üzerindeki başarılarını kıyaslayın.
Aynı şablonları bir resim üzerindeki kenarlarda oluşan açıklıkları kapatmak için kullanın. Hangisi daha iyi
kapattığını gözlemleyin. Programı yazarken kişi menüden hangi şablonu kullanacağını belirleyebilsin. Hangi
genişleteceğini yada daraltacağını belirleyebilsin. Birbirine yakın renkleride komşu olarak görmesi için kişi R, G,
B olmak üzere üç kanal için renk aralığı belirleyebilsin. Yani 50<R<120, 0<G<200 ve 150<B<180 aralıkları
ayarlayabilsin.

Ödev 4-Bozuk Para Sayma Makinası Algoritması:


a) Bozuk Paraların Değeri Kaç Lira? Bir beyaz kağıdın üzerine koyduğunuz, 25 kuruş, 50 kuruş ve 1 TL lik
paralardan kaçtane bulunduğunu ve toplamda kaç lira olduğunu gösteren programı yazın. (İpucu: Bir çok farklı
yöntem bulunabilir fakat paranın çerçeveleri bulunduktan sonra her hangi bir rengin en büyük en küçük
koordinatları çıkırılarak dairenin çapı tespit edilebilir. Çap büyüklükleri de paranın değeri ile ölçeklenirse
yüzeyde kaç lira olduğu çıkarılabilir)
b) Paraların Kaç Tanesi Yazı Kaç Tanesi Tura? Kağıt üzerindeki paraların kaç tanesinin yazı tura olduğunu
otomatik olarak tespit eden programı yazın. (İpucu: Elde edilen görüntülerin kenar desenleri çıkılıp, histogramları
oluşturulabilirse, aynı büyüklükteki parların Yazı kısmı aynı benzer histogramı, Tura kısmı ise benzer histogramı
verebilir. Bu yöntem kullanılarak yazı turalar tespit edilebilir. Kendiniz başka yöntemlerde bulmaya çalışın)

14
Karabük Üniversitesi, Mühendislik Fakültesi............................................................................................... ........www.IbrahimCayiroglu.com

Ödev 5: Uydu Fotograflarından Çevre ve Alan Bulma: Uzaydan çekilen fotoğraflar üzerinde bir gölün yada
arazinin alanını ve çevresini km yada m cinsinden hesaplayan bir program geliştirin. Çekilen fotoğraf üzerinde
düz bir çizgi çizip bu çizgiyi ölçek olarak kullanın. (örneğin aşağıdaki Van gölü üzerinde çizilen sarı çizgi 50 km
karşlılık gelmektedir. Bu resimde bu çizginin boyu 150 piksel ise her piksel 50.000 m/150 = 300 metreye karşılık
gelir).
Sınıf ortamında denen kareler üzerinde yapılan adımlar aşağıdaki şekilde olmuştur. Siz bu adımları daha otomatik
hale getirin (bir tuşla alan ve çevresini ekrana yazdırabilin) ve adımların daha iyi sonuç vermesi için algoritmaları
geliştirin.
a) Van gölünün hava fotoğrafı Google Earth den alındı. Üzerine ölçek çizgisi çizildi ve resim Gri resme
dönüştürüldü.

b) Gri resim 60 sınırı ile eşiklendi ve siyah-beyaz resme dönüştürüldü.

15
Karabük Üniversitesi, Mühendislik Fakültesi............................................................................................... ........www.IbrahimCayiroglu.com

c) Resim üzerindeki küçük siyah noktalar Medyan filtresi kullanılarak yok edildi.

d) Gölün alanı beyaz gözükmesi için (arka planı siyah yapmak için) negatifi alındı.

e) Beyaz bölgeleri tespit için alan bulma algoritması uygulandı ve her bir alan farklı renklere boyandı. 25
tane alan buldu. Bu renkli alanların her birinin km2 olarak alanı piksel ölçeklemesi kullanarak
hesaplanacak.

f) Gölün kenarları nı tespit için beyaz bölgeleri genişletme algoritması uygulandı ve orjinalinde çıkarılınca
kenarlar keskin bir şekilde (tek piksel kalınlığında) bulundu. Bu kenar resmi üzerinden gölün çevresi
ölçülecek.

16
Karabük Üniversitesi, Mühendislik Fakültesi............................................................................................... ........www.IbrahimCayiroglu.com

g) Sonuç olarak tek tuşla gölün alanı ve çevresi aşağıdakine benzer şekilde ekranda gösterilsin. Burada
önemli bir konu daha vardır. Resim üzerinde çok sayıda renklendirilmiş alan vardır. Bunlardan hangisinin
Van gölü olduğu nasıl anlaşılacak. Bunu tespit etmek için bir çok mantık geliştirilebilir ama şöyle bir
mantıkta olabilir.

Gölün ağırlık merkezi hesaplanabilir. (Tüm aynı renkleri resmin koordinat köşesine göre x ve y cinsinden
ayrı ayrı hesaplanabilir. Aşağıda formülü verildi). Hesaplanan bu ağırlık merkezlerinden hangisi resmin
ortasına en yakın ise o ağırlık merkezinin ait olduğu alan hesaplanmaya çalışılan alandır. Yani sonuçta
incelenen resim ortadaki gölü içine alan çerçevedir. Dolayısı ile göl ile çerçevenin ağırlık merkezleri
yakın olacaktır.

Araştırma 1 (Uygun eşikleme değerini otomatik tespit): Bir resim üzerinde en uygun eşikleme yapan bir
algoritma geliştirin. Resim türlerine göre uygun eşikleme değişebilir. Eşikleme yapıldıktan sonra resmin bir kısmı
siyah bir kısmı beyaz olacaktır. Resim üzerindeki alanları net bir şekilde ortaya çıkaran uygun eşikleme problemi
nasıl çözülür, bir yöntem bulmaya çalışın. Burada tek renk üzerinde eşikleme yapıldı fakat üç renk üzerinden üç
farklı eşikleme değeride kullanılabilir. Böyle bir mantık daha iyi sonuçlar verebilir mi, bu konuları deneyerek
araştırın ve bir yöntem bulmaya çalışın.

17
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

GÖRÜNTÜ İŞLEME-9.HAFTA

ARİTMETİK OPERATÖRLER
Görüntü aritmetiği iki veya daha fazla görüntüye standart aritmetik işlemlerden birini (toplama, çıkarma, çarpma,
bölme) veya mantıksal bir operatörü uygulayan işlemleridir. İşlem giriş resmi ile çıktı resmi arasında piksel piksel
uygulanır. Bu nedenle, görüntülerin normalde aynı boyutta olması gerekir. Görüntü aritmetiği görüntü işlemenin
en basit şekli ve dolayısı ile hızlı işlemlerdir.

Birçok uygulamada, işlenen görüntüler aynı sahneden farklı zaman noktalarında alınır. Örneğin, aynı sahnenin
ardışık görüntüleri eklenerek rastgele gürültünün azaltılması veya iki ardışık görüntü çıkartılarak hareket algılama
işlemleri yapılabilir. Mantıksal işlemler ise genellikle iki görüntüyü birleştirmek için kullanılır.

GPT
Görüntü İşlemede Aritmetik operatörler nerede kullanılır?
Görüntü işlemede aritmetik operatörler, piksel değerlerini değiştirmek veya hesaplamak için kullanılır. Aritmetik
operatörler, görüntülerdeki pikseller arasında matematiksel işlemler yapmak için kullanılır ve çeşitli
uygulamalarda kullanılırlar. İşte aritmetik operatörlerin bazı kullanım örnekleri:
Görüntü toplama (Addition): İki veya daha fazla görüntüyü toplama işlemiyle birleştirmek için kullanılır. Her
pikselin değeri, aynı koordinatlardaki diğer görüntülerin piksel değerleriyle toplanır.
Görüntü çıkarma (Subtraction): İki görüntü arasındaki farkı hesaplamak için kullanılır. İki görüntünün piksel
değerlerini çıkartarak, farklılıkları vurgulamak veya arka planı çıkarmak için kullanılabilir.
Görüntü çarpma (Multiplication): İki görüntünün piksel değerlerini çarparak yeni bir görüntü oluşturur. Bu işlem,
görüntüleri birbirleriyle karıştırarak renk efektleri oluşturmak veya kontrastı artırmak için kullanılabilir.
Görüntü bölme (Division): Bir görüntüyü diğer bir görüntüye bölmek için kullanılır. Bölme işlemi, görüntüleri
normalleştirme veya bir görüntüyü diğerine göre orantılı hale getirme amaçlarıyla kullanılabilir.
Görüntü ölçeklendirme (Scaling): Bir görüntüyü belirli bir oranda büyütmek veya küçültmek için çarpma veya
bölme işlemleri kullanılabilir. Örneğin, görüntüyü yakınlaştırmak veya uzaklaştırmak için ölçeklendirme işlemi
yapılabilir.
Bu sadece bazı örneklerdir ve aritmetik operatörlerin kullanımı çok çeşitli olabilir. Görüntü işleme
algoritmalarında, piksel düzeyinde matematiksel işlemler yapmak için aritmetik operatörler sıklıkla kullanılır.

A- Piksel Toplama, Görüntü Ekleme

Bu operatör giriş olarak aynı boyutlarda iki adet görüntüyü alıp, çıkış olarak aynı boyutta üçüncü bir görünüşü
üretir. Çıkış resmi, giriş resminlerinde aynı konumdaki piksellerin toplamı ile üretilir. İkiden fazla görüntüyü
birleştirme yada her piksele belirli bir sabitin eklenmesi şeklinde uygulamalar da yapılabilir.
İki görüntünün eklenmesi tek bir geçişte doğrudan gerçekleştirilir. Çıktı piksel değerleri şu şekilde oluşturulur.
𝑄(𝑥, 𝑦) = 𝑃1 (𝑥, 𝑦) + 𝑃2 (𝑥, 𝑦)
Tek bir görüntüye sabir bir sayı eklenmek isteniyorsa formülasyon aşağıdaki gibi olacaktır.
𝑄(𝑥, 𝑦) = 𝑃1 (𝑥, 𝑦) + 𝐶
Renkli görüntülerde, çıktı değerini üretmek için her bir kanal (R, G, B) kendi arasında toplanır. Sabit değer ise her
bir kanala eklenir. Sabit değer eklenerek yapılan uygulamar, resmin parlaklığını artıran bir işlemdir.
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Ekleme işleminden sonra, renk değerleri üst limiti aşarsa (255), taşan kısımlar için şu uygulamalar yapılabilir.
a) Taşan değerler 255 sabitlenebilir.
b) Taşan en üst değer 255 olacak şekilde tüm pikseller Normalleştirilebilir.
c) Ekleme işlemi yapılmadan önce orijinal resim belli bir sayı ile ölçeklenebilir (A=0.8 gibi).
𝑄(𝑥, 𝑦) = 𝑃1 (𝑥, 𝑦) ∗ 𝐴 + 𝑃2 (𝑥, 𝑦)
Benzer şekilde her iki resmi de ölçekleyip toplayabiliriz (A=0.5, B=0.5).
𝑄(𝑥, 𝑦) = 𝑃1 (𝑥, 𝑦) ∗ 𝐴 + 𝑃2 (𝑥, 𝑦) ∗ 𝐵
c) Taşan kısımlar 0 dan başlayacak şekilde tekrar başa dönebilir.
d) Eğer bir görüntünün kenar çizgileri ile toplama yapılıyor ise, sadece kenar kısımlarında kenar görüntüsün değeri
diğer alanlarda ise orijinal resmin pikselleri kullanılabilir.

Programlama (Görüntü ekleme)


Aşağıdaki ilk iki resim farklı toplama işlemine ve sınır aşma uygulamalarına tabi tutularsa şu sonuçlar alınır.

Aşağıdaki birinci resim direk iki resim toplanıp, sınırı aşan değerler 255 de sabitlenmiştir. İkinci resimde ise her iki
resimde 0.5 ölçekle çarpılarak önce karartılıp daha sonra değerler toplanmıştır.

Aşağıdaki iki resim toplanırken nişangahın renkli piksellere gelince renklerin%70 nişangahtan, %30 ana sahneden
alınmıştır.
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Örnek 1

private void pikselToplamaToolStripMenuItem_Click(object sender, EventArgs e)


{
Bitmap Resim1, Resim2, CikisResmi;
Resim1 = new Bitmap(pictureBox1.Image);
Resim2 = new Bitmap(pictureBox2.Image);

int ResimGenisligi = Resim1.Width;


int ResimYuksekligi = Resim1.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

Color Renk1, Renk2;


int x, y;
int R=0, G=0, B=0;

for (x = 0; x < ResimGenisligi; x++) //Resmi taramaya şablonun yarısı kadar dış kenarlardan
içeride başlayacak ve bitirecek.
{
for (y = 0; y < ResimYuksekligi; y++)
{
Renk1 = Resim1.GetPixel(x, y);
Renk2 = Resim2.GetPixel(x, y);

//İki resmi direk toplama


//R = Renk1.R + Renk2.R;
//G = Renk1.G + Renk2.G;
//B = Renk1.B + Renk2.B;

//İki resmi ölçekli olarak toplama


if (Renk2.R > 20 && Renk2.G > 20 && Renk2.B > 20)
{
R = Convert.ToInt16(Renk1.R * 0.3 + Renk2.R * 0.7);
G = Convert.ToInt16(Renk1.G * 0.3 + Renk2.G * 0.7);
B = Convert.ToInt16(Renk1.B * 0.3 + Renk2.B * 0.7);
}
else
{
R = Renk1.R;
G = Renk1.G;
B = Renk1.B;
}
//Sınırı aşan değerleri 255 ayarlama
if (R > 255) R = 255;
if (G > 255) G = 255;
if (B > 255) B = 255;

//Sınırı aşan değerleri Başa sarma şeklinde ayarlama


//if (R > 255) R = (R - 255);
//if (G > 255) G = (G - 255);
//if (B > 255) B = (B - 255);

CikisResmi.SetPixel(x, y, Color.FromArgb(R, G, B));

}
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

}
pictureBox3.Image = CikisResmi;
}

Normalizasyon Yaparak İki Resmi Toplama

private void PIKSEL_TOPLAMA_Click(object sender, EventArgs e)


{
Bitmap Resim1, Resim2, CikisResmi;
Resim1 = new Bitmap(pictureBox1.Image);
Resim2 = new Bitmap(pictureBox2.Image);

int ResimGenisligi = Resim1.Width;


int ResimYuksekligi = Resim1.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

Color Renk1, Renk2;


int x, y;
int R = 0, G = 0, B = 0;

int EnBuyukDeger = 0, EnKucukDeger = 255;

for (x = 0; x < ResimGenisligi; x++) //Resmi taramaya şablonun yarısı kadar dış kenarlardan
içeride başlayacak ve bitirecek.
{
for (y = 0; y < ResimYuksekligi; y++)
{
Renk1 = Resim1.GetPixel(x, y);
Renk2 = Resim2.GetPixel(x, y);

////İki resmi direk toplama


R = Renk1.R + Renk2.R;
G = Renk1.G + Renk2.G;
B = Renk1.B + Renk2.B;

int Gri = (R + G + B) / 3;

//Sınırı aşan değerleri 255 ayarlama. Gri resim üzerinde işlem yapıldığı için Sadece
R ye bakıldı.
if (Gri > EnBuyukDeger)
EnBuyukDeger = Gri;

if (Gri < EnKucukDeger)


EnKucukDeger = Gri;

if (R > 255) R = 255;


if (G > 255) G = 255;
if (B > 255) B = 255;

CikisResmi.SetPixel(x, y, Color.FromArgb(R, G, B));

}
}

pictureBox3.Image = CikisResmi;
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

pictureBox4.Image = Normalizasyon(Resim1, Resim2, EnBuyukDeger, EnKucukDeger);

public Bitmap Normalizasyon(Bitmap Resim1, Bitmap Resim2, int EnBuyukDeger, int EnKucukDeger)
{
Bitmap CikisResmi;

int ResimGenisligi = Resim1.Width;


int ResimYuksekligi = Resim1.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

Color Renk1, Renk2;


int x, y;
int R = 0, G = 0, B = 0;

int UstSinir = 0, AltSinir = 0;

if (EnBuyukDeger > 255)


UstSinir = 255;
else
UstSinir = EnBuyukDeger;

if (EnKucukDeger < 0)
AltSinir = 0;
else
AltSinir = EnKucukDeger;

for (x = 0; x < ResimGenisligi; x++) //Resmi taramaya şablonun yarısı kadar dış kenarlardan
içeride başlayacak ve bitirecek.
{
for (y = 0; y < ResimYuksekligi; y++)
{
Renk1 = Resim1.GetPixel(x, y);
Renk2 = Resim2.GetPixel(x, y);

////İki resmi direk toplama


R = Renk1.R + Renk2.R;
G = Renk1.G + Renk2.G;
B = Renk1.B + Renk2.B;

int NormalDegerR = (((UstSinir - AltSinir) * (R - EnKucukDeger)) / (EnBuyukDeger -


EnKucukDeger)) + AltSinir;
int NormalDegerG = (((UstSinir - AltSinir) * (G - EnKucukDeger)) / (EnBuyukDeger -
EnKucukDeger)) + AltSinir;
int NormalDegerB = (((UstSinir - AltSinir) * (B - EnKucukDeger)) / (EnBuyukDeger -
EnKucukDeger)) + AltSinir;

//EnBuyuk ve EnKucuk değerler Gri renge göre ayarlandığından Yinede bu renkler


sınırı geçebilir.
if (NormalDegerR > 255) NormalDegerR = 255;
if (NormalDegerG > 255) NormalDegerG = 255;
if (NormalDegerB > 255) NormalDegerB = 255;

if (NormalDegerR < 0) NormalDegerR = 0;


if (NormalDegerG < 0) NormalDegerG = 0;
if (NormalDegerB < 0) NormalDegerB = 0;

CikisResmi.SetPixel(x, y, Color.FromArgb(NormalDegerR, NormalDegerG, NormalDegerB));

}
}
return CikisResmi;
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Ek Konu: Resim Üzerine Yazı, Çizgi ve Resim Ekleme (Hazır fonksiyonlar)


Resim üzerine yazı ve çizgi gibi eklemek yapmak istediğimizde aşağıdaki hazır fonksiyonları kullanabiliriz.
Normal kameradan alınan görüntülerin üzerine bazen tarih ve saat işlenmesi gerekebilir. Yada görüntü üzerinde
nişangah (artikıl) benzeri bir şeklin düşürülmesine ihtiyaç olabilir. Ayrıca bir görüntü oluşturulurken (daha çok
video görüntülerinde) köşede başka bir kameranın görüntüsünün de olmasını isteyebiliriz. Yada aynı anda bir çok
kameranın görüntüsü tek çerçeve içerisinde oluşturulması gerekebilir. Video filmleri resimlerin arda arda
görüntülenmesi olduğundan bir resim üzerinde yapılacak bu işlemler tekrarlandığında video görüntüsünde de
yapılmış olacaktır.

Örnek 2. Resim üzerine yazı yazma

Bitmap GirisResmi = new Bitmap(pictureBox1.Image);


Bitmap CikisResmi = new Bitmap(GirisResmi);

string Metin1 = "KARABÜK ÜNİVERSİTESİ";


string Metin2 = "MEKATRONİK MÜHENDİSLİĞİ";

Point BirinciKonum = new Point(10, 10);


Point IkinciKonum = new Point(10, 50);

Graphics graphics = Graphics.FromImage(CikisResmi);

Font ArialFontTipi = new Font("Arial", 15);

graphics.DrawString(Metin1, ArialFontTipi, Brushes.Red, BirinciKonum);


graphics.DrawString(Metin2, ArialFontTipi, Brushes.Yellow, IkinciKonum);

pictureBox2.Image = CikisResmi;

string ResimDosyaYolu = @"..\..\..\Resimler\Deneme.jpg"; //Direk dosya adı yazılırse bin/debug


klasörüne yazılır.
CikisResmi.Save(ResimDosyaYolu);
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Örnek 3. Resim üzerine yazı yazma

private void btnYaziEkle_Click(object sender, EventArgs e)


{
Bitmap GirisResmi = new Bitmap(pictureBox1.Image);
Bitmap CikisResmi = new Bitmap(GirisResmi);
CikisResmi = GirisResmi;

int FontBoyutu = 25;

Font FontBilgisi = new Font("Times New Roman", FontBoyutu, FontStyle.Regular);

string Metin = "KARABÜK ÜNİVERSİTESİ";

Color Renk1 = Color.FromArgb(255,255,10,10); //Alfa,Red,Green,Blue ile tanımladık


Color Renk2 = Color.FromName("Yellow");

Rectangle Dikdortgen = new Rectangle(0, 0, 10, 20);

LinearGradientBrush GecisliFirca = new LinearGradientBrush(Dikdortgen, Renk1, Renk2,


LinearGradientMode.Vertical);

int xKonum = 100;


int yKonum = 80;

Graphics Grafik = Graphics.FromImage(CikisResmi);


Grafik.DrawString(Metin, FontBilgisi, GecisliFirca, xKonum, yKonum);

pictureBox2.Image = CikisResmi;

Örnek 4. Resim üzerine resim ekleme

private void btnResimBirlestir_Click(object sender, EventArgs e)


{
pictureBox1.Image = Image.FromFile(@"..\..\..\Resimler\Araba2.jpg");
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

pictureBox2.Image = Image.FromFile(@"..\..\..\Resimler\Araba1.jpg");

Bitmap GirisResmi1 = new Bitmap(pictureBox1.Image);


Bitmap GirisResmi2 = new Bitmap(pictureBox2.Image);

int Xkoordinati = 20; int Ykoordinati = 20; int Genislik = 200; int Yukseklik = 150;

Rectangle Dikdortgen = new Rectangle(Xkoordinati, Ykoordinati, Genislik, Yukseklik);

Graphics Grafik = Graphics.FromImage(GirisResmi2);


Grafik.DrawImage(GirisResmi1, Dikdortgen);

string ResimDosyaYolu = @"..\..\..\Resimler\Deneme3.jpg"; //Direk dosya adı yazılırse bin/debug


klasörüne yazılır.
GirisResmi2.Save(ResimDosyaYolu);

Örnek 5. Resim üzerine çizgi ekleme

private void btnResimUzerineCizgiEkle_Click(object sender, EventArgs e)


{
Bitmap GirisResmi = new Bitmap(pictureBox1.Image);
Bitmap CikisResmi = new Bitmap(GirisResmi);
CikisResmi = GirisResmi;

Graphics Grafik = Graphics.FromImage(CikisResmi);

Color Renk = Color.Red;// Çizim kaleminin rengini beyaz atıyor


Pen KalemCizgi = new Pen(Renk, 2);//Çizim

Grafik.DrawEllipse(KalemCizgi, 200, 150, 160, 160);

pictureBox2.Image = CikisResmi;

string ResimDosyaYolu = @"..\..\..\Resimler\Deneme4.jpg"; //Direk dosya adı yazılırse bin/debug


klasörüne yazılır.
CikisResmi.Save(ResimDosyaYolu);

Ödev 1: Gece görüş kamerası


a) Gece ortamda ışıklar çok düşükken (odada mum ışığı altında olabilir, cep telefonu ışığı üzerine bir şey kapatılarak
olabilir yada balkondan gece sokak görüntüsü alınarak denenebilir) alınan video görüntüleri üzerinde piksel
değerleri üzerine sabit bir değer ekleyerek görüntüyü aydınlatın (gece görüntüsünü gündüz gibi yapın). Bunun için
eklenecek sabit sayıyı bir sürgü (scrollbar) ile ayarlanabilir yaparsanız daha uygun değerde parlaklığı artırmış
olursunuz. Görüntü işleme hızı nedeniyle her kare belki biraz kesikli olabilir ama olabildiğince gece görüş kamerası
şeklinde olayı gösterin. (Not. Bu şekilde bir gece görüş kamerası geceyi gündüz gibi gösteren bir uygulamadır, fakat
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

termal kamera olayı değildir. Termal kamerada insan gözünün göremediği frekansları (kızıl ötesi bölge)
görebileceğimiz frekansa dönüştürmek gerekir)
b) Aynı uygulamayı şu şekide değiştirin. Karanlık ortamda çıkan en büyük renk değerini 255 gelecek şekilde ve en
küçük renk değerini de 100 gelecek şekilde Normalize ederek resmi yeniden düzenleyin. Buradaki 100 sayısını
Sürgü (Trackbar) ile ayarlanabilir yapın.

B- Piksel Çıkarma , Görüntü Çıkarma


Piksel çıkarma operatöründe, iki resim birbirinde çıkarılarak üçüncü çıktı resmi oluşturulur.
𝑄(𝑖, 𝑗) = 𝑃1 (𝑖, 𝑗) − 𝑃2 (𝑖, 𝑗)
Çıktı oluşturulurken ortaya çıkacak negatif değerler mutlak değeri alınarak pozitife dönüştürülebilir.
𝑄(𝑖, 𝑗) = |𝑃1 (𝑖, 𝑗) − 𝑃2 (𝑖, 𝑗)|
Sabit bir değerde çıkarılarak çıktı resmi elde edilebilir.
𝑄(𝑖, 𝑗) = 𝑃1 (𝑖, 𝑗) − 𝐶
Renkli görüntülerde her bir değer R,G,B kanallarından ayrı ayrı çıkarılır.
Sınırları taşan değerler için şu uygulamalar yapılabilir. Hangisinin uygulanacağına, yapılan uygulamanın türüne
göre karar verilir. Çıkarma işleminde ortaya çıkan değerler negatif bölgede olacaktır. Buna göre;
a) Çıkış piksel değerleri negatifse direk olarak sıfıra eşitlenebilir
b) Negatif değer 255 den çıkarılarak tekrar yukarıdan geriye doğru değer atanabilir. Yani -30 için 255-30=225
değeri atanabilir.
c) Yukarıda formülü yazıldığı gibi negatif değeler mutlak değeri alınarak direk pozitife dönüştürülebilir.
d) Bazı görüntü formatları eksi değerleri kabul eder. Bu tip görüntülerde olduğu gibi bırakılabilir.
e) Negatif değer 0 a çekilerek tüm resim değerleri Normalizasyon yapılarak, yani her pikselin değeri üst ve alt
limiter arasın orantısal olarak dağıtılabilir. -30 değeri 0 yapıldığında üst limitte 250 ise bu durumda bütün pikseller
0 ile 250 arasında yeniden hesaplanarak dağıtılabilir.

Örnek 6. Arka plandan görüntü çıkarma. Yazıları okunaklı hale getirme


Görüntü yada piksel çıkarmanın yaygın bir kullanımı olarak resimde arka plan görüntülerini kaldırma gösterilebilir.
Böylece ön plandaki görüntüler daha kolay analiz edilir. Örneğin: bazı tarama işlemlerinde yada yetersiz bir
aydınlatma ortamında çekilen bir sayfanın görüntüsü aşağıdaki gibi olabilmektedir. Bu işlemde sahnenin boş bir
görüntüsü (yazının olduğu ortama boş bir sayfa konarak oluşturulabilir), üzerinde yazı bulunan görüntüden
çıkarılarsa ön plandaki yazılar daha iyi tespit edilir.
Endüstriyel bir uygulamada ise bir bant üzerindeki cisimleri homojen olmayan bir ışık altında kontrol edilirse ön
plandaki cisimlerin daha anlaşılır olması için bu yöntem kullanılabilir. Görüntü alınan ortamda, kamera ve ışık
konumu sabit ise, sahne boş iken arka planı oluşturan bir görüntü alınır ve ardından sahneye giren cisimler varken
alınan görüntülerden bu arka plan çıkarılarak esas incelenen cisimler tespit edilebilir.
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Orijinal Resim Gölge Resmi (boş sahne resmi)

Böyle bir görüntüde belli bir değerin üzerindeki beyaz kısımları tamamen beyaz, geri kalanı tamamen siyah
yaparsak başarısız bir ayırma işlemi gerçekleştirmiş oluruz. Aşağıdaki resim 100 değeri ile eşiklenerek elde
edilmiştir.

OkunanRenk = GirisResmi.GetPixel(x, y);

R = OkunanRenk.R;

if (R > 100)
R = 255;
else
R = 0;

Bu problemi çözmek için sahne dolu iken alınan görüntüden (Orijinal resim), sahne boş iken alınan görüntü (Gölge
resmi) çıkarılırsa ön plandaki cisimlerin görüntü değeri elde edilir. Çıkarma işleminde negatif sayılar elde etmeyi
önlemek yukarıda anlatılan uygun yöntemler denenerek daha iyi sonuçlar elde edilebilir. Aşağıdaki resim çıkarma
işlemine mutlak değer fonksiyonu uygulanarak elde edilmiştir.

Renk1 = Resim1.GetPixel(x, y);


Renk2 = Resim2.GetPixel(x, y);
R = Math.Abs(Renk1.R - Renk2.R);
G = Math.Abs(Renk1.G - Renk2.G);
B = Math.Abs(Renk1.B - Renk2.B);

Bu görüntünün negatifi alınırsa daha iyi bir sonuç elde edilir.


Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

OkunanRenk = GirisResmi.GetPixel(x, y);

R = 255 - OkunanRenk.R;
G = 255 - OkunanRenk.G;
B = 255 - OkunanRenk.B;

DonusenRenk = Color.FromArgb(R, G, B);

CikisResmi.SetPixel(i, j, DonusenRenk);

Elde edilen bu görüntüde arka plandaki gölgeleri 170 değeri ile eşiklersek (ayarlanabilir bir sürgü-scrollbar ile
yapmak daha uygun olur) aşağıdaki sonucu elde ederiz.

OkunanRenk = GirisResmi.GetPixel(x, y);

R = OkunanRenk.R;

int EsiklemeDeger = ScroollBar1.Value;

if (R > EsiklemeDeger)
R = 255;
else
R = 0;

Görüntünün zayıf aydınlatılmış alanlarında kontrast (yani ön plan ve arka plan yoğunluk farkı) daha iyi aydınlatılmış
kısma göre daha düşük olduğu için resim üzerindeki homojenlik henüz daha sağlanabilmiş değildir. Daha sonra
gelecek konularda bu problemi biraz daha iyileştirmeye çalışacağız fakat, ışık koşulları homojen olmadığı için tam
olarak %100 bir çözüm imkansızdır.
Araştırma 1: Bu uygulamayı gamma corrected yöntemini kullanarak daha da iyileştirmeye çalışın ve araştırın.

Ödev 2: Yazı Okuma


Arka plandan görüntü çıkararak yazı okuma uygulamasının bir benzerini kendiniz yapın. Bütün uygulamalarda
kamerayı sabitleyin. Uygulamalarda cep telefonu kamerası anlık olarak kullanılacak ise, bu görüntülerin bilgisayara
nasıl aktarılacağını bulun (blue tooth yada usb üzerinden aktarma yapılabilir, araştırın).
Yukarıdaki örnekde verildiği gibi, üzerine gölge düşmüş bir kağıdın üzerindeki yazı ve resimleri okunaklı şekilde
tespit etmeye çalışın. (Cep telefonu kamerası kullanacaksanız masa kenarına telefonu sabitleyip yere kağıdı
koyabilirsiniz. Yan açıdan üzerine bir cismin gölgesi düşecek şekilde aydınlatma yapabilirsiniz.

Örnek 7. Hareket algılama


Görüntüleri çıkarırken değerleri mutlak değer olarak hesaplama, sahnede değişimleri algılamak için kullanılabilir.
Birbirinin aynı iki görüntüde (yada video gibi bir dizi resminde) sahnede hareket eden bir şey yoksa, iki kare
arasındaki mutlak fark oluşmaz ve çıktı çoğunlukla sıfır değerli piksellerden oluşur (siyah resim). Eğer sahnede bazı
cisimler hareket ediyorsa, mekansal değişimin olduğu bölgelerdeki piksellerde mutlak değer olarak farklılıklar
ortaya çıkacaktır.
Bu tür bir hareket algılama için aşağıdaki iki resim arasındaki farkı çıkardığımızda üçüncü kareyi elde ederiz.
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Böyle bir uygulama belli aralıklarla çekilen fotograflar işlenerek foto-kapan olarak kullanılabilir. Yada video
görüntüsü işlendiğinde hereket algılama olarak kullanılabilir. Sahnede çok küçük hareketleri algılamamak için
mutlak değer olarak toplam değer belli bir sayının üzerine çıktığında hareket var kabul edilebilir. Fakat bu
hesaplamada gri resimleri çıkarımı üzerinden değil, siyah-beyaz resimler üzerinden hesaplamak daha doğru olur.
Yani piksel farkı 0 yada 255 olacak şekilde hesaplama yapılırsa, renk derinliği işleme girmeden mekansal değişim
(hareket) algılanmış olur. Bu uygulama sahnede hereketin olduğu bölgeyi de verdiği için için kamera o bölgeye
odaklanıp zoomlama işlemi yaptırılabilir.
C- Piksel Çarpma ve Ölçekleme
Çarpma işleminin iki farklı türünden bahsedilebilir. Birincisi iki tane giriş resmi alınır. Bunlardan birincisinin piksel
değeri, ikinci resmin piksel değerleri ile çarpılması ile çıktı görüntüsü elde edilir. Buna Piksel çarpma denir. Bu işlem
iki görüntü ile yapılırken biri diğeri üzerinde maskeleme yapmak için kullanılabilir. Çarpma işlemi renk değerlerinin
hızla daha yükselmesini sağlamaktadır. Sonuçta piksel toplama işlemine benzer. Piksel toplama işleminde renk
değerleri daha yavaş yükselir. Bu nedenla bu operatörde değerler üst sınırı daha hızlı yaklaşır.
𝑄(𝑖, 𝑗) = 𝑃1 (𝑖, 𝑗) 𝑥 𝑃2 (𝑖, 𝑗)

Diğer bir uygulama ise bir giriş resmi belli bir ölçek değeri ile çarpılarak çıktı resminin oluşturulması sağlanır. Buna
Piksel ölçekleme denir. Bu ölçekleme Geometrik ölçekleme ile karıştırılmamalıdır. Geometrik ölçeklemede piksel
koordinatları değişir (spatial), bunda ise piksel değerleri değişir (spektral). Burada C katsayısı 1 den düşük olursa
resim aydınlığını azaltır. Renkli resimlerde ise her bir R, G, B kanalı ayrı ayrı sabit ile çarpılır.
𝑄(𝑖, 𝑗) = 𝑃1 (𝑖, 𝑗) 𝑥 𝐶
Çarpım katsayısı C birden büyük olursa o zaman üst sınır ya 255 i geçebilir. Bu durumda aşan değerler 255 de
sabitlenebilir. Yada başa sararak aşan değeler 0 dan itibaren yeniden değer verilebilir.. Örneğin 280 ise 280-
255=35 gibi. Çarpım işleminde piksel değerleri üst sınıra hızlıca yaklaşır. Sistem olarak sabit sayı ile toplamaya
benzer.
Bu yöntem resimleri aydınlatmak için kullanılabilir. Çarpım katsayısı 1 den küçük değer atanırsa resmi karartır.
Çarpma işlemi yukarıdaki birinci konu olan Piksel toplamadan daha doğal aydınlatma/karartma sonucu verir.

Örnek 7. İki resmi çarpma


Aşağıdaki örnekte iki resimde her kanal diğer resim değeri ile çarpılmış ve sınırını aşanlar 255 sabitlenmiştir.

...
Renk1 = Resim1.GetPixel(x, y);
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Renk2 = Resim2.GetPixel(x, y);

R = Renk1.R * Renk2.R;
G = Renk1.G * Renk2.G;
B = Renk1.B * Renk2.B;
if (R > 255) R = 255;
if (G > 255) G = 255;
if (B > 255) B = 255;

CikisResmi.SetPixel(x, y, Color.FromArgb(R, G, B));


...

Örnek 8. Resmi Ölçekleme

Aşağıdaki resim düşük bir ışıkta çekilmiş fotograftır. Bu resmi 3x sayısı ile ölçeklersek yandaki resim elde edilir.
Burada ölçekleme yaparken en üst limiti aşmamasına dikkat etmeliyiz. Aynı resim 5x ile öçeklenirse ve 255 geçen
değerler başa sarılırsa aşağıdaki 3 resim elde edilir. Burada çarpma işlemi sonunda aşan sayıların ne yapılacağı
kullanılacak uygulamalara uygun olarak belirlenebilir.

0.5x ile ölçekleme Orijinal Resim (1x Ölçekleme) 1.5x ile ölçekleme

2x ile ölçekleme 2.5x ile ölçekleme 3x ile ölçekleme

4x ile ölçekleme 5x ile ölçekleme 5x ölçekleme sınırı geçenler başa sarıldı

Renk1 = Resim1.GetPixel(x, y);


Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

double Olcekleme = (double)Surgu1.Value/100.0; //Sürgü sınırları 0-500 arasına ayarlandı

R = Convert.ToInt16(Renk1.R * Olcekleme);
G = Convert.ToInt16(Renk1.G * Olcekleme);
B = Convert.ToInt16(Renk1.B * Olcekleme);

//Başa sararken değerler mod alarak hesaplanıyor. Böylece 540 % 255 =30 olmuş olur.
if (R > 255|| G > 255|| B > 255)
{
R = (R % 255);
G = (G % 255);
B = (B % 255);
}

//if (R > 255) R = 255;


//if (G > 255) G = 255;
//if (B > 255) B = 255;

CikisResmi.SetPixel(x, y, Color.FromArgb(R, G, B));

D-Piksel Bölme
İki resim değerleri birbirine bölünerek çıktı görüntüsü elde edilebilir. Sonuçta piksel çıkarma işlemine benzer.
Ortaya çıkan değerler hızla küçüleceği için, çıkarma işleminden daha küçük sayılar elde edilir. Örneğin çıkarma
işleminde 180 değeri ile 30 değerleri 150 sonucunu verirken, Bölme işleminde 180/30=6 değerini verir. Bu nedenla
bu operatörde değerler alt sınırı daha hızlı yaklaşır.
𝑄(𝑖, 𝑗) = 𝑃1 (𝑖, 𝑗) ÷ 𝑃2 (𝑖, 𝑗)

Diğer bir uygulama ise bir giriş resmi belli bir sabit değere bölünerek çıktı resminin oluşturulması sağlanır. Buna
Piksel ölçeklemenin bir başka türünü verecektir. Renkli resimlerde ise her bir R, G, B kanalı ayrı ayrı sabit ile
bölünür.
𝑄(𝑖, 𝑗) = 𝑃1 (𝑖, 𝑗) ÷ 𝐶
Uygulama: Bu konu ile uygulamaları kendiniz yaparak deneyin. Yukarıdaki örneklerde olduğu gibi sınırı geçen
değerler için yada alt sınıra yakın bölgede biriken değerler için belli düzeltme faktörleri uygulayarak (ölçekleme
yada normalizasyon yapılabilir) çıktı resmi daha görünür hale getirilebilir.

BLENDİNG (Görüntü Harmanlama)


Bu operatör, aynı boyutta iki giriş görüntüsünün bir karışımını belli oranda değerler ile çarparak çıkış görüntüsünü
oluşturur. Görüntülerin çarpılacağı katsayılar kullanıcı tarafından belirlenir ve bunlar her görüntünün belli bir
ölçekleme oranını oluşturur. Çıktı piksel değerleri maksimum sınırı aşmaması için çarpım katsayıları 1 den küçük
ve toplamları bire eşit olacak şekilde belirlenir. Yani birinci resim 0,6 ile çarpılıyorsa, ikinci resim 0,4 ile
çarpılmalıdır.

𝑄(𝑖, 𝑗) = 𝑋 ∗ 𝑃1 (𝑖, 𝑗) + (1 − 𝑋) ∗ 𝑃2 (𝑖, 𝑗)


Burada aslında iki resim belli ölçeklerle maskelenmiş olmaktadır. Gri resimlerde uygulandığı gibi, R,G,B banda yada
daha fazla banda sahip resimlerde (multi spektral resimler) her banda ayrı ayrı uygulanır.
Görüntü karıştırmada resimler 1 altında ölçeklerle çarpıldığından ışık yoğunlu azalır (resim kararır). Bu nedenle
hangi resim daha ön planda olması isteniyorsa onun katsayısı daha yüksek tutulabilir. Yada eklemeden sonra
Normalizasyon yapılabilir. İki resmin belli oranlarda karıştırılması ile değişik sanatsal efektler oluşturulabilir.
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Ek Bilgi: Normalizasyon (Kontras germe)


Kontrast uzatma (genellikle normalleştirme olarak adlandırılır), çıktı resminde oluşan piksel değerlerini alt ve üst
limitlerinden tutarak belli bir aralığa lineer olarak (doğrusal olarak/orantı kurularak) çekme işlemidir. Sadece
doğrusal ölçeklendirmeye izin verdiği için daha karmaşık olan “Histogram Eşitlemesinden” farklıdır. Çıktı resmi
daha az serttir. Çoğu uygulama giriş resmi ve çıktı resmini Gri seviye resim olarak ister. Normalizasyon yaparken
aşağıdaki formül kullanılabilir.
𝑏−𝑎
𝑃𝑜𝑢𝑡 = (𝑃𝑖𝑛 − 𝑐) ( )+𝑎
𝑑−𝑐

Burada a ve b değerleri çıktı resminde oluşan sınırları (-30, 280 gibi sınırların dışına çıkmış olabilir), c ve d ise
çekilmek istenen sınırları (örneğin 0-255 olabilir) gösterir.
Normalizasyondaki esas sorun çok yüksek veya çok düşük bir değere sahip tek bir pikselin değeri, çıktı c veya d
değerini ciddi şekilde etkileyebilmesidir ve bu da çok temsilsiz ölçeklendirmeye yol açabilir. Bu nedenle, daha
sağlam bir yaklaşım önce görüntünün bir histogramını almak ve sonrasında histogramdaki %5 ve %95
değerlerinden c ve d'yi seçmektir. Böylece aşırı uçlardaki değerler ihmal edilmiş olur. Bu durum, ölçeklendirmeyi
çok etkileyen aykırı değerleri önler.
Aykırı değerlerle başa çıkmanın bir başka yolu ise, bir görüntüdeki en popüler yoğunluk seviyesini (yani histogram
pikini) bulmak için yoğunluk histogramını kullanmaktır. Ortaya çıkan histogramda yığılmanın olduğu bölgenin
altından ve üstünden alınan değerler ile c ve d değerleri tespit edilebilir.
Renkli görüntüler ile çalışılıyorsa, doğru renk oranlarını korumak için tüm kanallar aynı ofset ve ölçeklendirme
kullanılarak gerilmelidir (normalize edilmelidir).

Programlama: Normalizasyon

Bu iki resmi 1.8 ve 1.2 katsayıları ile ölçekleyip toplarsak (Blending işlemi) üst değerler sınırı geçecektir. Bu değerler
için üst sınırı geçenleri 255 e sabitlersek birinci görüntüyü elde ederiz. Üst sınırı Normalizasyon yaparak (tüm
pikselleri orantısal olarak kaydırırsak) 255 ayarlarsak aşağıdaki ikinci görüntüyü elde ederiz.
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

private void blendingHarmanlamaToolStripMenuItem_Click(object sender, EventArgs e)


{
Bitmap Resim1, Resim2, CikisResmi;
Resim1 = new Bitmap(pictureBox1.Image);
Resim2 = new Bitmap(pictureBox2.Image);

int ResimGenisligi = Resim1.Width;


int ResimYuksekligi = Resim1.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

Color Renk1, Renk2;


int x, y;
int R = 0, G = 0, B = 0;

int EnBuyukDeger = 0, EnKucukDeger = 0;

for (x = 0; x < ResimGenisligi; x++) //Resmi taramaya şablonun yarısı kadar dış kenarlardan
içeride başlayacak ve bitirecek.
{
for (y = 0; y < ResimYuksekligi; y++)
{
Renk1 = Resim1.GetPixel(x, y);
Renk2 = Resim2.GetPixel(x, y);

double Carpan1 = Convert.ToDouble(txtDeger1.Text);


double Carpan2 = Convert.ToDouble(txtDeger2.Text);

R = Convert.ToInt16(Renk1.R * Carpan1 + Renk2.R * Carpan2);

//Sınırı aşan değerleri 255 ayarlama. Gri resim üzerinde işlem yapıldığı için Sadece
R ye bakıldı.
if (R > EnBuyukDeger)
EnBuyukDeger = R;

if (R < EnKucukDeger)
EnKucukDeger = R;
}
}

Normalizasyon(Resim1, Resim2, EnBuyukDeger, EnKucukDeger);


}

////////////////////////////////////////////////////////////////
public void Normalizasyon(Bitmap Resim1, Bitmap Resim2, int EnBuyukDeger, int EnKucukDeger)
{
Bitmap CikisResmi;
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

int ResimGenisligi = Resim1.Width;


int ResimYuksekligi = Resim1.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

Color Renk1, Renk2;


int x, y;
int R = 0, G = 0, B = 0;

int UstSinir = 0, AltSinir = 0;

if (EnBuyukDeger > 255)


UstSinir = 255;
else
UstSinir = EnBuyukDeger;

if (EnKucukDeger < 0)
AltSinir = 0;
else
AltSinir = EnKucukDeger;

for (x = 0; x < ResimGenisligi; x++) //Resmi taramaya şablonun yarısı kadar dış kenarlardan
içeride başlayacak ve bitirecek.
{
for (y = 0; y < ResimYuksekligi; y++)
{
Renk1 = Resim1.GetPixel(x, y);
Renk2 = Resim2.GetPixel(x, y);

double Carpan1 = Convert.ToDouble(txtDeger1.Text);


double Carpan2 = Convert.ToDouble(txtDeger2.Text);

R = Convert.ToInt16(Renk1.R * Carpan1 + Renk2.R * Carpan2);

R = Convert.ToInt16(Renk1.R * Carpan1 + Renk2.R * Carpan2);

int Deger = R; //Gri resim de tek değer kullanıldı.

int NormalDegerR = (((UstSinir - AltSinir) * (Deger - EnKucukDeger)) / (EnBuyukDeger


- EnKucukDeger)) + AltSinir;

CikisResmi.SetPixel(x, y, Color.FromArgb(NormalDegerR, NormalDegerR, NormalDegerR));

}
}
pictureBox2.Image = CikisResmi;
}

Araştırma 2: Aşağıdaki konuları inceleyin. Uygulamaları programlayıp, dökümanları Türkçeleştirin.


http://homepages.inf.ed.ac.uk/rbf/HIPR2/fourier.htm (Fourier Transform)
http://homepages.inf.ed.ac.uk/rbf/HIPR2/pixlog.htm (Logarithm Operator)
http://homepages.inf.ed.ac.uk/rbf/HIPR2/histeq.htm (Histogram Equalization)
http://homepages.inf.ed.ac.uk/rbf/HIPR2/freqfilt.htm (Frequency Filter)

Ödev 1
a) İki tane resmi toplama işlemi yaptırın. Bu resimleri toplarken her resmi farklı ölçeklerle çarparak toplayın.
Böylece ortaya çıkan birleşmiş resimi her iki resmi aynı orantıda göstermeye çalışsın. Örneğin aşağıda birinci resim
koyu bir resim, ikinci daha açık bir resimdir. Bu iki resim toplanırken birinci resim daha büyük bir ölçekle çarpılarak
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

toplanmalı. Ortaya çıkan resim üzerinde tamamen beyazlama olmayacak şekilde ölçekleri ayarlanmalı. Ölçekleri
ayarlamak için yan tarafta sürgüyü kullanarak manuel olarak yapınız.

b) Aynı uygulamayı otomatik ölçeklendirme yaparak yaptırın. (İpucu: Birinci resimdeki tüm renkleri toplasak,
ortalamasını alsak -yani piksel sayısına bölsek, aslında renk düzeyinin ortalamasını bulmuş oluruz. Örneğin birinci
resmin ortalaması (R, G, B hepsi için ortak bir sayı olmalı) 65 çıkmış olsun. İkinci resimde bu ortalama 130 çıkmış
olursa, buradan ne anlarız, birinci resim daha koyu bir resimdir, ikinci resim ise açık bir resimdir. Bu iki resmi
topladığımızda toplamları 255 geçmeli. Birinci resmi 2 le çarpsak diğerini de 1 le çarpsak yaklaşık olarak 260 gibi
bir sayıyı tuttururuz. Buda iki resmi eşdeğer oranda havuza katıldığını gösterir. Buna benzer bir mantık kullanarak
otomatik ölçeklendirme yaptırın.

c) İki resmi kendi orijinal piksel değerleri ile toplayın. Dolayısı ile bazı piksellerin değeri 255 i geçecektir . Bu
durumda ortaya çıkan resimde beyazlamış bölgeler olacaktır. İşte bu beyazlamış olan bölgeleri yok etmek
Normalizasyon işlemi uygulayın.
Geliştirdiğiniz bu üç yöntemden hangisi daha uygun resim toplama işlemi yaptı. Yorumlayın.

Ödev 2: Bant üzerinde akan ürünlerin farklı ışık ortamlarında zeminden ayırma: Bant üzerinden akan ürünleri
görüntü işleme ile tespit etmek istiyoruz. Bu ürünler YSA ya gönderilirken sadece siyah ve beyaz olmasını istiyoruz
(2 renk olacak). Fabrikada üretim hattında ışık ortamı sürekli olarak değişmektedir. Gündüz ve akşam saatleri ile
fabrikanın ışıklarını oluşturduğu farklı gölgelemeler ortaya çıkmaktadır. Bu gölgelemeler çok hızlı olmasa da yavaş
bir şekilde değişmektedir. Böyle bir ortamda bant üzerindeki ürünleri doğru bir şekilde zeminden ayırabilmek için
algoritmayı geliştirin.
Ödev için bu uygulamayı yaparken masa üzerine boş bir kâğıt koyun. Odanın ışıklarını kapatın. Yan taraftan mum
ışığında (telefon ışığında) kâğıdın fotoğrafını üstten çekin. Kâğıt gölgeli bir fotoğraf olacaktır. Bu fotoğraf arka plan
resmi olur. Sonra üzerine bir cisim koyun (Bir kaşık olabilir). Bu cismi arka plandan ayırırken eşikleme yaparak ve
iki resmi birbirinden çıkararak uygulamayı gerçekleştirin. Hangisinde nesneyi daha iyi ayırdınız gösterin.

Ödev 3: Hareket sensör ile cismin merkezini yakalayıp, kamera eksenini (silah eksenini) ne kadar çevireceğini
(yatayda ve dikeyde) hesaplayacak programı yazın).
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Ödev 4: Hareket eden cisimlerde Ağaç ile insanı fark edebilecek bir algoritma geliştirin. Hareket cismin üzerine bir
Artikel ekleyin (+ işareti) bu işaret hareket eden cismi takip etsin. Deney ortamını hazırlayın algoritmalarını yazın..
Ödev 5: Bir fabrika otomasyon sisteminde kamere çevre şartları içinde içinde içinde çalışsın. Çevredeki ışıklar
değiştikçe bant sistemi üzerindeki yakalanan nesnenin görüntüsünün kalitesi değişmesin. Çevredeki ışıklar
değişsin. Her değişimde hızlı bir şekilde cismi daha net bir şekilde ortamdan ayırabilsin. Deney ortamını oluşturun.
Ödev 6: Askeri uygulamalar için dürbünle bakarken Artikel, çekim saatleri, mesafe skalası gibi gerçek görüntüyü
oluşturacak bir uygulama yapın. Video görüntüsü üzerinde bu uygulama nasıl yaparsınız araştırın.
ÖDEV 7: Aşağıdaki gibi bir üzerine daha ayarlanabilir bir yazıyı çapraz ve saydam olarak yazdıran komutları
oluşturun.

Ödev 8: Görüntüyü zeminden ayırma


Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Gölgeli bir yazı görüntüsünü daha okunaklı hale getirmek için zemin görüntüsünden çıkarırsak daha iyi sonuç elde
ederiz. Aşağıda bu uygulamanın aşamaları gözükmektedir. Fakat hala koyu bölgede yazılar kaybolmakta, açık
bölgede ise yazıların arası dolmaktadır. Tam iyi bir sonuç elde edilememektedir.
Daha gelişmiş algoritmalar yazarak bu sorunu çözmeye çalışın. Yazı ve zemin görüntüsünü karanlık bir odada
telefonun ışığı ile kendiniz elde edin.

Ödev 9: Foto kapan


a) Hareket algılama ile ilgili olarak aşağıdaki sahnelerden birinde Foto-kapan uygulaması yapın. Bunun için
kamerayı sabitleyin (cep telefonu, web kamera, laptop kamerası vs)
Balkon yada cam kenarına bir yere kamerayı cadde yada gökyüzüne doğru sabitleyip, aralıklarla resim çekin (Her
resmi alıp işledikten sonra tekrar resim alsın. Aralıklar ne kadar kısa olursa o kadar iyi olur). Bunun için sahne boş
iken (tüm cisimler hareket etmemeli) önce sahne görüntüsünü alın. Ardından döngüyü çalıştırıp kameradan sürekli
görüntü alın ve işleyin. Alınan görüntüler ile boş sahne görüntüsü arasında fark varsa, hareket var demektir ve
hareket eden pikselleri yukarıda örnekte olduğu gibi belirleyebilirsiniz. Hareket eden piksellerin koordinatlarının
bir ortalamasını alarak ( x koordinatları kendi arasında toplanıp, kaç piksel ise ona bölünerek ve y eksenleri içinde
aynısı yapılarak) hareket eden nesnenin sahnenin neresinde olduğunu bulun. Bu bölgenin üzerine bir daire yada
Artikel (+) işareti kondurun. Böylelikle hedefi tespit eden bir uygulama yapmış olacaksınız.
b) Aynı ödevde hareket eden nesneler bulunduktan sonra bunları bir çerçeve içine alın. Ardından otomatik olarak
hareket eden nesnenin olduğu bölgeyi zoomlasın.

Ödev 10: Arka plan görüntüsünü düzeltme.


a) İki resmi birbirinden çıkarak şöyle bir uygulama yapın. Gece vakti odanın ışığı kapalı iken Camdan dışarıdaki bir
manzaranın fotoğrafını çekin (Dışarıda sokak yada karşıda evler vs çıkacaktır). Fotoğraf odanın ortasından bir
yerden çekilmeli. Sonra içerinin ışığını açın, Camın iç kısmında odanın yansıması gözükecektir. Burada istenen Hem
içerideki nesnelerin (cam ve etrafı) aydınlık görüntüsü olsun hem de camdan yansıma olmadan dışarının manzarası
gözüksün. Buna benzer bir uygulama yapın. Burada hedef camdaki yansımayı kaldırmak. Ortamın ev içi vs olması
gerekmiyor, özel alanlarda çekmeyin. Uygun bir deney ortamı kurarak yapmaya çalışın.

Ödev 11. Hareket algılama-foto kapan: İki resmi bir birinden çıkardığımızda ortaya çıkan resim bize hareket eden
nesneleri gösterir. Fakat bu işlemde küçük gölgeler ve küçük nesnelerde (yaprakların oynaması gibi) hareket ediyor
olarak gözükür. Böyle bir kamera uygulamasında insan ve araba gibi büyük nesnelerin hareket ettiğini algılayan,
yaprak, sinek vs gibi küçük nesneleri hareket ediyor olarak algılamayacak bir algoritma geliştirin. Bulunan
nesnelerin ağırlık merkezine bir (+) işaret kondurun.
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Ödev 12: Gölgeli zeminden cismi ayırma: Masanın üzerine bir kağıt koyun. Kağıdın yan tarafına bir engel (Bardak,
sürahi). Sürahinin arkasından ışık kağıdın üzerini aydınlatsın. (Oda karanlık olacak) Sürahinin gölgesi dalgalı bir
şekilde kağıdın üzerine düşer. Bu gölgenin üzerine Kalem, silgi, Şeker (kağıdı ile), vs cisimler koyalım.
a) İlk olarak tepeden kağıdın sabit bir kamera ile (telefonu sabitleyerek) fotoğraf alalım. Bu fotoğrafın
içinden cisimleri renkli bir şekilde ayıralım. Gölgeli arka plandan cisimleri zor olacaktır.
b) İkinci durumda bu sefer cisimler yokken kağıdın gölgeli görüntüsünü alalım. Bu görüntüden cisimler
varken çekilen fotoğrafı çıkarırsak, cisimleri daha kolay tespit ederiz. Fakat tespit ettiğimiz yer aslında
cismin silüetidir. Tam olarak kendi renginde göremeyiz. Eğer bu sülietleri olduğu görüntüyü arka plandan
ayırırsak (cismin beyaz pikselleri olur) ve aynı koordinatları orijinal resmin (gölgeli kağıdın üzerindeki
cisimlerin görüntüsü) üzerindeki piksellerden okursak artık aradığımız cismin renkli halini zeminden
tamamen ayırarak ortaya çıkartırız. (Resim temsili konmuştur, konuyu tam anlatmaz)
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

GÖRÜNTÜ İŞLEME-10.HAFTA

İçindekiler
GÖRÜNTÜ İŞLEME-10.HAFTA .................................................................................................................................... 1
MANTIKSAL OPERATÖRLER ................................................................................................................................... 1
Mantıksal AND/NAND Operatörleri....................................................................................................................... 2
AND/NAND operatörü nerede kullanılır? .......................................................................................................... 2
C# Kendi Fonksiyonları ile AND operatörünü kullanma ........................................................................................ 6
Uygulama 1-İki görüntünün kesişimini bulma ................................................................................................... 7
Uygulama 2-Görüntülerden birini maske olarak kullanma ............................................................................... 7
BİT DİLİMLEME................................................................................................................................................... 7
Sabit Sayı ile AND leme .................................................................................................................................... 13
Mantıksal OR/NOR Operatörleri.......................................................................................................................... 16
OR/NOR operatörü nerede kullanılır? ............................................................................................................. 16
OR Uygulamaları .............................................................................................................................................. 17
OR ile Bölge Genişletme .................................................................................................................................. 18
Mantıksal XOR/XNOR Operatörleri ..................................................................................................................... 20
XoR ile Kenar Tespiti Yapan Algoritma ............................................................................................................ 20
XoR ile İki Resimde Farklı Bölgeleri Tespit Etme .............................................................................................. 21
XoR ile Görüntüye Efekt Uygulama ................................................................................................................. 22
Mantıksal NOT Operatörü (Invert-Tersini alma) ................................................................................................. 23
NOT operatörü ile Kenar Tespiti ...................................................................................................................... 24
Bitshift (Bit kaydırma) Operatörü ........................................................................................................................ 25
Bit kaydırma ile Örnek Overlap (Örtüşme) yapan kod. ................................................................................... 27

MANTIKSAL OPERATÖRLER
Mantıksal operatörler, resmin gerçek değerlerine dokunmadan, boolean ifadeler (true yada false) kullanılarak yeni
bilgiler veya görüntüler çıkarmak için kullanılır. Örneğin “Ağaç hem yeşil hemde büyük ise” ifadesi A AND B
şeklinde ifade edilebilir. Bu durumda her iki kavramda doğru (true) ise sonuç True olacaktır ve ona göre işlem
yapılacaktır. Bu şekilde girilen iki tane görüntü üzerinde yada tek bir görüntü üzerinde, piksel değerlerine
mantıksal operatörlerin doğruluk tablosu kuralları uygulanarak görüntüler üzerinde mantıksal işlemler
gerçekleştirebiliriz. Normalde, aynı boyutta iki görüntüden çıktı görüntüsünü üretmek için, giriş görüntüsülerine
ait birbirine karşılık gelen pikseller karşılaştırılır. Tek bir giriş görüntüsünü sabit bir mantıksal değerle mantıksal
olarak birleştirmek de mümkündür. Bu durumda giriş görüntüsündeki her piksel karşılık gelen çıkış pikselini
üretmek için aynı sabit ile karşılaştırılır.
Mantıksal işlemler, tamsayı piksel değerlerine sahip görüntüler üzerinde, bu tamsayıların ikili gösterimleri (binary)
yapılarak bunlar üzerinde bitsel bir şekilde işlem yapılarak, çıkış piksel değerine bitsel sonuçlar üretilip buradan
tam sayı değerine ulaşılabilir. Örneğin, 47 ve 255 tam sayılarını 8 bitlik tam sayıları kullanarak birlikte XOR yapmak
istediğimizi varsayalım. Bunları ikili biçimde göserirsek 45 sayısı 00101111 ve 255 sayısı 11111111'dir. Bunları
bitsel olarak birlikte XORing yaparak, ikili olarak 11010000 değerine ulaşılır. Bunun karşılığı ise tam sayı olarak 208
dir.
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Mantıksal işlemler illa böyle bitsel (1/0) olarak uygulanması gerekmez. Örneğin, bazı uygulamalarda sıfır değerleri
false kabul edilirken, sıfır haricindeki herhangi bir değer true olarak kabul edilebilir. Çıktı görüntüsünü elde etmek
için ise 1-bit mantıksal işlemleri uygulanır. Çıktı görüntüsü basit bir ikili (binary) görüntünün kendisi olabilir ya da
belki de ikili (binar) çıktı görüntüsü (sadece siyah ve beyaz görüntü) giriş görüntülerinden hehangi biriyle
çarpılarak gri seviye bir görüntü elde edilebilir..

İnteger sayıyı ikili (binary) sayıya 8 bit olarak dönüştürme

int intSayi1 = Convert.ToInt16(txtDeger1.Text);

string binarySayi = Convert.ToString(intSayi1, 2).PadLeft(8, '0');

txtDeger1.Text = binarySayi;

int intSayi2 = Convert.ToInt32(binarySayi, 2);

txtDeger2.Text = intSayi2.ToString();

Mantıksal AND/NAND Operatörleri


Mantıksal operatörler, Boolean değerler üzerinde (1 yada 0)(Doğru yada Yanlış) işlem yapılarak elde edilir. AND
ve NAND işlem tablosu aşağıdaki gibidir.

Dikkat edilirse iki tablo birbirinin tam zıttıdır. Bu Operatörlerde Birinci resmi alıp, ikinci resimle AND veya NAND
işlemine tabi tutularak çıktı resmi oluşturulur. Yada sadece tek bir Girdi resmi alınır ve belli bir sabit sayı ile AND
yada NAND işlemine tabi tutulabilir. Tablolara dikkat edilirse bu iki operatör birbirinin tam tersidir.
AND ve NAND operatörü giriş olarak iki adet ikili (binary-siyah/beyaz resim) veya tamsayı ile ifade edilen gri seviye
görüntüyü alır ve piksel değerleri üzerinde işlem yaparak ilk görüntünün değerlerini ikinci görüntü ile işlem
yaparak üçüncü bir görüntü oluşturulur. Bu operatörün farklı bir uygulaması olarak tek bir giriş görüntüsü alınıp
her pikseli sabit bir değer ile işleme tutarak çıktı görüntüsü oluşturulabilir.
İşlem tek bir geçişte doğrudan gerçekleştirilir. Üzerinde çalışılan tüm giriş pikseli değerlerinin aynı sayıda bite sahip
olması önemlidir. Giriş görüntülerindeki piksel değerlerinin basit 1 bitlik sayılar olmadığı durumlarda, AND işlemi
normalde (ancak her zaman değil) piksel değerlerindeki her bir bit üzerinde ayrı ayrı, bitsel şekilde gerçekleştirilir.

AND/NAND operatörü nerede kullanılır?


Görüntü işleme alanında, AND operatörü genellikle görüntüler arasında piksel bazında birleştirme, maskeleme
veya sınırlama gibi işlemlerde kullanılır. İşte bazı örnekler:
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Piksel birleştirme: İki görüntü arasında piksel bazında birleştirme yapmak için AND operatörü kullanılabilir. Bu
işlemde, iki görüntünün aynı konumdaki pikselleri AND operatörü ile birleştirilir ve sonuç görüntüsünde yalnızca
ortak olan piksellerin değeri korunur.
Maskeleme: Bir görüntüyü başka bir görüntüyle maskelemek için AND operatörü kullanılabilir. Maskeleme işlemi,
bir maske görüntüsünün belirli bir değeri olan pikselleri korurken, diğer pikselleri göz ardı etme işlemidir. AND
operatörü, görüntüyü maskeleme işleminde kullanılan maske görüntüsüyle birleştirerek istenilen piksellerin
sınırlanmasını sağlar.
Sınırlama: Görüntüdeki pikselleri belirli bir değer aralığıyla sınırlamak için AND operatörü kullanılabilir. Örneğin,
bir görüntüdeki piksellerin belirli bir aralıkta (örneğin, minimum ve maksimum değerler arasında) olmasını
istiyorsak, bu sınırlama işlemi için AND operatörü kullanılabilir. AND operatörü, piksellerin değerlerini sınırlama
aralığıyla birleştirerek istenen sınırlamayı uygular.
Bu örnekler, görüntü işleme uygulamalarında AND operatörünün yaygın olarak kullanıldığı bazı senaryoları
göstermektedir. Ancak, bu sadece bazı örneklerdir ve AND operatörü, diğer görüntü işleme işlemlerinde de farklı
şekillerde kullanılabilir. Diğer mantıksal işleçlerde olduğu gibi, AND ve NAND genellikle daha karmaşık görüntü
işleme görevlerinin alt bileşenleri olarak kullanılır.

private void AND_NAND_IslemiToolStripMenuItem_Click(object sender, EventArgs e)


{
Bitmap Resim1, Resim2, CikisResmi;
Resim1 = new Bitmap(pictureBox1.Image);
Resim2 = new Bitmap(pictureBox2.Image);

int ResimGenisligi = Resim1.Width;


int ResimYuksekligi = Resim1.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

Color Renk1, Renk2;


int x, y;
int R = 0, G = 0, B = 0;

for (x = 0; x < ResimGenisligi; x++) //Resmi taramaya şablonun yarısı kadar dış kenarlardan
içeride başlayacak ve bitirecek.
{
for (y = 0; y < ResimYuksekligi; y++)
{
Renk1 = Resim1.GetPixel(x, y);
Renk2 = Resim2.GetPixel(x, y);

string binarySayi1 = Convert.ToString(Renk1.R, 2).PadLeft(8, '0'); //Gri renk


olduğundan tek kanal üzerinden yapılıyor.
string binarySayi2 = Convert.ToString(Renk2.R, 2).PadLeft(8, '0');

string Bit1 = null, Bit2 = null, StringIkiliSayi = null;

for (int i = 0; i < 8; i++)


{
Bit1 = binarySayi1.Substring(i, 1);
Bit2 = binarySayi2.Substring(i, 1);

////AND İŞLEMİ
//if (Bit1 == "0" && Bit2 == "0") StringIkiliSayi = StringIkiliSayi + "0";
//else if (Bit1 == "1" && Bit2 == "1") StringIkiliSayi = StringIkiliSayi + "1";
//else StringIkiliSayi = StringIkiliSayi + "0";

//NAND İŞLEMİ
if (Bit1 == "0" && Bit2 == "0") StringIkiliSayi = StringIkiliSayi + "1";
else if (Bit1 == "1" && Bit2 == "1") StringIkiliSayi = StringIkiliSayi + "0";
else StringIkiliSayi = StringIkiliSayi + "1";
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

}
R = Convert.ToInt32(StringIkiliSayi, 2); //İkili sayıyı tam sayıya dönüştürüyor.

CikisResmi.SetPixel(x, y, Color.FromArgb(R, R, R)); //Gri resim

}
}
pictureBox3.Image = CikisResmi;

AND için oluşan çıktı.

NAND için oluşan çıktı.

Renkli Resim için Kodlar

private void MANTIKSAL_OPERATOR_Click(object sender, EventArgs e)


{

Bitmap Resim1, Resim2, CikisResmi;


Resim1 = new Bitmap(pictureBox1.Image);
Resim2 = new Bitmap(pictureBox2.Image);

int ResimGenisligi = Resim1.Width;


int ResimYuksekligi = Resim1.Height;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

Color Renk1, Renk2;


int x, y;
int R = 0, G = 0, B = 0;

for (x = 0; x < ResimGenisligi; x++) //Resmi taramaya şablonun yarısı kadar dış kenarlardan
içeride başlayacak ve bitirecek.
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

{
for (y = 0; y < ResimYuksekligi; y++)
{
Renk1 = Resim1.GetPixel(x, y);
Renk2 = Resim2.GetPixel(x, y);

string binarySayi1R = Convert.ToString(Renk1.R, 2).PadLeft(8, '0'); //Gri renk


olduğundan tek kanal üzerinden yapılıyor.
string binarySayi2R = Convert.ToString(Renk2.R, 2).PadLeft(8, '0');

string binarySayi1G = Convert.ToString(Renk1.G, 2).PadLeft(8, '0'); //Gri renk


olduğundan tek kanal üzerinden yapılıyor.
string binarySayi2G = Convert.ToString(Renk2.G, 2).PadLeft(8, '0');

string binarySayi1B = Convert.ToString(Renk1.B, 2).PadLeft(8, '0'); //Gri renk


olduğundan tek kanal üzerinden yapılıyor.
string binarySayi2B = Convert.ToString(Renk2.B, 2).PadLeft(8, '0');

string Bit1R = null, Bit1G = null, Bit1B = null, Bit2R = null, Bit2G = null, Bit2B =
null;
string StringIkiliSayiR = null, StringIkiliSayiG = null, StringIkiliSayiB = null;

for (int i = 0; i < 8; i++)


{
Bit1R = binarySayi1R.Substring(i, 1);
Bit2R = binarySayi2R.Substring(i, 1);

//AND İŞLEMİ
if (Bit1R == "0" && Bit2R == "0") StringIkiliSayiR = StringIkiliSayiR + "0";
else if (Bit1R == "1" && Bit2R == "1") StringIkiliSayiR = StringIkiliSayiR + "1";
else StringIkiliSayiR = StringIkiliSayiR + "0";

Bit1G = binarySayi1G.Substring(i, 1);


Bit2G = binarySayi2G.Substring(i, 1);

//AND İŞLEMİ
if (Bit1G == "0" && Bit2G == "0") StringIkiliSayiG = StringIkiliSayiG + "0";
else if (Bit1G == "1" && Bit2G == "1") StringIkiliSayiG = StringIkiliSayiG + "1";
else StringIkiliSayiG = StringIkiliSayiG + "0";

Bit1B = binarySayi1B.Substring(i, 1);


Bit2B = binarySayi2B.Substring(i, 1);

//AND İŞLEMİ
if (Bit1B == "0" && Bit2B == "0") StringIkiliSayiB = StringIkiliSayiB + "0";
else if (Bit1B == "1" && Bit2B == "1") StringIkiliSayiB = StringIkiliSayiB + "1";
else StringIkiliSayiB = StringIkiliSayiB + "0";

}
R = Convert.ToInt32(StringIkiliSayiR, 2); //İkili sayıyı tam sayıya dönüştürüyor.
G = Convert.ToInt32(StringIkiliSayiG, 2); //İkili sayıyı tam sayıya dönüştürüyor.
B = Convert.ToInt32(StringIkiliSayiB, 2); //İkili sayıyı tam sayıya dönüştürüyor.

CikisResmi.SetPixel(x, y, Color.FromArgb(R, G, B));

}
}
pictureBox3.Image = CikisResmi;
}
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Çıktısı: İki resimdeki yüksek değerli (255) ortak bölgeyi göstermiş oldu. Birinde yüksek diğerinde düşükse onu yok
etti. Her ikisi de düşük olunca zaten yok oldu. Zaten AND operatörünü inceleyecek olursak tablo ile aynı mantığı
burada verdi. Resimler iki renkli olduğu için bu yorumu yapmak kolay oldu, fakat renkli resimlerde bu kadar
değişimi görmek kolay olmayacaktır .

C# Kendi Fonksiyonları ile AND operatörünü kullanma


Aşağıdaki programda AND operatörünü C# kendi fonksiyonları ile nasıl yazıldığını göreceksiniz.
private void btnDENEME_Click(object sender, EventArgs e)
{
Bitmap Resim1 = new Bitmap(pictureBox1.Image);
Bitmap Resim2 = new Bitmap(pictureBox2.Image);

// Görüntülerin boyutlarını kontrol et


if (Resim1.Width != Resim2.Width || Resim1.Height != Resim2.Height)
{
MessageBox.Show("Görüntüler aynı boyutta değil!");
return;
}

// Sonuç görüntüsü için yeni bir bitmap oluştur


Bitmap SonucGoruntusu = new Bitmap(Resim1.Width, Resim1.Height);

// Görüntülerin piksellerini dolaşarak AND operatörü uygula


for (int x = 0; x < Resim1.Width; x++)
{
for (int y = 0; y < Resim1.Height; y++)
{
// İki görüntünün piksellerini al
Color renk1 = Resim1.GetPixel(x, y);
Color renk2 = Resim2.GetPixel(x, y);

// Piksellerin R, G ve B bileşenlerini AND operatörü ile birleştir


Color sonucRenk = Color.FromArgb(
renk1.R & renk2.R,
renk1.G & renk2.G,
renk1.B & renk2.B
);
// Piksellerin R, G ve B bileşenlerini NAND operatörü ile birleştir (NEGATİF SAYI
HATASI VERİYOR)
//Color sonucRenk = Color.FromArgb(
// ~(renk1.R & renk2.R),
// ~(renk1.G & renk2.G),
// ~(renk1.B & renk2.B)
//);

// Piksellerin R, G ve B bileşenlerini OR operatörü ile birleştir


//Color sonucRenk = Color.FromArgb(
// renk1.R | renk2.R,
// renk1.G | renk2.G,
// renk1.B | renk2.B
//);

// Sonuç görüntüsüne pikseli yerleştir


Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

SonucGoruntusu.SetPixel(x, y, sonucRenk);
}
}

// Sonuç görüntüsünü göster


pictureBox3.Image = SonucGoruntusu;

Uygulama 1-İki görüntünün kesişimini bulma

Uygulama 2-Görüntülerden birini maske olarak kullanma

BİT DİLİMLEME
AND operatörü, 8 bitlik bir görüntüde “bit dilimleme” adı verilen işlemi gerçekleştirmek için de kullanılabilir. Belirli
bir bitin görüntü üzerindeki etkisini belirlemek için, ilgili bitin 1'e ve geri kalan 7 bitin 0'a ayarlanır. sabit bir sayı
ile bitsel bir şekilde AND işlemi uygulanır.

Örneğin, görüntünün 8. Bitini (en önemli bite karşılık gelir) işlemi uygularsak ve AND işlemine tabi tuttuktan sonra
128 değeri ile eşiklersek arşağıdaki ikinci görüntüyü elde ederiz.
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Aşağıdaki resimler sırasıyla görüntünün 7., 6., 4., 1. bit düzlemlerine uygulanan işlemlere karşılık gelir. Görüntü
bilgisinin daha çok yüksek değerli bitlerde olduğu görülecektir. Daha az anlamlı bitler daha ince detayları yada
paraziti içerir.
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Orijinal resim ve 1 kat ölçeklenmiş hali. 0 bit 1x ölçekleme

1. bit 1x ölçekleme ve 3x ölçekleme

2. bit 5x öçekleme

3 Bit 10x ölçekleme


Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

4 bit 20x

5 bit 50x

6 bit 100x
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

7 200x

private void BIT_DILIMLEME_Click(object sender, EventArgs e)


{

Bitmap Resim1, CikisResmi;


Resim1 = new Bitmap(pictureBox1.Image);

int ResimGenisligi = 400;


int ResimYuksekligi = 250;

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

Color Renk1;
int x, y;
int R = 0, G = 0, B = 0;

for (x = 0; x < ResimGenisligi; x++) //Resmi taramaya şablonun yarısı kadar dış kenarlardan
içeride başlayacak ve bitirecek.
{
for (y = 0; y < ResimYuksekligi; y++)
{
Renk1 = Resim1.GetPixel(x, y);
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

string binarySayi1R = Convert.ToString(Renk1.R, 2).PadLeft(8, '0'); //Gri renk


olduğundan tek kanal üzerinden yapılıyor.

string binarySayi1G = Convert.ToString(Renk1.G, 2).PadLeft(8, '0'); //Gri renk


olduğundan tek kanal üzerinden yapılıyor.

string binarySayi1B = Convert.ToString(Renk1.B, 2).PadLeft(8, '0'); //Gri renk


olduğundan tek kanal üzerinden yapılıyor.

string Bit1R = null, Bit1G = null, Bit1B = null;


string StringIkiliSayiR = null, StringIkiliSayiG = null, StringIkiliSayiB = null;

int BitSiraNo = Convert.ToInt32(textBox1.Text);

for (int i = 0; i < 8; i++)


{
if (i == BitSiraNo)
{
Bit1R = binarySayi1R.Substring(i, 1);
StringIkiliSayiR = StringIkiliSayiR + Bit1R;

Bit1G = binarySayi1G.Substring(i, 1);


StringIkiliSayiG = StringIkiliSayiG + Bit1G;

Bit1B = binarySayi1B.Substring(i, 1);


StringIkiliSayiB = StringIkiliSayiB + Bit1B;

}
else
{
StringIkiliSayiR = StringIkiliSayiR + "0";
StringIkiliSayiG = StringIkiliSayiG + "0";
StringIkiliSayiB = StringIkiliSayiB + "0";
}

}
R = Convert.ToInt32(StringIkiliSayiR, 2); //İkili sayıyı tam sayıya dönüştürüyor.
G = Convert.ToInt32(StringIkiliSayiG, 2); //İkili sayıyı tam sayıya dönüştürüyor.
B = Convert.ToInt32(StringIkiliSayiB, 2); //İkili sayıyı tam sayıya dönüştürüyor.

int Olcek = Convert.ToInt32(textBox2.Text);

R = R * Olcek;
G = G * Olcek;
B = B * Olcek;

if (R > 255) R = 255;


if (G > 255) G = 255;
if (B > 255) B = 255;

CikisResmi.SetPixel(x, y, Color.FromArgb(R, G, B));

}
}
pictureBox3.Image = CikisResmi;

}
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Sabit Sayı ile AND leme

Aşağıdaki resmi çeşitli sabit sayılar ile AND işlemine tabi tutarsak şu sonuçları elde ederiz. Sayı küçük iken görüntü
koyu olduğu için görebilmek için ölçeklemek gerekmiştir.

1 sayısı ile AND leme ve 1x Ölçekleme 1 sayısı ile AND leme ve 255x Ölçekleme
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

15 sayısı ile AND leme ve 10x Ölçekleme 100 sayısı ile AND leme ve 1x Ölçekleme

230 sayısı ile AND leme ve 1x Ölçekleme 250 sayısı ile AND leme ve 1x Ölçekleme

Benzer şekilde 0 sayısı ile AND leme yaparsak tamamen siyah resim, 255 sayısı ile AND leme yaparsak tamamen
Orijinal resmi elde ederiz.

private void ANDSabitSayiToolStripMenuItem_Click(object sender, EventArgs e)


{
Bitmap Resim1, Resim2, CikisResmi;
Resim1 = new Bitmap(pictureBox1.Image);

int ResimGenisligi = Resim1.Width;


int ResimYuksekligi = Resim1.Height;
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi);

Color Renk1;
int x, y;
int R = 0, G = 0, B = 0;

for (x = 0; x < ResimGenisligi; x++) //Resmi taramaya şablonun yarısı kadar dış kenarlardan
içeride başlayacak ve bitirecek.
{
for (y = 0; y < ResimYuksekligi; y++)
{
Renk1 = Resim1.GetPixel(x, y);

string binarySayi1 = Convert.ToString(Renk1.R, 2).PadLeft(8, '0'); //Gri renk


olduğundan tek kanal üzerinden yapılıyor.

int SabitSayi = Convert.ToInt32(txtDeger1.Text);


string binarySayi2 = Convert.ToString(SabitSayi, 2).PadLeft(8, '0');

string Bit1 = null, Bit2 = null, StringIkiliSayi = null;

for (int i = 0; i < 8; i++)


{
Bit1 = binarySayi1.Substring(i, 1);
Bit2 = binarySayi2.Substring(i, 1);

//AND İŞLEMİ
if (Bit1 == "0" && Bit2 == "0") StringIkiliSayi = StringIkiliSayi + "0";
else if (Bit1 == "1" && Bit2 == "1") StringIkiliSayi = StringIkiliSayi + "1";
else StringIkiliSayi = StringIkiliSayi + "0";

}
R = Convert.ToInt32(StringIkiliSayi, 2); //İkili sayıyı tam sayıya dönüştürüyor.

int Olcek = Convert.ToInt32(txtDeger2.Text);


R = R * Olcek;

//Sınırı aşan değerleri 255 ayarlama


if (R > 255) R = 255;
if (G > 255) G = 255;
if (B > 255) B = 255;

CikisResmi.SetPixel(x, y, Color.FromArgb(R, R, R)); //Gri resim

}
}
pictureBox2.Image = CikisResmi;

0
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

50 100

150 200

Mantıksal OR/NOR Operatörleri


Doğrulama tabloları aşağıda gösterilmiştir. Görüleceği gibi her ikisi birbirinin tam tersidir. Her iki operatörde
yukarıda olduğu gibi iki tane gri seviye resmi alıp bundan üçüncü bir resim üretir. Okunan her gri renk değeri 8 bit
ikili sayı sistemine çevrilerek karşılıklı bitler OR yada NOR işlemine tabi tutulur.

OR/NOR operatörü nerede kullanılır?


Görüntü işleme alanında, OR operatörü genellikle görüntüler arasında piksel bazında birleştirme veya bölge
genişletme gibi işlemlerde kullanılır. İşte bazı örnekler:
Piksel birleştirme: İki veya daha fazla görüntüyü piksel bazında birleştirmek için OR operatörü kullanılabilir. Bu
işlemde, iki görüntünün aynı konumdaki pikselleri OR operatörü ile birleştirilir ve sonuç görüntüsünde her iki
pikselin değeri de korunur.
Bölge genişletme: Bir görüntüdeki belirli bir bölgeyi genişletmek veya büyütmek için OR operatörü kullanılabilir.
Bu işlemde, bir başlangıç noktası olarak seçilen piksel, etrafındaki benzer pikselleri belirli bir eşik değeriyle
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

karşılaştırarak genişletilecek bölgeyi belirler. OR operatörü, bu benzer pikselleri birleştirerek bölgenin


genişletilmesini sağlar.
Görüntü maskeleri: OR operatörü, görüntü maskelerini birleştirmek veya uygulamak için kullanılabilir. Bir maske,
belirli bir özellik veya bölgeyi temsil eden piksellerden oluşan bir görüntüdür. OR operatörü, farklı maskeleri
birleştirerek birden fazla özelliği veya bölgeyi temsil eden pikselleri korur.
Bu örnekler, görüntü işleme uygulamalarında OR operatörünün yaygın olarak kullanıldığı bazı senaryoları
göstermektedir. Ancak, OR operatörü, diğer görüntü işleme işlemlerinde de farklı şekillerde kullanılabilir.

OR Uygulamaları

private void btnDENEME_Click(object sender, EventArgs e)


{
Bitmap Resim1 = new Bitmap(pictureBox1.Image);
Bitmap Resim2 = new Bitmap(pictureBox2.Image);

// Görüntülerin boyutlarını kontrol et


if (Resim1.Width != Resim2.Width || Resim1.Height != Resim2.Height)
{
MessageBox.Show("Görüntüler aynı boyutta değil!");
return;
}

// Sonuç görüntüsü için yeni bir bitmap oluştur


Bitmap SonucGoruntusu = new Bitmap(Resim1.Width, Resim1.Height);

// Görüntülerin piksellerini dolaşarak AND operatörü uygula


for (int x = 0; x < Resim1.Width; x++)
{
for (int y = 0; y < Resim1.Height; y++)
{
// İki görüntünün piksellerini al
Color renk1 = Resim1.GetPixel(x, y);
Color renk2 = Resim2.GetPixel(x, y);

// Piksellerin R, G ve B bileşenlerini OR operatörü ile birleştir


Color sonucRenk = Color.FromArgb(
renk1.R | renk2.R,
renk1.G | renk2.G,
renk1.B | renk2.B
);

// Sonuç görüntüsüne pikseli yerleştir


SonucGoruntusu.SetPixel(x, y, sonucRenk);
}
}

// Sonuç görüntüsünü göster


pictureBox3.Image = SonucGoruntusu;

Maske olarak kullanımı


Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

İki görüntüyü birleştirme

OR ile Bölge Genişletme


private void btnDENEME_Click(object sender, EventArgs e)
{
// Görüntüyü yükle
Bitmap image = new Bitmap(pictureBox1.Image);

// Yeni bir bitmap oluştur


Bitmap dilatedImage = new Bitmap(image.Width, image.Height);

// Genişletme için kullanılacak yapılandırma elemanı


int structuringElementSize = 3; // Yapılandırma elemanının boyutu (örneğin, 3x3)

// Pikselleri dolaşarak bölge genişletme yap


for (int x = structuringElementSize / 2; x < image.Width - structuringElementSize / 2; x++)
{
for (int y = structuringElementSize / 2; y < image.Height - structuringElementSize / 2;
y++)
{
// Pikselin etrafındaki yapılandırma elemanına bakarak bölge genişletme yap
bool isDilated = false;

for (int i = -structuringElementSize / 2; i <= structuringElementSize / 2; i++)


{
for (int j = -structuringElementSize / 2; j <= structuringElementSize / 2; j++)
{
Color neighborPixel = image.GetPixel(x + i, y + j);

if (neighborPixel.GetBrightness() > 0)
{
isDilated = true;
break;
}
}

if (isDilated)
break;
}

// Genişletilmiş pikseli yerleştir


if (isDilated)
dilatedImage.SetPixel(x, y, Color.White);
else
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

dilatedImage.SetPixel(x, y, Color.Black);
}
}

// Genişletilmiş görüntüyü kaydet


pictureBox2.Image = dilatedImage;

Bu kod, "image.jpg" adlı bir görüntüyü yükler. Ardından, dilatedImage adlı yeni bir görüntü oluşturulur ve pikselleri
dolaşarak her pikselin etrafındaki yapılandırma elemanına (structuring element) bakarak bölge genişletme işlemi
yapar. Bölge genişletme, pikselin etrafındaki yapılandırma elemanında en az bir beyaz (parlaklık değeri 0'dan
büyük) piksel varsa, pikseli beyaz yapar; aksi takdirde, pikseli siyah yapar. Bu işlem, görüntü üzerinde beyaz
bölgeleri genişletir ve siyah bölgeleri daraltır. Sonuç olarak, "dilated_image.jpg" adıyla genişletilmiş görüntü
kaydedilir.
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Mantıksal XOR/XNOR Operatörleri

XOR operatörü nerede kullanılır? (GPT)


Görüntü işleme alanında, XOR (exclusive OR) operatörü genellikle görüntüler arasında farklılık analizi, kenar tespiti
veya renk efektleri gibi işlemlerde kullanılır. İşte bazı örnekler:
Farklılık analizi: İki görüntü arasındaki farkları analiz etmek için XOR operatörü kullanılabilir. XOR operatörü, her
iki görüntünün aynı konumdaki piksellerini karşılaştırır ve farklı olan pikselleri belirgin hale getirir. Bu şekilde, iki
görüntü arasındaki farklı bölgeleri vurgulamak veya çıkarmak için XOR operatörü kullanılabilir.
Kenar tespiti: XOR operatörü, kenar tespiti algoritmalarında kullanılabilir. Bir görüntünün kenarlarını tespit etmek
için, görüntüdeki her pikseli çevresindeki piksellerle XOR operatörü ile karşılaştırabilirsiniz. Bu işlem, piksellerin
benzerliklerini analiz ederek kenarlara karşılık gelen farklı pikselleri belirler.
Renk efektleri: XOR operatörü, renk efektleri oluşturmak için de kullanılabilir. Örneğin, bir görüntünün pikselleri
ile sabit bir renk değeri arasında XOR operatörü uygulanabilir. Bu, görüntüye ilginç ve dikkat çekici renkli efektler
eklemek için kullanılabilir.
Bu örnekler, görüntü işleme uygulamalarında XOR operatörünün yaygın olarak kullanıldığı bazı senaryoları
göstermektedir. Ancak, XOR operatörü, diğer görüntü işleme işlemlerinde de farklı şekillerde kullanılabilir.

XoR ile Kenar Tespiti Yapan Algoritma


private void DENEME2_Click(object sender, EventArgs e)
{
// Görüntüyü yükle
Bitmap image = new Bitmap(pictureBox1.Image);

// Yeni bir bitmap oluştur


Bitmap edgeImage = new Bitmap(image.Width, image.Height);

// Pikselleri dolaşarak kenar tespiti yap


for (int x = 1; x < image.Width - 1; x++)
{
for (int y = 1; y < image.Height - 1; y++)
{
// Pikselin etrafındaki komşu pikselleri al
Color pixel = image.GetPixel(x, y);
Color leftPixel = image.GetPixel(x - 1, y);
Color rightPixel = image.GetPixel(x + 1, y);
Color topPixel = image.GetPixel(x, y - 1);
Color bottomPixel = image.GetPixel(x, y + 1);

// Piksellerin R, G ve B değerlerini XOR operatörü ile karşılaştır


bool isEdgePixel = (pixel.R ^ leftPixel.R) > 128 ||
(pixel.R ^ rightPixel.R) > 128 ||
(pixel.R ^ topPixel.R) > 128 ||
(pixel.R ^ bottomPixel.R) > 128;

// Eğer kenar pikseli ise beyaz yap, değilse siyah yap


Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

if (isEdgePixel)
edgeImage.SetPixel(x, y, Color.White);
else
edgeImage.SetPixel(x, y, Color.Black);
}
}

// Kenar tespiti yapılan görüntüyü kaydet


pictureBox2.Image = edgeImage;
}

Bu kod, "image.jpg" adlı bir görüntüyü yükler. Ardından, edgeImage adlı yeni bir görüntü oluşturulur ve pikselleri
dolaşarak her pikselin etrafındaki komşu pikselleri alır. Daha sonra, piksellerin R (kırmızı) bileşenlerini XOR
operatörü ile karşılaştırarak kenar piksellerini belirler. Eğer XOR işlemi sonucu elde edilen değer 128'den büyük
ise piksel kenar pikseli olarak kabul edilir. Kenar pikselleri beyaz yapılır, diğer pikseller siyah yapılır. Sonuç olarak,
"edge_image.jpg" adıyla kenar tespiti yapılan görüntü kaydedilir.
Bu kod örneği, basit bir kenar tespiti algoritmasıdır ve çıktıda yalnızca yatay ve dikey kenarlar belirginleştirilir.
Daha gelişmiş kenar tespiti algoritmaları, farklı filtreler veya yöntemler kullanarak daha hassas sonuçlar elde
edebilir.

XoR ile İki Resimde Farklı Bölgeleri Tespit Etme

private void btnDENEME_Click(object sender, EventArgs e)


{
Bitmap Resim1 = new Bitmap(pictureBox1.Image);
Bitmap Resim2 = new Bitmap(pictureBox2.Image);

// Görüntülerin boyutlarını kontrol et


if (Resim1.Width != Resim2.Width || Resim1.Height != Resim2.Height)
{
MessageBox.Show("Görüntüler aynı boyutta değil!");
return;
}

// Sonuç görüntüsü için yeni bir bitmap oluştur


Bitmap SonucGoruntusu = new Bitmap(Resim1.Width, Resim1.Height);

// Görüntülerin piksellerini dolaşarak AND operatörü uygula


for (int x = 0; x < Resim1.Width; x++)
{
for (int y = 0; y < Resim1.Height; y++)
{
// İki görüntünün piksellerini al
Color pixel1 = Resim1.GetPixel(x, y);
Color pixel2 = Resim2.GetPixel(x, y);
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

// Piksellerin R, G ve B değerlerini XOR operatörü ile karşılaştır


bool isDifferent = (pixel1.R ^ pixel2.R) > 128 ||
(pixel1.G ^ pixel2.G) > 128 ||
(pixel1.B ^ pixel2.B) > 128;

// Eğer pikseller farklı ise beyaz yap, değilse siyah yap


if (isDifferent)
SonucGoruntusu.SetPixel(x, y, Color.White);
else
SonucGoruntusu.SetPixel(x, y, Color.Black);
}
}

// Sonuç görüntüsünü göster


pictureBox3.Image = SonucGoruntusu;

Bu kod, "image1.jpg" ve "image2.jpg" adlı iki görüntüyü yükler. Ardından, görüntülerin boyutlarını kontrol eder
ve eşit olduklarını doğrular. Sonuç olarak, diffImage adlı yeni bir görüntü oluşturulur ve pikselleri dolaşarak her iki
görüntünün piksellerini XOR operatörü ile karşılaştırır. XOR operatörü, her iki pikselin R, G ve B bileşenlerini XOR
işlemine tabi tutar. Eğer XOR işlemi sonucu elde edilen değer 128'den büyük ise pikseller farklı olduğu kabul edilir.
Farklı pikseller beyaz yapılır, diğer pikseller siyah yapılır. Sonuç olarak, "diff_image.jpg" adıyla farklılık analizi
yapılan görüntü kaydedilir.

XoR ile Görüntüye Efekt Uygulama

private void DENEME2_Click(object sender, EventArgs e)


{
// Görüntüyü yükle
Bitmap image = new Bitmap(pictureBox1.Image);

// Renk efekti için XOR ile kullanılacak renk değeri


Color effectColor = Color.FromArgb(255, 128, 0); // Örnek olarak turuncu

// Yeni bir bitmap oluştur


Bitmap effectImage = new Bitmap(image.Width, image.Height);

// Pikselleri dolaşarak renk efekti uygula


for (int x = 0; x < image.Width; x++)
{
for (int y = 0; y < image.Height; y++)
{
// Pikselin renk değerini al
Color pixel = image.GetPixel(x, y);

// Pikselin R, G ve B değerlerini XOR operatörü ile belirtilen renkle birleştir


Color resultPixel = Color.FromArgb(
pixel.R ^ effectColor.R,
pixel.G ^ effectColor.G,
pixel.B ^ effectColor.B
);
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

// Efekt uygulanmış pikseli yerleştir


effectImage.SetPixel(x, y, resultPixel);
}
}

// Efekt uygulanmış görüntüyü göster


pictureBox2.Image = effectImage;
}

Bu kod, "image.jpg" adlı bir görüntüyü yükler. Ardından, bir renk efekti oluşturmak için effectColor adlı bir renk
değeri belirler. Sonuç olarak, effectImage adlı yeni bir görüntü oluşturulur ve pikselleri dolaşarak her pikselin R, G
ve B değerlerini XOR operatörü ile effectColor değeriyle birleştirir. Bu işlem, pikselin renk değerleri ile belirtilen
efekt rengi arasında XOR işlemi yaparak yeni bir renk oluşturur. Sonuç olarak, "effect_image.jpg" adıyla efekt
uygulanmış görüntü kaydedilir.

Mantıksal NOT Operatörü (Invert-Tersini alma)

Mantıksal operatörlerden NOT operatörü, görüntü işlemede bazı kullanım örnekleri:


Negatif Görüntü Oluşturma: Görüntünün her pikselinin renk değerlerini tersine çevirmek için NOT operatörü
kullanılabilir. Bu işlem, görüntünün negatifini oluşturarak parlaklık ve kontrastı değiştirir.
Görüntü Binarizasyonu: Görüntüdeki pikselleri siyah ve beyaz olarak ayırmak için eşik değeri kullanılır. NOT
operatörü, eşik değerine göre piksellerin rengini tersine çevirerek binarizasyon işlemini gerçekleştirebilir.
Kenar Tespiti: Kenar tespiti algoritmalarında, görüntü üzerindeki yoğunluk değişimlerini tespit etmek için NOT
operatörü kullanılabilir. Böylece, kenarlar daha belirgin hale gelir ve görüntünün sadece kenarları içeren bir
versiyonu elde edilir.
Gürültü Azaltma: Görüntüdeki gürültüyü azaltmak için bazı filtreler kullanılır. NOT operatörü, görüntünün
negatifini alarak gürültüyü azaltabilir veya belirli bir deseni veya yapıyı ortaya çıkarabilir.
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Bu sadece birkaç örnektir ve NOT operatörü, görüntü işlemede farklı amaçlar için kullanılabilir. Uygulama
senaryosuna ve ihtiyaçlara bağlı olarak farklı kullanımlar da mümkündür.

NOT operatörü ile Kenar Tespiti


private void btnDENEME_Click(object sender, EventArgs e)
{

// Görüntüyü yükle
Bitmap image = new Bitmap(pictureBox1.Image);

// Yeni bir bitmap oluştur


Bitmap edgeImage = new Bitmap(image.Width, image.Height);

// Kenar tespiti için kullanılacak eşik değeri


int threshold = 30;

// Pikselleri dolaşarak kenar tespiti yap


for (int x = 1; x < image.Width - 1; x++)
{
for (int y = 1; y < image.Height - 1; y++)
{
// Pikselin renk değerlerini al
Color pixel = image.GetPixel(x, y);
Color pixelRight = image.GetPixel(x + 1, y);
Color pixelDown = image.GetPixel(x, y + 1);

// Pikselin parlaklık değerlerini hesapla


int brightness = (pixel.R + pixel.G + pixel.B) / 3;
int brightnessRight = (pixelRight.R + pixelRight.G + pixelRight.B) / 3;
int brightnessDown = (pixelDown.R + pixelDown.G + pixelDown.B) / 3;

// Parlaklık farkını hesapla


int differenceX = Math.Abs(brightness - brightnessRight);
int differenceY = Math.Abs(brightness - brightnessDown);

// Eşik değeri ile karşılaştır ve kenar pikseli belirle


if (differenceX > threshold || differenceY > threshold)
{
edgeImage.SetPixel(x, y, Color.Black);
}
else
{
edgeImage.SetPixel(x, y, Color.White);
}
}
}

// Kenar tespit edilmiş görüntü

pictureBox2.Image = edgeImage;

}
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Bu kod, "image.jpg" adlı bir görüntüyü yükler. Ardından, edgeImage adlı yeni bir görüntü oluşturulur ve pikselleri
dolaşarak her pikselin etrafındaki piksellerle parlaklık farkını hesaplar. Parlaklık farkı, pikselin merkezindeki
pikselin parlaklık değeri ile sağdaki veya altındaki pikselin parlaklık değeri arasındaki farktır. Bu fark, belirlenen
eşik değeri (threshold) ile karşılaştırılır ve eşik değerinden büyükse piksel kenar pikseli olarak kabul edilir ve siyah
(Color.Black), değilse beyaz (Color.White) olarak atanır. Bu işlem, kenar tespiti yaparak görüntüdeki kenarları
belirginleştirir. Sonuç olarak, "edge_image.jpg" adıyla kenar tespit edilmiş görüntü kaydedilir. Bu örnekte, eşik
değeri olarak 30 kullanıldı. Siz istediğiniz farklı bir eşik değeriyle (threshold) deneme yaparak kenar tespit
edebilirsiniz

Bitshift (Bit kaydırma) Operatörü

Mantıksal operatörlerden biri olan bit kaydırma (bit shifting) operatörleri, görüntü işleme alanında çeşitli
amaçlarla kullanılabilir. İşte bit kaydırma operatörlerinin bazı kullanım alanları:
Piksel İşleme: Görüntü işleme uygulamalarında, piksel değerlerini manipüle etmek için bit kaydırma operatörleri
kullanılabilir. Örneğin, bir görüntünün parlaklık değerlerini artırmak veya azaltmak için piksel değerlerini sola veya
sağa kaydırarak işlemler yapılabilir.
Maskeleme (Masking): Maskeleme işlemlerinde, belirli bir desenin veya maskeyi görüntü üzerinde uygulamak için
bit kaydırma operatörleri kullanılabilir. Maskeleme, belirli bir desenin belirli bölgeleri seçmek veya gizlemek için
kullanılır.
Kenar Tespiti: Kenar tespiti işlemlerinde, görüntünün kenarlarını belirlemek için bit kaydırma operatörleri
kullanılabilir. Özellikle Canny kenar tespiti gibi algoritmalarda, kenarları belirlemek için bit kaydırma operatörleri
kullanılan filtreler bulunur.
Örtüşme (Overlap): Bazı görüntü işleme işlemlerinde, iki veya daha fazla görüntüyü birleştirirken bit kaydırma
operatörleri kullanılabilir. Örneğin, iki görüntünün piksellerini birleştirmek veya üst üste bindirmek için bit
kaydırma operatörleri kullanılabilir.
İşaretçi Operasyonları: Görüntü işleme uygulamalarında, bellek manipülasyonu için işaretçi operasyonları
kullanılır. Bit kaydırma operatörleri, bellek adreslerini hesaplarken veya veri bloklarını işaretçi aracılığıyla taşırken
kullanılabilir.
Bu sadece bazı örneklerdir ve bit kaydırma operatörleri daha geniş bir şekilde görüntü işleme alanında
kullanılabilir. Uygulamanıza ve kullanım senaryonuza bağlı olarak, bit kaydırma operatörlerini farklı şekillerde
kullanabilirsiniz.

İşlem, tek bir geçişte doğrudan gerçekleştirilir. Bir sayının ikili gösterimi bir yönde kaydırılırsa, karşı tarafta boş bir
konum elde ederiz. Bu boş pozisyonun nasıl doldurulacağına dair genellikle üç olasılık vardır: boş bitleri 0 veya 1
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

ile doldurabiliriz veya diğer taraftaki sayının ikili gösteriminden kaydırılan bitleri sarabiliriz. Son olasılık, ikili sayıyı
döndürmeye eşdeğerdir.
Kullanılan tekniğin seçimi operatörün uygulamasına ve uygulamaya bağlıdır. Çoğu durumda, hızlı bir çarpma veya
bölme gerçekleştirmek için bit kaydırma kullanılır. Bu uygulama için doğru sonuçları elde etmek için boş bitleri 0
ile doldurmamız gerekir. Sadece negatif bir sayının 2'ye bölünmesi durumunda sol bitleri 1 ile doldurmamız
gerekir, çünkü negatif bir sayı, pozitif sayının ikiye tümleyeni olarak temsil edilir, yani işaret biti 1'dir. Bu şekilde
bit kaydırma uygulamanın sonucu aşağıdaki formülde gösterilmektedir:

Çarpma ve bölme için bit kaydırma kullanımına örnekler. Alttaki örneğin, bir baytın -128 ile +127 arasında bir sayıyı
temsil ettiği bir imzalı bayt kuralı kullandığını unutmayın.

private void btnDENEME_Click(object sender, EventArgs e)


{
// Görüntüyü sola kaydır
int shiftAmount = -5;

// Görüntüyü yükle
Bitmap image = new Bitmap(pictureBox1.Image);

// Yeni bir bitmap oluştur


Bitmap shiftedImage = new Bitmap(image.Width, image.Height);

// Pikselleri dolaşarak kaydırma işlemini yap


for (int x = 0; x < image.Width; x++)
{
for (int y = 0; y < image.Height; y++)
{
// Pikselin renk değerini al
Color pixel = image.GetPixel(x, y);

// Renk değerlerini sola kaydır


int red = pixel.R << shiftAmount;
int green = pixel.G << shiftAmount;
int blue = pixel.B << shiftAmount;

// Renk değerlerini sınırla (0-255 aralığında)


red = Math.Max(0, Math.Min(red, 255));
green = Math.Max(0, Math.Min(green, 255));
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

blue = Math.Max(0, Math.Min(blue, 255));

// Kaydırılmış pikseli ata


Color shiftedPixel = Color.FromArgb(red, green, blue);
shiftedImage.SetPixel(x, y, shiftedPixel);
}
}

pictureBox2.Image = shiftedImage;

Bit kaydırma ile Örnek Overlap (Örtüşme) yapan kod.


private void DENEME2_Click(object sender, EventArgs e)
{
// İlk görüntüyü yükle
Bitmap image1 = new Bitmap(pictureBox1.Image);

// İkinci görüntüyü yükle


Bitmap image2 = new Bitmap(pictureBox2.Image);

// Örtüşme işlemi için kullanılacak kaydırma miktarı


int shiftAmount = 50;

// İlk görüntüyü sola kaydır


Bitmap shiftedImage1 = ShiftImage(image1, -shiftAmount);

// İkinci görüntüyü sağa kaydır


Bitmap shiftedImage2 = ShiftImage(image2, shiftAmount);

// İki görüntüyü birleştir


Bitmap overlappedImage = OverlapImages(shiftedImage1, shiftedImage2);

// Örtüşme sonucunu kaydet


pictureBox3.Image = overlappedImage;
}
static Bitmap ShiftImage(Bitmap image, int shiftAmount)
{
// Yeni bir bitmap oluştur
Bitmap shiftedImage = new Bitmap(image.Width, image.Height);

// Pikselleri dolaşarak kaydırma işlemini yap


for (int x = 0; x < image.Width; x++)
{
for (int y = 0; y < image.Height; y++)
{
// Pikselin renk değerini al
Color pixel = image.GetPixel(x, y);
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

// Renk değerlerini kaydır


int red = pixel.R << shiftAmount;
int green = pixel.G << shiftAmount;
int blue = pixel.B << shiftAmount;

// Renk değerlerini sınırla (0-255 aralığında)


red = Math.Max(0, Math.Min(red, 255));
green = Math.Max(0, Math.Min(green, 255));
blue = Math.Max(0, Math.Min(blue, 255));

// Kaydırılmış pikseli ata


Color shiftedPixel = Color.FromArgb(red, green, blue);
shiftedImage.SetPixel(x, y, shiftedPixel);
}
}

return shiftedImage;
}

static Bitmap OverlapImages(Bitmap image1, Bitmap image2)


{
// Yeni bir bitmap oluştur
Bitmap overlappedImage = new Bitmap(image1.Width, image1.Height);

// Pikselleri dolaşarak örtüşme işlemini yap


for (int x = 0; x < image1.Width; x++)
{
for (int y = 0; y < image1.Height; y++)
{
// İlk görüntünün pikselini al
Color pixel1 = image1.GetPixel(x, y);

// İkinci görüntünün pikselini al


Color pixel2 = image2.GetPixel(x, y);

// Pikselleri topla
int red = pixel1.R + pixel2.R;
int green = pixel1.G + pixel2.G;
int blue = pixel1.B + pixel2.B;

// Renk değerlerini sınırla (0-255 aralığında)


red = Math.Max(0, Math.Min(red, 255));
green = Math.Max(0, Math.Min(green, 255));
blue = Math.Max(0, Math.Min(blue, 255));

// Birleştirilmiş pikseli ata


Color overlappedPixel = Color.FromArgb(red, green, blue);
overlappedImage.SetPixel(x, y, overlappedPixel);
}
}

return overlappedImage;
}
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

******************** 000 *******************


Ödev1: Mantıksal Operatörlerin günlük yaşamda kullanıldığı bir alanı bulun, programlayın.
Ödev 2: 0 bitlerle oluşan resimden 5 bitlerle oluşan resmi çıkarma ve ekleme yaparak yeni görüntüler elde edin.
Ödev 3: Normalde 0 biti yansıtıp diğerlerini yansıtmadık. Bunun tarsi olabilir. 0 biti yansıtma diğerlerini yansıt.
Ödev 4: Bitshıft (Kaydırma) İşlemini Ödev Olarak Deneyin…

Ödev 5: Resmi anahtar resim ve anahtar sayı ile şifreleyerek gönderme: Bir resmin internet üzerinden gizlenip
gönderilmesi için örnek bir algoritma geliştirin. Resmi başka bir anahtar resimle bit işlemlerine tabi tutun. Resmi
alan kişinin elinde anahtar resim bulunsun. O anahtar resmi kullanarak gizlenen resmi tekrar orijinal haline
dönüştürebilsin.
Gizlenecek Resim

Anahtar resim

Gizlenmiş resim (başkaları resmi anlayamayacak şekilde karışmış olacak)

Gizlenmiş resim anahtar resimle çözülünce tekrar bu resim elde edilecek.


Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

GÖRÜNTÜ İŞLEME-11.HAFTA

HOUGH DÖNÜŞÜM ALGORİTMASI (Doğru, Daire Elipslerin vb tespiti)

İçindekiler
GÖRÜNTÜ İŞLEME-11.HAFTA .................................................................................................................................... 1
HOUGH DÖNÜŞÜM ALGORİTMASI (Doğru, Daire Elipslerin vb tespiti) .................................................................... 1
KARTEZYEN KOORDİNATLARDA BİR DOĞRUNUN TESPİTİ ..................................................................................... 2
Sayısal Örnek: .................................................................................................................................................... 3
DOĞRUNUN DENKLEMİNİ POLAR KOORDİNATLARDA OLUŞTURMA .................................................................... 4
Doğrunun Tespiti Programı ............................................................................................................................. 11
HOUGH TRANSFORM: CIRCLE DETECTİON .......................................................................................................... 21
Usıng Gradient Informatıon............................................................................................................................. 24
Circle Detection: R Is Not Known..................................................................................................................... 25
Referanslar....................................................................................................................................................... 26

Aşağıdaki bir resim üzerinde bisikletin tekerini oluşturan daireyi oluşturan formülasyonu bulmak istiyoruz. Yani
noktalardan oluşan bir resmin matematiğini elde etmek istiyoruz. Bunu başarabilirsek artık o bilgiyi bir çok yerde
kullanabiliriz. Artık dairenin alanını, çapını, çevresini bulabiliriz. Üzerinde eksik noktalar varsa onları tamamlayıp
yeniden çizebiliriz gibi onlarca amaç için kullanabiliriz.

Klasik Hough dönüşüm (Classical Hough transform) algoritması en yaygın olarak parametrik ifade edilebilen
doğru, daire ve elips gibi düzenli eğrileri tespit için kullanılır. Daha karmaşık bir hesaplama tekniği olan
Genelleştirilmiş Hough Algoritması (Generalized Hough algorithm) burada ele alınmayacaktır. Bu algoritmanın
en büyük avantajı resim üzerindeki boşluk ve gürültülere karşı toleranslı olmasıdır.
Bir resim içerisinde yerel olarak birbirinden bağımsız nokta (point) ve çizgiler (edge) bulunur. Bunlar içinden
hangileri bir cismin kenarına (boundary) aittir bunun belirlenmesi bu algoritmada ana hedefimizdir.
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Burada sınırları tespit edilen şeklin matematiksel modelinin (formülünün) çıkarılması esas amaçtır. Yani bitmap
bir resmi (piksellerden oluşan bir resmi), vektörel (matematiksel formülle saklanan) bir resme dönüştürmek
yapılmak istenen işlemdir. Bunun için hedeflenen cismin şekli önceden biliniyorsa bilginin çıkarılması daha
kolaydır. Yani önceden resimde daire yada line olduğu biliniyorsa buna uygun arama yapmak işi kolaylaştırır.
Eğer cismin ne olduğu bilinmiyorsa o zaman kenarları oluşturan parçalar bir seri olarak bulunup, ortaya çıkan
eğri gösterilebilir.
Aşağıdaki resmi incelediğimizde 4 noktanın hangi çizgilere ait olduğunu belirlemeye çalışsak, çok sayıda çizgi
olasılığı ortaya çıkacaktır.

Herhangi bir noktanın muhtemel bir çizgiye ait olması durumunda bu çizgiyi iki şekilde resim üzerinde
gösterebiliriz. (x,y) koordinatı çizgi üzerinde herhangi bir noktayı gösteriyorsa parametrik olarak kartezyen ve
Polar koordinatlar olarak gösterebiliriz.

KARTEZYEN KOORDİNATLARDA BİR DOĞRUNUN TESPİTİ


Aşağıdaki resimde verildiği gibi birbirinden bağımsız yerleştirilmiş noktalardan oluşan bir resim olsun. Bu
noktaların içinde düz bir şekilde sıralanmış noktalardan bir doğruyu tespit etmeye çalışalım. Doğrunun denklemi
kartezyen koordinatlarda y=mx + c şeklinde tarif edilebilir. Burada m doğrunun eğimi, c ise bir sabittir.

Bu noktaların bulunduğu konumlar resim üzerinde (uzayında) aşağıdaki gibi gösterilebilir. Her bir nokta sonsuza
giden bir çizginin üzerindeki bir konumu temsil edecektir. Buradaki x ve y koodinatları değiştirilerek çizgi sonsuza
kadar çizilebilir.

Bu sefer denklemimizi x-y ortamından (resim uzayından) parametrelerin olduğu c-m ortamına (parametre
uzayına) dönüştürelim. Bu durumda denklemimiz y=mx + c iken c=-mx + y şekline dönüşmüş olacaktır.
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Resim üzerindeki iki noktayı alalım. Bu noktalara ait denklemleri x,y uzayından m,c uzayına dönüştürelim. Eğer A
ve B noktası ayrık uzayda (resim uzayında) (spatial domain) iki tane birbirine bağlı nokta ise bu noktalara ait
oluşturulan yeni m,c uzayındaki doğruların denklemi m,c uzayında (parametre uzayı yada Hough uzayı denir)
birbirini kesecektir.

Benzer şekilde çok sayıda sıralanmış noktalar (m,c) uzayında herbiri bir çizgiye karşılık gelir ve bunların (c=-mx +
y) denklemi içindeki m ve c değerleri aynı olacağından bu nokta üzerinde kesişeceklerdir. Farklı bir yerde
bulunan bir noktaya ait çizgi ise bu ortak noktadan geçmeyecektir.

(m,c) uzayında kesişen noktaların sayısı iki boyutlu bir dizi içinde tutulursa ortaya çıkan en yüksek değerli dizi
elemanına ait m ve c değerleri resim uzayında (x,y) bir çizginin fonksiyonundaki m ve c katsayıları olacaktır.
Böylece aranan doğrunun denklemi y=mx + c şeklinde bulunmuş olacaktır. Dizi üzerindeki elemanların
büyüklükleri belli bir eşik değer kullanılırsa az sayıda kesişimi gösteren değerler elenebilir. Böylece resim
uzayında çok kısa çizgileri ele alınmamış olur.

Sayısal Örnek:
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Noktalarımızı denklemlerde yerine korsak m,c uzayındaki denklemlerizi buluruz

Bu durumda m,c uzayında doğrularımızı oluşturan noktalar


olur. Bu noktalar birer m,c uzayında birer doğruyu gösterir. Bu üç tane doğrunun kesiştiği nokta (m,c) = (1,1)
noktasıdır. Bu nokta bize aradığımız resim uzayındaki doğrunun denklemini yani y=mx+c den y=x+1 verecektir.

DOĞRUNUN DENKLEMİNİ POLAR KOORDİNATLARDA OLUŞTURMA

Denklemlerde bu formül kullanıldı..


Soru(GPT):Aşağıdaki gibi elimizde iki tane denklem var. Bu iki denklemin ortak parametresi olan θ ve ρ
çözüm kümesini nasıl bulabilirim? ρ = x1 cos(θ)+y1 sin(θ) , ρ =x2 cos(θ)+y2 sin(θ)
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Cevap (GPT):
Verilen denklemlerde θ ve ρ'nin çözüm kümesini bulmak için denklemleri birleştirebiliriz:
x1 cos(θ) + y1 sin(θ) = x2 cos(θ) + y2 sin(θ)
Burada θ'yi yalnız bırakıp denklemi çözebiliriz:
x1 cos(θ) - x2 cos(θ) = y2 sin(θ) - y1 sin(θ)
( x1 - x2 ) cos(θ) = ( y2 - y1 ) sin(θ)
sin(θ) / cos(θ) = ( x1 - x2 ) /( y2 - y1 )
tan(θ) = ( x1 - x2 ) /( y2 - y1 )

θ = atan( ( x1 - x2 ) /( y2 - y1 ))

Burada atan, arktanjant fonksiyonunu temsil eder. θ'nin değerini bu şekilde bulabiliriz.
Elde edilen θ değerini herhangi bir denklemde kullanarak ρ'yı bulabiliriz. Örneğin, ilk denklemi kullanarak ρ'yı
bulmak için:
ρ = x1 cos(θ)+y1 sin(θ)
Bu şekilde θ ve ρ'nin çözüm kümesini bulabilirsiniz.

Grafiği döngü kullanarak noktalar ile çizdirirsek şu formüllü kullanabiliriz.

=>
Üstteki formül programda x ekseni boyunca tarama yaparak çizilir. Fakat teta sıfır olursa hata verir. Bu durumda
yani dikey çizgilerde formül değiştirilip tarama ekseni y boyunca olmalıdır. Bu durumda şu formülü kullanabiliriz.

=>
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Doğrunun Tespiti Programı

using System;
using System.Collections;
using System.Drawing;
using System.Windows.Forms;
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

namespace Uygulama1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)


{
this.WindowState = FormWindowState.Maximized;

CizimAlani1 = pictureBox1.CreateGraphics();
CizimAlani2 = pictureBox2.CreateGraphics();

pictureBox1.Image = Image.FromFile("C:/Users/pc1/Pictures/1.bmp"); //varsayılan


resim olarak siyah zeminli bir resim yükleniyor.

//HOUGH ALGORİTMASI .****** x*cos(o) + y*sin(o) =r FONKSİYONU kullanılıyor.


private void btnRESMIYENIDENYUKLE_Click(object sender, EventArgs e)
{
// Grafik Çizimi yapmadan önce çizim alanını temizle
pictureBox2.Invalidate();

pictureBox1.Image = Image.FromFile("C:/Users/pc1/Pictures/1.bmp"); //varsayılan


resim olarak yükleniyor.
}

//AAA------PICTUREBOX TIKLANAN NOKTALARI RESİM İÇİNE EKLİYOR-------------------


private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
int FareX = e.X;
int FareY = e.Y;

Color OkunanRenk, DonusenRenk;


int R = 0; //, G = 0, B = 0; //tek renk çalışılacak.
Bitmap GirisResmi = new Bitmap(pictureBox1.Image);

int ResimGenisligi = GirisResmi.Width;


int ResimYuksekligi = GirisResmi.Height;

Bitmap CikisResmi = new Bitmap(ResimGenisligi, ResimYuksekligi); //Cikis resmini


oluşturuyor. Boyutları giriş resmi ile aynı olur.

for (int x = 0; x < ResimGenisligi; x++)


{
for (int y = 0; y < ResimYuksekligi; y++)
{
OkunanRenk = GirisResmi.GetPixel(x, y);

R = OkunanRenk.R;

if (FareX == x && FareY == y)


{
DonusenRenk = Color.FromArgb(255, 255, 255);
}
else
{
DonusenRenk = Color.FromArgb(R, R, R);
}

CikisResmi.SetPixel(x, y, DonusenRenk);
}
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

pictureBox1.Image = CikisResmi;

Graphics CizimAlani1, CizimAlani2;

Pen KalemBeyaz = new Pen(System.Drawing.Color.White, 1);


Pen KalemSari = new Pen(System.Drawing.Color.Yellow, 1);
Pen KalemKirmizi = new Pen(System.Drawing.Color.Red, 1);
Pen KalemMavi = new Pen(System.Drawing.Color.Blue, 1);
Pen KalemYesil = new Pen(System.Drawing.Color.Green, 1);
Pen KalemTurkuaz = new Pen(System.Drawing.Color.Cyan, 1);

Brush FircaSari = new SolidBrush(System.Drawing.Color.Yellow);


Brush FircaKirmizi = new SolidBrush(System.Drawing.Color.Red);
Brush FircaMavi = new SolidBrush(System.Drawing.Color.Blue);
Brush FircaYesil = new SolidBrush(System.Drawing.Color.Green);
Brush FircaTurkuaz = new SolidBrush(System.Drawing.Color.Cyan);

private void btnRESIMDEKI_DOGRULARI_BUL_Click(object sender, EventArgs e)


{

//Butona tekrar tıklandığında dizileri sıfırlama yapıyor.


DiziXnoktalari.Clear();
DiziYnoktalari.Clear();

DiziKesisim_Teta.Clear();
DiziKesisim_Ro.Clear();
DiziKesisim_AynisiBulundu.Clear();

DiziRafine_Teta.Clear();
DiziRafine_Ro.Clear();
DiziRafine_TekrarSayisi.Clear();

Dizi_Teta.Clear();
Dizi_Ro.Clear();

Bitmap GirisResmi = new Bitmap(pictureBox1.Image);

//*********** ALT İŞLEMLER *********************


//A---------------------
ResimIcindekiBeyazNoktalariDiziyeYukle(GirisResmi); //DiziXnoktalari.Clear();
DiziYnoktalari.Clear();

//B---------------------Grafik Çizdirme
if (ckbSinGrafiginiCizdir.Checked==true)
{
DizidekiNoktalarinSinGrafiginiCiz(); //Sinüs Grafiği--Çalışırsa hesaplamayı
yavaşlatır
}

//C---------------------
KesisimNoktalariniDiziyeAt(); //(teta, ro)

//D---------------------Grafik Çizdirme
if (ckbKesisimNoktalariniCizdir.Checked==true)
{
DizidekiKesisimNoktalariniGrafikteGoster(); //Kesişim noktalarını Grafikte çiz--
-DİREK HESAPLAMADA BURAYI KAPAT--HIZI YAVAŞLATIR
}
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

//E---------------------
KesisimDizisindenTekrarliOlanlariCikarTekrarSayisiniKaydet(); //Tekrarlı noktaları
çıkar

//F---------------------
BelliBirTekrarSayisiUzerindekiNoktalari_TetaRoDizisineAt();

//G---------------------Grafik Çizdirme
if (ckbBelliBirSayininUzerindekiKesisimleriGoster.Checked==true)
{
Belli_Bir_Sayinin_Uzerindeki_Kesisim_Noktalarini_Grafikte_Goster(); //TetaRo
dizisindeki noktalari gösteriyor.

BirbirineYakinNoktalarin_OrtalamaDegerleriniHesapla_BuDegerlerIleDiziyiYenile();

Ortalama_DiziTetaRo_Noktalarini_Grafikte_Goster();

TetaRo_Dizisindeki_Noktalari_XYduzleminde_ForDongusuKullanarakCiz(); //Burada çizgi


döngü ile çizilecek. Böylece ekran dışına çıkan durumlardada çizim yapılmış olacak.

//**************RESİM NOKTALARINI DİZİYE YÜKLÜYOR ******************


ArrayList DiziXnoktalari = new ArrayList();
ArrayList DiziYnoktalari = new ArrayList();
public void ResimIcindekiBeyazNoktalariDiziyeYukle(Bitmap GirisResmi)
{
Color OkunanRenk;
int R = 0;

int ResimGenisligi = GirisResmi.Width;


int ResimYuksekligi = GirisResmi.Height;

for (int x = 0; x < ResimGenisligi; x++)


{
for (int y = 0; y < ResimYuksekligi; y++)
{
OkunanRenk = GirisResmi.GetPixel(x, y);

R = OkunanRenk.R;

if (R > 128) //BEYAZ NOKTA VAR İSE


{
DiziXnoktalari.Add(x);
DiziYnoktalari.Add(y);
}
}
}

listBox1.Items.Add("Resim Nokta Sayisi=" + DiziXnoktalari.Count);


}

//ÖTELEME
int OrijinOtelemeX = 300;
int OrijinOtelemeY = 300;

double OlcekX = 1.2;


double OlcekY = 1;

//************************ SİNÜS GRAFİKLERİNİ ÇİZDİRİYOR


Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

public void DizidekiNoktalarinSinGrafiginiCiz()


{

//******************************
double x = 0, y = 0, TetaRadyan = 0, Ro = 0;

//Eksen takımının yerini gösteriyor..


CizimAlani2.DrawLine(KalemBeyaz, 0, OrijinOtelemeY, pictureBox2.Width,
OrijinOtelemeY);
CizimAlani2.DrawLine(KalemBeyaz, OrijinOtelemeX, 0, OrijinOtelemeX,
pictureBox2.Height);

for (int i = 0; i < DiziXnoktalari.Count; i++)


{
x = Convert.ToDouble(DiziXnoktalari[i]);
y = Convert.ToDouble(DiziYnoktalari[i]);

for (int TetaDerece = -360; TetaDerece <= 360; TetaDerece++)


{
TetaRadyan = (TetaDerece * 2 * Math.PI) / 360; //Dereceyi Radyan a çevir

Ro = x * Math.Cos(TetaRadyan) + y * Math.Sin(TetaRadyan); //ρ = x cos(θ)+y


sin(θ)

//Teta ve Ro ifadeleri x ve y gibi eksenleri gösteriyor


CizimAlani2.FillEllipse(FircaSari, Convert.ToInt16((TetaDerece +
OrijinOtelemeX) * OlcekX), Convert.ToInt16((Ro + OrijinOtelemeY) * OlcekY), 2, 2);
}
}
}

ArrayList DiziKesisim_Teta = new ArrayList();


ArrayList DiziKesisim_Ro = new ArrayList();
ArrayList DiziKesisim_AynisiBulundu = new ArrayList(); //İki döngü iç içe arama yaparken
aynısı bulunanları her seferinde fazladan okumasın diye bir sonraki prosedürde kullanılıyor.

//************************ KESİŞİM NOKTALARINI DİZİYE YÜKLÜYOR


public void KesisimNoktalariniDiziyeAt()
{
int YuvarlatmToleransi_Teta = Convert.ToInt32(txtYuvarlatmaToleransi_Teta.Text);
int YuvarlatmToleransi_Ro = Convert.ToInt32(txtYuvarlatmaToleransi_Ro.Text);

listBox1.Items.Clear();
double x1, y1, x2, y2;

double TetaRadyan = 0;
double TetaDerece = 0;
double Ro = 0;

for (int i = 0; i < DiziXnoktalari.Count; i++)


{
x1 = Convert.ToDouble(DiziXnoktalari[i]);
y1 = Convert.ToDouble(DiziYnoktalari[i]);

for (int j = i + 1; j < DiziXnoktalari.Count; j++)


{
x2 = Convert.ToDouble(DiziXnoktalari[j]);
y2 = Convert.ToDouble(DiziYnoktalari[j]);

//İKİ DENKLEMİN ORTAK ÇÖZÜM KÜMESİ BULUNUYOR.


TetaRadyan = Math.Atan((x1 - x2) / (y2 - y1)); //Radyan cinsinden Teta

Ro = x1 * Math.Cos(TetaRadyan) + y1 * Math.Sin(TetaRadyan);
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

TetaDerece = 360 * TetaRadyan / (2 * Math.PI); //Açıyı Dizide derece


cinsinden tutacak.

//Bulduğu kesişim sayılarını diziye atmadan önce belli bir toleransdan


geçirecek
if (ckbTetaYuvarlatmaToleransi.Checked == true)
{
TetaDerece = Math.Round(TetaDerece, YuvarlatmToleransi_Teta);
}

if (ckbRoYuvarlatmaToleransi.Checked == true)
{
Ro = Math.Round(Ro, YuvarlatmToleransi_Ro);
}

DiziKesisim_Teta.Add(TetaDerece);
DiziKesisim_Ro.Add(Ro);
DiziKesisim_AynisiBulundu.Add(false);

//listBox1.Items.Add("Kesişim Noktasi= Teta: " + TetaDerece + ", Ro:" + Ro);


}
}

listBox1.Items.Add("Ham Kesişim Nokta Sayisi=" + DiziKesisim_Teta.Count);

//************************ KESİŞİM NOKTALARINI GRAFİKTE GÖSTERİYOR


public void DizidekiKesisimNoktalariniGrafikteGoster()
{
double Teta = 0, Ro = 0;
int NoktaBuyuklugu = Convert.ToInt32(txtKesisimNoktasiBuyuklugu.Text);

for (int i = 0; i < DiziKesisim_Teta.Count; i++)


{
try
{
Teta = Convert.ToDouble(DiziKesisim_Teta[i]);
Ro = Convert.ToDouble(DiziKesisim_Ro[i]);

CizimAlani2.FillEllipse(FircaKirmizi, Convert.ToInt16((Teta +
OrijinOtelemeX) * OlcekX), Convert.ToInt16((Ro + OrijinOtelemeY) * OlcekY), NoktaBuyuklugu,
NoktaBuyuklugu);
}
catch { }
}
}

ArrayList DiziRafine_Teta = new ArrayList();


ArrayList DiziRafine_Ro = new ArrayList();
ArrayList DiziRafine_TekrarSayisi = new ArrayList();

//************************ TEKRARLI KESİŞİM NOKTALARINI AZALTIYOR-RAFİNE DİZİSİNİ


OLUŞTURUYOR
public void KesisimDizisindenTekrarliOlanlariCikarTekrarSayisiniKaydet()
{
double Teta1 = 0, Ro1 = 0;
double Teta2 = 0, Ro2 = 0;
int YuvarlatmaToleransi = Convert.ToInt16(txtYuvarlatmaToleransi.Text);

for (int i = 0; i < DiziKesisim_Teta.Count; i++)


{
Teta1 = Convert.ToDouble(DiziKesisim_Teta[i]);
Ro1 = Convert.ToDouble(DiziKesisim_Ro[i]);
bool AynisiBulundu1 = Convert.ToBoolean(DiziKesisim_AynisiBulundu[i]);
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

if (AynisiBulundu1 == false) //Daha önce ilk aranan hiç kullanılmadıysa..


{
//listBox1.Items.Add("Tekrarsız Kesişim Noktasi" + Teta1 + " , " + Ro1);

DiziRafine_Teta.Add(Teta1);
DiziRafine_Ro.Add(Ro1);

int k = 1; //Rafine edilmiş noktalardan kaç tane bulduğunu tutatacak. Bunlar


çizginin kaç noktadan oluştuğu sayıdır.

for (int j = i + 1; j < DiziKesisim_Teta.Count; j++)


{
Teta2 = Convert.ToDouble(DiziKesisim_Teta[j]);
Ro2 = Convert.ToDouble(DiziKesisim_Ro[j]);
bool AynisiBulundu2 = Convert.ToBoolean(DiziKesisim_AynisiBulundu[j]);

if (Math.Round(Teta1, YuvarlatmaToleransi) == Math.Round(Teta2,


YuvarlatmaToleransi) && Math.Round(Ro1, YuvarlatmaToleransi) == Math.Round(Ro2,
YuvarlatmaToleransi) && AynisiBulundu2 == false) //İlk aranan ile ikinci aranan eşitse ve
ikincisi daha önce hiç işlem görmediyse
{
DiziKesisim_AynisiBulundu[i] = true; //Birincisi kullanıldı, bir
daha bakmamak için true yapıldı
DiziKesisim_AynisiBulundu[j] = true; //İkincisi kullanıldı, bir
dahakine pas geçilmesi için true yapıldı.

k++;

}
DiziRafine_TekrarSayisi.Add(k); //Aynı noktadan kaç tane bulduysa onun
tekrar sayısı oluyor.
}
}
}

ArrayList Dizi_Teta = new ArrayList();


ArrayList Dizi_Ro = new ArrayList();
//***************************************************************
public void BelliBirTekrarSayisiUzerindekiNoktalari_TetaRoDizisineAt()
{
int CizgideBulunmasiGerekenMinimumNoktaSayisi =
Convert.ToInt16(txtMinNoktaSayisi.Text);
double Teta = 0, Ro = 0;

for (int i = 0; i < DiziRafine_Teta.Count; i++)


{
int KesisimUzerindekiNoktaSayisi = Convert.ToInt32(DiziRafine_TekrarSayisi[i]);

if (KesisimUzerindekiNoktaSayisi >= CizgideBulunmasiGerekenMinimumNoktaSayisi)


//-5- adet kesişimden yüksek olan çizgileri ele alacak.
{
Teta = Convert.ToDouble(DiziRafine_Teta[i]);
Ro = Convert.ToDouble(DiziRafine_Ro[i]);

Dizi_Teta.Add(Teta);
Dizi_Ro.Add(Ro);
}

}
listBox1.Items.Add(CizgideBulunmasiGerekenMinimumNoktaSayisi + " nokta üzeri Bulunan
Cizgi Sayisi=" + Dizi_Teta.Count);
}
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

//****************TETA_RO GRAFİK ÇİZİMİ


public void Belli_Bir_Sayinin_Uzerindeki_Kesisim_Noktalarini_Grafikte_Goster()
{
double Teta = 0, Ro = 0;
int NoktaBuyuklugu = Convert.ToInt32(txtKesisimNoktasiBuyuklugu.Text);

for (int i = 0; i < Dizi_Teta.Count; i++)


{
Teta = Convert.ToDouble(Dizi_Teta[i]);
Ro = Convert.ToDouble(Dizi_Ro[i]);

CizimAlani2.FillEllipse(FircaYesil, Convert.ToInt16((Teta + OrijinOtelemeX) *


OlcekX), Convert.ToInt16((Ro + OrijinOtelemeY) * OlcekY), NoktaBuyuklugu, NoktaBuyuklugu);

}
}

public void
BirbirineYakinNoktalarin_OrtalamaDegerleriniHesapla_BuDegerlerIleDiziyiYenile()
{
double Teta1 = 0, Ro1 = 0;
double Teta2 = 0, Ro2 = 0;
double FarkTeta=0, FarkRo=0;
double OrtalamaTeta = 0, OrtalamaRo = 0;

int ToleransTeta =Convert.ToInt16(txtTetaToleransi.Text); //Ortalamasını almak için


Açılara uygulanacak Tolerans
int ToleransRo = Convert.ToInt16(txtRoToleransi.Text); //Ortalamasını almak için
Boylara uygulanacak Tolerans

if (ToleransTeta >= 1 && ToleransRo >= 1) //Tolerans verildi ise (1 den büyükse)
diziyi ortalama değerler ile yenileyecek..
{
for (int i = 0; i < Dizi_Teta.Count - 1; i++)
{
for (int j = i + 1; j < Dizi_Teta.Count; j++)
{
Teta1 = Convert.ToDouble(Dizi_Teta[i]);
Ro1 = Convert.ToDouble(Dizi_Ro[i]);

Teta2 = Convert.ToDouble(Dizi_Teta[j]);
Ro2 = Convert.ToDouble(Dizi_Ro[j]);

FarkTeta = Math.Abs(Teta1 - Teta2);


FarkRo = Math.Abs(Ro1 - Ro2);

if (FarkTeta <= ToleransTeta && FarkRo <= ToleransRo) //fark düşükse


noktalar yakın demektir.
{
OrtalamaTeta = (Teta1 + Teta2) / 2;

Dizi_Teta[i] = OrtalamaTeta;
Dizi_Teta[j] = OrtalamaTeta;

OrtalamaRo = (Ro1 + Ro2) / 2;

Dizi_Ro[i] = OrtalamaRo;
Dizi_Ro[j] = OrtalamaRo;
}
}
}
}
}

//****************ORTALAMA TETA_RO GRAFİK ÇİZİMİ


Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

public void Ortalama_DiziTetaRo_Noktalarini_Grafikte_Goster()


{
double Teta = 0, Ro = 0;
int NoktaBuyuklugu = Convert.ToInt32(txtKesisimNoktasiBuyuklugu.Text);

for (int i = 0; i < Dizi_Teta.Count; i++)


{
Teta = Convert.ToDouble(Dizi_Teta[i]);
Ro = Convert.ToDouble(Dizi_Ro[i]);

CizimAlani2.FillEllipse(FircaMavi, Convert.ToInt16((Teta + OrijinOtelemeX) *


OlcekX), Convert.ToInt16((Ro + OrijinOtelemeY) * OlcekY), NoktaBuyuklugu, NoktaBuyuklugu);
}
}

public void TetaRo_Dizisindeki_Noktalari_XYduzleminde_ForDongusuKullanarakCiz()


{
double Ro = 0;
double x = 0, y = 0;

for (int i = 0; i < Dizi_Teta.Count; i++)


{
double TetaDerece = Convert.ToDouble(Dizi_Teta[i]); //Diziye teta derece olarak
kaydedilmişti.
Ro = Convert.ToDouble(Dizi_Ro[i]);

double TetaRadyan = TetaDerece * 2 * Math.PI / 360;

if(TetaDerece==0) //Açı 0 ise çizgi DİKEY demektir. Dikey çizgileri formülde


kullanırken sıfıra bölme oluşuyor. O yüzden for döngüsü y ekseninde taranacak.
{

//MessageBox.Show("Açı 0=Çizgi Dikey");

//Dikey çizgileri çizerken y ekseninde for döndürecek.


//Her Teta-Ro çifti için bir çizgi oluşturacak.Bu çizgileri nokta kullanarak
çizecek.
for (y = 0; y < 300; y++)
{

x = (Ro - y * Math.Sin(TetaRadyan)) / (Math.Cos(TetaRadyan));

int X = Convert.ToInt32(x); //PictureBox integer ister


int Y = Convert.ToInt32(y); //PictureBox integer ister

//Grafiği nokta ile çizdirecek.


CizimAlani1.FillEllipse(FircaTurkuaz, X, Y, 2, 2);
}

}
else //Yatay çizgileri çizerken x ekseninde for döndürecek.
{
//Her Teta-Ro çifti için bir çizgi oluşturacak.Bu çizgileri nokta kullanarak
çizecek.
for (x = 0; x < 400; x++)
{

y = (Ro - x * Math.Cos(TetaRadyan)) / (Math.Sin(TetaRadyan));

int X = Convert.ToInt32(x); //PictureBox integer ister


int Y = Convert.ToInt32(y); //PictureBox integer ister

//Grafiği nokta ile çizdirecek.


CizimAlani1.FillEllipse(FircaTurkuaz, X, Y, 2, 2);
}
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

}
}
}

//************ EKRANLA İLGİLİ SEÇENEK VE AYARLAMA KODLARI *************** Algoritma ile


ilgili değil
//************ EKRANLA İLGİLİ SEÇENEK VE AYARLAMA KODLARI *************** Algoritma ile
ilgili değil
//************ EKRANLA İLGİLİ SEÇENEK VE AYARLAMA KODLARI *************** Algoritma ile
ilgili değil
private void ckbTetaYuvarlatmaToleransi_CheckedChanged(object sender, EventArgs e)
{
if (ckbTetaYuvarlatmaToleransi.Checked == true)
txtYuvarlatmaToleransi_Teta.Enabled = true;
else
txtYuvarlatmaToleransi_Teta.Enabled = false;
}

private void ckbRoYuvarlatmaToleransi_CheckedChanged(object sender, EventArgs e)


{
if (ckbRoYuvarlatmaToleransi.Checked == true)
txtYuvarlatmaToleransi_Ro.Enabled = true;
else
txtYuvarlatmaToleransi_Ro.Enabled = false;
}
private void btnGrafigiTemizle_Click(object sender, EventArgs e)
{
// Grafik Çizimi yapmadan önce çizim alanını temizle
pictureBox1.Invalidate();
pictureBox2.Invalidate();
}

}
}

Kaynak Kodlar: www.IbrahimCayiroglu.com/Dokumanlar/GoruntuIsleme/HOUGH_ALGORITMASI.rar


Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

HOUGH TRANSFORM: CIRCLE DETECTİON


Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com
Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Usıng Gradient Informatıon


Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Circle Detection: R Is Not Known


Karabük Üniversitesi, Mühendislik Fakültesi.........................................................................................................www.ibrahimcayiroglu.com

Referanslar
https://www.youtube.com/watch?v=XRBc_xkZREg
https://www.youtube.com/watch?v=uDB2qGqnQ1g
https://www.youtube.com/watch?v=t1GXMvK9m84
https://www.youtube.com/watch?v=4zHbI-fFIlI

You might also like