Joaquim Luis tarafından yazılan ve benim de eklemeler yaparak geliştirdiğim bir kodu paylaşacağım. Önceki bir yazıda MPT araçkutusunu kullanarak bir resimdeki yüzleri ve gözleri bulmuştuk. Şimdi sadece yüzleri bulacağız ama bu sefer öyle saniyelerce beklemeden, bir saniyeden çok daha kısa bir sürede! Bunu da OpenCV'nin yüz bulma fonksiyonunu MATLAB'ten çağırarak başaracağız. Bunun dışında OpenCV'ye ait olan cvAbsDiff, cvAdd, cvAddS, cvAddWeighted, cvCanny, cvCircle, cvCvtColor, cvFindContours, cvCvtScale, cvDilate, cvDiv, cvApproxPoly, cvEllipseBox, cvErode, cvExp, cvFilter2D, cvFillPoly, cvFlip, cvFloodFill, cvGoodFeaturesToTrack, cvHoughLines2, cvHoughCircles, hypot, cvInpaint, cvLaplace, cvLine, cvLog, cvMatchTemplate, cvMorphologyEx, cvMul, cvPolyLine, cvPow, cvPyrDown, cvPyrUp, cvRectangle, cvResize, cvSmooth, cvSobel, cvSub, cvSubS ve cvPutText fonkiyonlarını da kullanabileceğiz. Bunların hepsini denemedim, garantisi yok. Neyse konuyu pek dağıtmayalım ve yüz bulmak için adımlara geçelim. O kısmını ben ekledim. Diğer fonksiyonların kullanımı için kaynaklarına bakarsınız.

OpenCV'nin bilgisayarınızda kurulu olduğunu düşünüyorum ama yazıyı takip etmek için bu gerekli değil.

Öncelikle Using_OpenCV_in_MATLAB.zip dosyasını bilgisayarınıza indirip arşivi açın. Ardından MATLAB'i açın ve çalışma dizininizi indirdiğiniz dosyaların bulunduğu klasör olarak değiştirin.

make_cvlib

fonksiyonunu çağırarak cvlib_mex.mexw32 (donanıma ve versiyona göre cvlib_mex.mexw64 veya cvlib_mex.dll de olabilir) dosyasını oluşturun. Benim bilgisayarımda oluşmuş halini dosyalara ekledim ama sizinkinde çalışmalayabilir, o yüzden kendiniz oluşturabilirseniz iyi olur.

Artık MATLAB fonksiyonu yazar gibi OpenCV fonksiyonlarının bir kısmına ulaşabileceğiz.

cvlib_mex

yazarak imkanlarımızı görebilirsiniz. Özel olarak bir fonksiyonun kullanımı için, örneğin "resim ölçeklemek nasılmış?" sorusu için

cvlib_mex('resize')

yazmak gerekiyor.

Yüz bulma fonksiyonu için de test_face_detect kodunu inceleyerek nasıl çalıştığını anlayabilirsiniz. Kısaca şöyle;

clear, clc

% Seçenekler (isteğinize göre değiştirin)

% Sınıflandırıcı xml dosyaları. Normalde
% "OpenCV dizini"\data\haarcascades adresinde bulunurlar ve oradan
% alarak istediğiniz yere kopyalayabilirsiniz. Biz karşıya bakanları bulalım.
classifierFilename = 'haarcascade_frontalface_default.xml';
currentPath = [fileparts([mfilename('fullpath') '.m']) filesep];
classifierFileFullPath = [currentPath 'haarcascades' filesep classifierFilename];

% Yüz olarak seçilebilecek izin verilen en küçük alan
minFaceSize = 25;

% Harcanan zamanı göstereyim mi?
shouldViewElapsedTime = 1;

% Resmi oku ve gri seviye resme çevir
img = imread('1.jpg');
imgGray = rgb2gray(img);

% Yüzleri bul ve dikdörtgen içinde çiz
rectangleMatrix = face_detect( imgGray, classifierFileFullPath, minFaceSize, shouldViewElapsedTime );
imshow(img);
for iRectangle = 1:size(rectangleMatrix,1)
rectangle('Position',rectangleMatrix(iRectangle,:), 'EdgeColor', 'r')
end

Sonuçlar

Değerlendirme

Hız konusunda muhteşem! Sadece yüz bulma değil, diğer fonksiyonlar da MATLAB'in kendi fonksiyonlarına oranla hızlı olabiliyor. Örneğin resize fonksiyonu için öyleydi.

Bazı yüzleri bulamamış gözüküyor. Parametreler ile oynanarak veya xml sınıflandırıcı dosyasını değiştirerek farklı sonuçlar almak mümkün. Bunun için ya facedetect kodunun içine girip isteğe göre değiştirmek lazım ya da farklı yüzler/pozlar/ırklar/vb. kapsayan sınıflandırıcı dosyası hazırlamak. İkincisi hiç kolay bir iş değil.

Tüm fonksiyonlarını denemedim ama halihazırdakilere bakarak OpenCV'de yazılan bir fonksiyonu MATLAB'ten çağırabilmek için bu dosyaya geçirebiliriz artık!

Yorumlarınızı ve katkılarınızı beklerim...

Düzeltme (25.08.08, Albert Ali Salah'ın katkısı): Yüz bulma fonksiyonunun çok kullanılması sonucu hafıza şişmesi oluyordu ('memory leak' vardı). Jfacedetect fonksiyonundan çıkmadan önce hafızayı boşaltmak gerekiyordu. Sonuna:

cvReleaseHaarClassifierCascade( &cascade );

ekleyince olay halloldu. Şu anki dosya güncelleştirilmiş halidir.