Matlab ile Nesne Tanıma (Object Recognition)

Merhaba arkadaşlar...
Bu yazımda Matlab'ın İmage Proccresing Toolbox ını kullanarak bir resimdeki nesnelerin nasıl belirlendiğini ve bu nesnelerin kaç adet olduğunu size anlatacağım.

1.Adım olarak resmi okuma işlemi ile başlayacağız. Resmi okuma komutları aşağıda verilmiştir.
image=imread('C:\nesneler.png'); %Resmi Okuma
figure(1), imshow(image);  %Resmi Gösterme
Şekil-1

2.Adım olarak şekilleri belirlemeye yardımcı olmak için resmi tamamen binary olarak siyah-beyaz hale getirmemiz gerekiyor. Bu işlem için aşağıdaki komutları kullanmalıyız.
imagegray=rgb2gray(image); %Resim gri tona döndürülüyor.
figure(2), imshow(imagegray);
Şekil-2
Burada rgb2gray komutu ile resmi gri tonlamalı hale getiriyoruz. Yani resim 3 boyutluyken (RGB) 2 boyutlı hale geliyor bu komut çok önemlidir. Diğer işlemlerin çalışması için resim 2 boyutlu olması gerekir. (Şekil-2)
level=graythresh(imagegray) %Parlaklık eşiğini otomatik  belirlendi ve 0 ile 1 arasında sayı oluşturdu

bw=im2bw(imagegray,0.4); %Resim tamamen siyah-beyaz piksellere dönüştü.
figure(3),imshow(bw);
Şekil-3
graythresh komutu komutu görüntüdeki parlaklık eşiğini otomatik olarak belirler ve sonuç olarak 0-1 arasında bir sayı (level) oluşturur. Görüntüdeki parlaklık sınırları ile yapacağımız işlemlerde genel olarak graythresh'ten elde ettiğimiz sayıyı kullanırız. (Şekil-3)

Önemli NOT: Ben bu projede graythresh ten elde ettiğim sonucu kullanmadım. Çünkü graythresh komutu bana 0.54 gibi bir değer verdi ve bu değere göre resimin üstündeki gri dikdörtgenin parlaklık seviyesi bu değerin altında olduğu için bu dikdörtgeni saymadı. Bu nedenle 0.54 ten daha düşük bir rakam belirledim. Bu değer 0.4 (Deneme yanılma yoluyla).
Ama sizin resminizde parlaklık seviyesi olarak sıkıntı çıkarmayacak objeler yoksa graythresh komutundan yararlanmanızda fayda var.

Bundan sonraki adımda tamamen binary resim elde etmek için im2bw komutunu kullanıyoruz. Bu komut ile belirlediğimiz (0.4) parlaklık seviyesine göre resmimiz tamamen siyah-beyaz piksellerden oluşmaktadır.

3.Adım olarak ise görüntüdeki bileşenleri kaldırmamız temiz bir görüntü elde etmemiz gerekiyor. Bu adımda uğraştığımızz nesnelerden bağımsız olan nesneleri kaldıracağız. Bunun için morfolojik işlemler uyguluyoruz. Bunun için bazı komutları tanıtacağım.

bwareaopen: Binary modda küçük parçaları (bağlı olmayan) yok eder.
strel: Morfolojik işlemlerde uygulanan yapısal filtre elemanıdır. Morfolojik işlemleri hangi şekil ve parametrelerle uygulayacağımızı strel ile belirleyebiliriz.

se=strel('disk',R)       R: Yarıçap
se=strel('square',L)    L: Karenin bir kenarının uzunluğu
se=strel('line',D)        D: Çizginin uzunluğu

Bu bilgilerden sonra komutlarımuz aşağıdaki gibi olur.
bw=bwareaopen(bw,30); %30px den daha az sayıda olan nesneler kaldırılıyor.
figure(4),imshow(bw);
Şekil-4
se=strel('disk',10); %Yarıçapı 10px olan disk biçiminde yapısal element oluşturuyoruz.
bw=imclose(bw,se); %Yapısal element yardımıyla iç kısımdaki boşluklar kayboldu.
figure(5),imshow(bw);
Şekil-5

Bundan sonraki adımda şekillerin sınırlarını belirlicez öncelikle bunun için şekillerin içini doldurmamız lazım. imfill komutu bu işe yarar. Bu komutu kullanmamızdaki amaç sınırları rahat bulmak içindir. (Şekil-5)

bw=imfill(bw,'holes'); %Resimde çukur diye nitelendirilen yerleri dolduruyoruz.
figure(5), imshow(bw);
Şekil-5

4.Adım ise nesnelerin sınırlarını buluyoruz. Aşağıdaki kodda sınırlar bulunmuştur.
[B,L] = bwboundaries(bw,'noholes'),disp(B)
figure(6), imshow(label2rgb(L, @jet, [.5 .5 .5]))
Şekil-6

