Öncelikle OpenCV kütüphanesinden bahsedelim. OpenCV ilk versiyonu 1999 yılında İntel'in araştırma ekibi tarafından yayımlanmış açık kaynak kodlu ve BSD lisanslı bir görüntü işleme kütüphanesidir.İçinde birçok ileri düzey algoritmayı bulundurur ve çok kolay bir kullanımı vardır. (yapılan işlemlerin aslında ne kadar karmaşık olduğunu göz önüne alırsak.) OpenCV kullanarak C++ ve C dillerinde kolayca Haar cascade'leri kullanarak yüz tanıma, SURF-FAST gibi algoritma kullanarak nesne tanıma gerçekleştirebilirsiniz.
Dediğimiz gibi C++ ve C dillerinde kullanıma hazır olan bu kütüphaneyi C# ve Python gibi dillerde kullanmak için wrapper denen, kütüphanenin fonksiyonlarını farklı diller kullanarak çağırmamıza yarayan ara kütüphanelere ihtiyacımız var. Bu noktada yardımımıza Emgu CV ve OpenCVSharp gibi wrapperlar koşuyor.
Kütüphaneden bahsettiğimize göre örnek programımıza geçebiliriz. Öncelikle Visual Studio'da yeni bir C# projesi açalım. Projemizde opencvsharp kullanabilmek için ilk önce gerekli dllleri projemize eklememiz gerekiyor. Bunu bu adresten indirerek elle de yapabilirsiniz fakat biz bu makalede NuGet kullanarak otomatik olarak projemize gerekli dosyaları ekleyeceğiz.
Projenizi oluşturduktan sonra araç çubuğundan Project > Manage NuGet Packages seçeneklerini seçerek NuGet paket ekleme penceresini açın. Online seçeneğini seçip arama kutusuna "opencvsharp" yazdığınızda karşınıza gelen sonuç aşağı yukarı böyle bir şey olacak. İşletim sisteminize göre 64 bit ve 32 bit sürümleri arasından seçim yapın ve "Install" a basın. (x86 32 bit anlamına gelmektedir.)
Bu aşamada herhangi bir sorunla karşılaştıysanız yorumlarda belirtebilirsiniz. Wrapperımızı yükledik ve artık kod yazmaya geçebiliriz.
Her şeyden önce kodumuza kullanacağımız kütüphaneleri ekleyelim;
using OpenCvSharp; using OpenCvSharp.MachineLearning; using OpenCvSharp.Blob; using OpenCvSharp.UserInterface; using OpenCvSharp.CPlusPlus;
Kodumuzun en üstüne bu satırları ekliyoruz.
Formumuza resmi göstermek için kullanacağımız bir pictureBox ve kodu çalıştırmak için kullanacağımız bir buton ekleyelim.
Butonumuza çift tıklayarak click eventini oluşturalım. Buttonumuzun click eventi içinde:
Bitmap resim = (Bitmap)Bitmap.FromFile(@"C:\resim\resim1.jpg");
şeklinde bir bitmap nesnesi oluşturalım. Eğer parantez içine neden (Bitmap) yazdığımı merak ediyorsanız internetten C# Implicit Type Conversion şeklinde araştırabilirsiniz. Bu nesne yüz algılama yapacağımız resmi tutacak. O yüzden parametrelere işlem yapmak istediğiniz resmi yazın.
OpenCv kütüphanesi resimleri saklarken görüntü işleme ile ilgili fonksiyonları olan iplimage adlı bir nesne kullanır. Resmimizi bitmap olarak aldık ama işlem yapmak için ilk önce iplimage'e çevirmeliyiz. Bunun için;
IplImage resimipl = BitmapConverter.ToIplImage(resim);
diyerek resmimizi iplimage'e çevirelim. Resmi aldığımıza göre artık algılamaya geçebiliriz.
Yüz algılama yapacağımız, iplimage türünden değer geri döndüren ve parametrelerinde bir adet iplimage alan bir fonksiyon oluşturalım;
private IplImage yuzAlgila(IplImage resim) {}
Bu fonksiyonun içine suratların etrafına çizeceğimiz çemberin rengini belirleyen bir CvColor nesnesi oluşturalım.
CvColor surat = new CvColor(0, 0, 255); //mavi
Parametrelere yazdığımız (0,0,255) değerleri mavi renktir. R - G - B değerlerini değiştirerek rengi değiştirebilirsiniz.
Fonksiyonumuz içerisinde aşağıdaki değerleri tanımlayalım.
const double olcek = 3.0; //hizli islem icin resmin kac kat kucultulecegi const double ScaleFactor = 2.5; const int MinNeighbors = 1;
Buradaki ölçek değişkeni resmin kaç kat küçültüleceğini belirtiyor. İşlem yapmadan önce resmi küçülterek tanıma için gerekli süreyi azaltıyoruz. Bu gerçek zamanlı çalışan uygulamalar için kritik önem taşıyor.
ScaleFactor ve MinNeighbors değişkenleri ise Haar yöntemi için gerekli bazı değişkenler. Bu makalede açıklamaya çalışırsak gereksiz uzar ve konumuzun dışına çıkmış oluruz. Burada sadece basit bir örnek ile başlangıç yapmaya çalışıyoruz :)
using (IplImage kucukresim = new IplImage(new CvSize(Cv.Round(resim.Width / olcek), Cv.Round(resim.Height / olcek)), BitDepth.U8, 1)) { using (IplImage gri = new IplImage(resim.Size, BitDepth.U8, 1)) //renksizlestir { Cv.CvtColor(resim, gri, ColorConversion.BgrToGray); Cv.Resize(gri, kucukresim, Interpolation.Linear); Cv.EqualizeHist(kucukresim, kucukresim); } IplImage outImage = Cv.Clone(resim); //asil tespit kismina geldik using (CvHaarClassifierCascade cascade = CvHaarClassifierCascade.FromFile(Environment.CurrentDirectory + "\\haarcascades\\haarcascade_frontalface_alt2.xml")) using (CvMemStorage storage = new CvMemStorage()) { storage.Clear(); Stopwatch watch = Stopwatch.StartNew(); CvSeq<CvAvgComp> faces = Cv.HaarDetectObjects(kucukresim, cascade, storage, ScaleFactor, MinNeighbors, 0, new CvSize(30, 30)); watch.Stop(); Console.WriteLine("tespit suresi = {0} milisaniye", watch.ElapsedMilliseconds); tespitsuresi = (watch.ElapsedMilliseconds).ToString(); for (int i = 0; i < faces.Total; i++) { CvRect r = faces[i].Value.Rect; CvPoint center = new CvPoint { X = Cv.Round((r.X + r.Width * 0.5) * olcek), Y = Cv.Round((r.Y + r.Height * 0.5) * olcek) }; int radius = Cv.Round((r.Width + r.Height) * 0.25 * olcek); resim.Circle(center, radius, surat, 3, LineType.AntiAlias, 0); } } return resim; }
Kodumuzu açıklayalım: başta using içerisinde kullanacağımız şeyleri belirtiyoruz,çünkü wrapperımızın otomatik çöp toplama özelliği yok, yani nesnelerle işimiz bittiğinde nesneler otomatik olarak silinmiyor, bellekte kalmaya devam ediyor. Bu OutOfMemory hatalarına yol açabilir. using bloğunun bittiği yerde using parantezlerinin içine yazılan değişkenler otomatik olarak dispose edilir (bellekten silinir).
İkinci using bloğunun içinde resmi küçültüyor ve gri tonlamaya çeviriyoruz. EqualizeHist() fonksiyonu resmin histogramını düzenleyerek ışıklandırmanın etkilerini azaltıyor. Bu sayede daha iyi sonuçlar elde ediyoruz.
Bir alt kısımda ise yüz tanıma işlemi gerçekleşiyor ve yüzlerin bulunduğu koordinatlar daha sonra işaretleyip kullanıcıya göstermek için alınıyor. Bu örnekte kullandığımız haar cascade'ini google aracılığıyla bulup programınızın exe'sinin bulunduğu konuma atmalısınız.
Kodun en sonundaki for döngüsünde küçük resim üzerinde tespit edilen suratların koordinatları ile büyük resim üzerinde suratların etrafına çember çiziliyor. Butonumuza bu fonksiyonu çağırmak için kodu ekleyerek programımızı bitirelim.
pictureBox1.Image = BitmapConverter.ToBitmap(yuzAlgila(resimipl));
Kodumuzun son hali şöyle olmalı;
Çalıştırmayı deneyelim;
Kodumuz çalışıyor! Bu aşamaya kadar gelebildiyseniz tebrikler!
Bir sonraki yazımda SURF algoritmasını kullanarak nesne tespit etmeyi anlatacağım. Okuduğunuz için teşekkürler.
Dostum anlatım için ağzına sağlık nesne tanımayı ne zaman anlatacan
YanıtlaSilCevat bey nesne tanima ile bir gelisma yakalayabildiniz eger okeyse paylasirsaniz sevinirim
SilSaygilarimla
Merhabalar hocam ben bu örneği yazdım fakat .xml satırında haarcascade ile ilgili satırdasarı renkli bir hata veriyor tam olarak ne yapmalıyım yardımcı olursanız çok sevinirim..
YanıtlaSilusing OpenCvSharp.MachineLearning; bu kısımda hata veriyor neden acaba yardımcı olur musunuz ?
YanıtlaSilBu yorum yazar tarafından silindi.
YanıtlaSilusing OpenCvSharp.Extensions;
Silbunu kullanıp çözüme ulaştım. sen de dene istersen.
Bu yorum yazar tarafından silindi.
SilBu yorum yazar tarafından silindi.
SilOpencv kutuphanesini tam yuklememissin
YanıtlaSilCvSeq faces = Cv.HaarDetectObjects(kucukresim, cascade, storage, ScaleFactor, MinNeighbors, 0, new CvSize(30, 30));
YanıtlaSilSatırında HaarDetectObjects'de hata gösteriyor.
aynı hata bendede var düzletebildinmi acaba ?
SilCvSeq faces = Cv.HaarDetectObjects(kucukresim, cascade, storage, ScaleFactor, MinNeighbors, 0, new CvSize(30, 30), new CvSize(80, 80));
SilBen sizler gibi ileri seviyede degilim sizlerin geldigi asamaya gelmem icin sanirim bu calisma icin uzun sure ugrasmam gerekecek,Rica etsem gelmis oldugunuz sondurmu exe sorce codlariyla benimle paylasabilirmisiniz paylasirsaniz inanin cok sevinirim
YanıtlaSilSaygilarim
CvSeq faces = Cv.HaarDetectObjects(kucukresim, cascade, storage, ScaleFactor, MinNeighbors, 0, new CvSize(30, 30));
YanıtlaSilHaarDetectObjects objesinde hata alıyorum hatanın nedenini çözemedim kodlar tamamen aynı
CvSeq faces = Cv.HaarDetectObjects(kucukresim, cascade, storage, ScaleFactor, MinNeighbors, 0, new CvSize(30, 30), new CvSize(80, 80));
SilMerhabalar bende Project > Manage NuGet Packages secenegi yok nasıl yapabılırım ?vs 2010 ultımate kullanıyorum
YanıtlaSilkütüphaneyi indirmemize rağmen machine learning de hata veriyor ve haarcascade kodunu google aracılığı ile bulup exe ye ekleyin deniyor ama binlerce satırlık bir code nasıl olacak
YanıtlaSilBu yorum bir blog yöneticisi tarafından silindi.
YanıtlaSilBu yorum yazar tarafından silindi.
YanıtlaSilOpenCvSharp Error hatası ile opencv_core240 yüklenemedi hatası alıyorum. ne yapmalıyım. lütfen yardım... :(
YanıtlaSilbu hatayı ben de alıyorum, çözüme ulaşabildiniz mi?
Sileditör içinde de
YanıtlaSilAdditional information: 'OpenCvSharp.CvInvoke' tür başlatıcısı özel durum döndürdü.
hatası alıyorum aynı problem için.