MATLAB görüntü işleme açısından çok zengin bir uygulamadır. Yeni yeni öğrenmeye başladığım Computer Vision System Toolbox, çok daha kısa kodla epeyi iş başarmak da mümkün. Bu yazıda siyah beyaz görüntüde delikli ve deliksiz objelerin sayısını bulmayı anlatacağım ve kodlarını paylaşacağım.
close all %açık tüm pencereleri kapat, cereyan yapıyor.
clear %workspace'de bulunan tüm değişkenleri ve nesneleri sil
clc %komut penceresini temizle
Buraya kadar sadece genel bir temizlik yapıldı.
Şimdi, evvela MATLAB’ın CVST’si içinde bulunan VideoPlayer ve VideoFileReader nesnelerini oluşturalım.
hVideoPlayer = vision.VideoPlayer;
hVideoFileReader = vision.VideoFileReader;
İşlem yapılacak görüntünün yolunu belirtelim ve görüntüyü işlemek üzere frame değişkeni içine alalım.
hVideoFileReader.Filename = 'img1.jpg'; % başlıktaki resim
frame = step(hVideoFileReader);
Görüntü siyah beyaz. Bunu ben biliyor ve görüyorum ama bir başkası RGB görüntü üzerinde çalışmak isteyebilir. O yüzden görüntüyü her ihtimale karşı önce gri tonlamalı sonra da siyah beyaz hale dönüştürelim. Bu işlemler için vision.ColorSpaceConverter ve vision.Autothresholder araçlarından faydalanacağız.
hcsc = vision.ColorSpaceConverter;
hcsc.Conversion = 'RGB to intensity';
frame = step(hcsc, frame);
at = vision.Autothresholder;
frame = step(at, frame);
Gelelim asıl meseleye… Hangi parçanın delikli olup olmadığını bulmak için öncelikle parçaları tek tek inceleyebilmek gerekir diye düşündüm. Görüntüde birbirinden bağımsız duran objelerin sayısını bulmak için vision.ConnectedComponentLabeler aracından yararlanalım.
ccl = vision.ConnectedComponentLabeler;
[L NUM] = step(ccl, frame);
Bu işlemden sonra L ile her bir obejeye ait, orijinal görüntüyle aynı boyutlarda matrisler elde edilir. NUM değişkeni görüntü içinde kaç adet bağımsız obje olduğunun sayısını tutar.
Bütün görüntü içinde kaç adet delikli obje olduğunu saydıracağız. O yüzden basit bir sayaca ihtiyacımız olacak.
delikliObjSay = 0;
Her bir obje için aşağıdaki işlemleri tekrarla:
- Grup numarasıyla değiştirilmiş olan matrisin değerlerini 1 yap.
- Görüntünün reklerini ters çevir. (Siyahı beyaz, beyazı siyah yap.)
- Evrilmiş görüntüde birbirinden bağımsız bölgeleri say.
- Eğer bölge sayısı 1den büyükse delikli obje sayacına +1 ekle.
İşlem sonrasında komut penceresine mesajı yazdıralım.
for i=1:NUM
framei = changem(L==i, 1, i); %1. madde
framei = imcomplement(framei); %2. madde
[Li NUMi] = step(ccl, framei); %3. madde
if NUMi > 1
delikliObjSay = delikliObjSay + 1; %4. madde
end
end
mesaj= sprintf('%d objenin %d tanesi deliklidir.',NUM, delikliObjSay);
disp(mesaj);
Mesajın aynısını VideoPlayer penceresinde resmin üstüne yazdır.
bilgi = vision.TextInserter('%d objenin %d tanesi deliklidir.',...
'Color', uint8([255, 255, 255]), ...
'Location', [100 100],...
'FontSize', 22);
frame = step(bilgi, frame, int32([NUM delikliObjSay]));
İşlenmiş görüntüyü VideoPlayer penceresinde göster ve işimiz bittiği için VideoPlayer nesnesini sal gitsin.
step(hVideoPlayer, frame);
release(hVideoFileReader);
release(hVideoPlayer);
Mantık Ne?
Mantık şu: MATLAB siyah beyaz görüntü içinde beyazları “VAR”, siyahları”YOK” olarak tanımlıyor. Dolayısıyla görüntünün bütününden alından parçanın renklerini ters çevirdiğimizde obje eğer delikli ise objenin kendisi siyah, delikleri ve etrafındaki boşluk beyaz olacaktır. O zaman tek delikli bir obje için beyaz bölge sayısı 2 olacaktır. Biz de bundan anlayacağız ki obje deliklidir.
Eğer objede delik yoksa, görüntüyü her iki durumda da bir siyah ve bir beyaz bölge olacaktır. O zaman diyeceğiz ki “bu obje delikli değildir”.