[B,L] = bwboundaries(bw,'noholes') komutu ile tüm hole yapıları B değişkenine atanır. Toplam 8 nesnemiz olduğundan 8x1 lik bir array oluşturulur. L ise nesne dışındaki değerleri yani arkaplanı ifade eder.

  B=  [209x2 double]
         [294x2 double]
         [ 98x2 double]
         [251x2 double]
         [526x2 double]
         [ 99x2 double]
         [224x2 double]
         [218x2 double]

imshow(label2rgb(L, @jet, [.5 .5 .5])) komutu ile nesnelerin dışındaki alanı yani arkaplan reklendirilir. (L) Sınırları daha iyi ayırt edebilmek için önemlidir.  (Şekil-6)

Artık resmimizde sınırları belirlemeye geçebiliriz.
hold on
for k = 1:length(B)
  boundary = B{k}; %'k' etiketindeki nesnenin sınır kordinatlarını (X,Y) belirler
  plot(boundary(:,2), boundary(:,1), 'w', 'LineWidth', 2)
end

fprintf('Nesneler işaretlenmiştir. Toplam Nesne Sayısı=%d\n',length(B))
Şekil-7

boundary = B{k} : 'k' etiketindeki nesnenin sınır kordinatlarını (X,Y) belirler.
boundary(:,2)      : Y koordinatı
boundary(:,1)      : X koordinatı

plot(boundary(:,2), boundary(:,1), 'w', 'LineWidth', 2): Komutu ile sırasıyla bütün nesnelerin etrafı 2 pixellik şerit ile çevreleniyor. for loopunun 1’den B arrayinin sayısına kadar olmasının nedeni de budur.

Program Çıktısı Şu Şekildedir.
>>Nesneler işaretlenmiştir. Toplam Nesne Sayısı=8


İsterseniz bulduğumuz nesnelerin neye ait olduğunu yani dikdörtgenmi yoksa yuvarlakmı olduğuna karar veren bir algoritma geliştirelim..

Bunun için bazı matematiksel formulleri kullanarak cisimlerin mertic değerlerini bulmamız gerekecek.


Formüldeki metric değer yuvarlak nesneler için yaklaşık 1’dir. Yuvarlak olmayan diğer nesneler için 1’den küçük değerler alır. Ben ayrıntılı olsun diye cisimlerin cisimlerin tek tek metric değerlerini hesaplattırıp sonra karşılaştırma (if-else) komutlarını yazdım.

Öncelikle aşağıdaki komutlar kullanılarak bölgenin özellikleri çıkarılır.

regionprops: ile bölgelerin özellikleri çıkarılır.
Area: alanı ifade eder.
Centroid: Kütle merkezini ifade eder.
stats = regionprops(L,'Area','Centroid');
for k = 1:length(B)   % Nesneleri sayan loopun başlangıcı

 boundary = B{k};   % 'k' etiketindeki nesnenin sınır kordinatlarını (X,Y) belirler

  % Nesnenin çevresini hesaplar
  delta_sq = diff(boundary).^2;
  perimeter = sum(sqrt(sum(delta_sq,2)));

  % 'k' etiketli nesnenin alanını hesaplar
  area = stats(k).Area;

  % Nesnenin metric değerini hesaplar
  metric = 4*pi*area/perimeter^2;

  % Hesaplanan değeri gösterir
  metric_string = sprintf('%2.2f',metric);
  centroid = stats(k).Centroid;

  %Metric değerlere göre karşılaştırma

  if metric > 0.9344
    text(centroid(1),centroid(2),'Çember');
  elseif (metric <= 0.8087) && (metric >= 0.7623)
    text(centroid(1),centroid(2),'Dikdörgen');
  elseif (metric <= 0.7393) && (metric >= 0.7380)
    text(centroid(1),centroid(2),'Dikdörgen');
  else
     text(centroid(1),centroid(2),'Belirlenemeyen Şekil');
  end

disp(metric)
  text(boundary(1,2)-35,boundary(1,1)+13,metric_string,'Color','y',...
       'FontSize',14,'FontWeight','bold');
end
Projemiz tamamlanmıştır. Sonuç aşağıdaki gibidir. :)
Sonuç Resmi

Projenin tam kodu aşağıdaki gibidir.
image=imread('C:\nesneler.png'); %Resmi Okuma
figure(1), imshow(image); %Resmi Gösterme

imagegray=rgb2gray(image); %Resim gri tona döndürülüyor.
figure(2), imshow(imagegray);
level=graythresh(imagegray) %Parlaklık eşiği belirlendi ve 0 ile 1 arasında sayı oluşturuldu.
bw=im2bw(imagegray,0.4); % Resim tamamen siyah-beyaz piksellere dönüştü.
figure(3),imshow(bw);

bw=bwareaopen(bw,30);%30px den daha az sayıda olan nesneler kaldırılıyor.
figure(8),imshow(bw);

se=strel('disk',10); %Yarıçapı 10px olan disk biçiminde yapısal element oluşturuyoruz.
bw=imclose(bw,se); %Yapısal element yardımıyla iç kısımdaki boşluklar kayboldu.
figure(4),imshow(bw);

bw=imfill(bw,'holes'); %Resimde çukur diye nitelendirilen yerleri dolduruyoruz.
figure(5), imshow(bw);

[B,L] = bwboundaries(bw,'noholes'),disp(B)
figure(6), imshow(label2rgb(L, @jet, [.5 .5 .5]))

hold on
for k = 1:length(B)
boundary = B{k}; %'k' etiketindeki nesnenin sınır kordinatlarını (X,Y) belirler;
plot(boundary(:,2), boundary(:,1), 'w', 'LineWidth', 2)
end
fprintf('Nesneler işaretlenmiştir. Toplam Nesne Sayısı=%d\n',k)

stats = regionprops(L,'Area','Centroid');

% Nesneleri sayan loopun başlangıcı
for k = 1:length(B)

% 'k' etiketindeki nesnenin sınır kordinatlarını (X,Y) belirler
boundary = B{k};

% Nesnenin çevresini hesaplar
delta_sq = diff(boundary).^2;
perimeter = sum(sqrt(sum(delta_sq,2)));

% 'k' etiketli nesnenin alanını hesaplar
area = stats(k).Area;

% Nesnenin metric değerini hesaplar
metric = 4*pi*area/perimeter^2;

% Hesaplanan değeri gösterir
metric_string = sprintf('%2.2f',metric);
centroid = stats(k).Centroid;

%Eğer metric değer eşik değerden daha büyük ise yuvarlak nesne kabul edilir.
if metric > 0.9344
text(centroid(1),centroid(2),'Çember');

elseif (metric <= 0.8087) && (metric >= 0.7623)
text(centroid(1),centroid(2),'Dikdörgen');
elseif (metric <= 0.7393) && (metric >= 0.7380)
text(centroid(1),centroid(2),'Dikdörgen');
else
text(centroid(1),centroid(2),'Belirlenemeyen Şekil');
end
disp(metric)
text(boundary(1,2)-35,boundary(1,1)+13,metric_string,'Color','y',...
'FontSize',14,'FontWeight','bold');
end
% 0.8086 0.9062 0.9432 0.7624 0.7392 0.9345 0.9059 0.7497
Loading...
Ad

Arduino Autocad Bilim-Teknoloji Biyomedikal Sistemler C-Programlama C# C# Programlama Diferansiyel Denklemler Dijital Kontrol Sistemleri Elektrik Devreleri 1 Elektrik Devreleri 2 Elektrik Makineleri 1 Elektrik Makineleri 2 Elektrik Tesislerinde Koruma Elektromantetik Alan Teorisi Elektromantetik Dalga Teorisi Elektronik 1 Elektronik 2 Elektronik-Devreler EmguCV Genel Fizik Genel Kimya Genel Matematik Gömülü Linux Güç Elektroniği Haberleşme Sistemleri İşaret ve Sistemler Lineer-Cebir Lojik Devreler Malzeme Bilimi MATLAB Mikroişlemciler Olasılık ve İstatistik Otomatik Kontrol Sistemleri PLC-Otomasyon Proje Yönetimi ve Girişimcilik Raspberry Pi Sayısal Analiz Sayısal İşaret İşleme Teknik-Kutuphane Termodinamik Yüksek Gerilim Tekniği
false
ltr
item
Çağlar GÜL: Matlab ile Nesne Tanıma (Object Recognition)
Matlab ile Nesne Tanıma (Object Recognition)
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvn07ksSN22KM4TnSUKLQHWLIbsO9LYYlw5YDkQgkIg37vtLnwfOfa5AsDlJVedw7uybnEBVHpvANuyrx6vZCMmALJ7TE9tAxoGBKkPHV8snySbQ6LLx_jss3Bv2DlKiwvnfUPUwPIKHg/s400/resim1.PNG
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvn07ksSN22KM4TnSUKLQHWLIbsO9LYYlw5YDkQgkIg37vtLnwfOfa5AsDlJVedw7uybnEBVHpvANuyrx6vZCMmALJ7TE9tAxoGBKkPHV8snySbQ6LLx_jss3Bv2DlKiwvnfUPUwPIKHg/s72-c/resim1.PNG
Çağlar GÜL
https://elektronikafa.blogspot.com/2015/09/matlab-ile-nesne-tanma-object.html
https://elektronikafa.blogspot.com/
http://elektronikafa.blogspot.com/
http://elektronikafa.blogspot.com/2015/09/matlab-ile-nesne-tanma-object.html
true
871250089272898028
UTF-8
Not found any posts Not found any related posts VIEW ALL Readmore Reply Cancel reply Delete By Home PAGES POSTS View All RECOMMENDED FOR YOU Tag ARCHIVE SEARCH ALL POSTS Not found any post match with your request Back Home Contents See also related Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sun Mon Tue Wed Thu Fri Sat January February March April May June July August September October November December Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec just now 1 minute ago $$1$$ minutes ago 1 hour ago $$1$$ hours ago Yesterday $$1$$ days ago $$1$$ weeks ago more than 5 weeks ago Followers Follow THIS CONTENT IS PREMIUM Please share to unlock Copy All Code Select All Code All codes were copied to your clipboard Can not copy the codes / texts, please press [CTRL]+[C] (or CMD+C with Mac) to copy