Önceki başlıkta haarcascade_frontalface_default.xml dosyasıyla yüz tespiti yapmıştık. Bu xml dosyası, insan yüzlerinin çeşitli şekillerini tutan bir veritabanıdır.
OpenCv ile herhangi bir objeyi görüntü üzerine aramanın yollarından biri, görüntüleri tarayarak bu şekilde xml dosyası oluşturmaktır. Yani insan yüzleri değil de mesela pet şişeleri görüntülerinin verilerini tutan bir xml dosyası oluştursaydık, aynı yöntemle pet şişeleri de bulabilirdik. Veya belirli kişilerin yüzünü de bulabilirdik... İşte bu yayınımızın olayı bu olacak.
Birlikte bir program yazacağız. Bu program, bu xml dosyasını oluşturmamız için bize adım adım yardımcı olacak. Konsol ekranında basit bir arayüzü olacak falan... Umuyorum ki bu konudaki nadir Türkçe kaynaklar arasında güzel bir alternatif yayın hazırlayacağız.
Bu yayını okumadan önce, Talha KOÇ'un yayınını okumanızı öneririm. Çünkü temelde aynı şeyleri farklı bir şekilde uygulayacağız. Ben aynı şeyleri kopyala-yapıştır'la buraya yazıp bilgi çöplüğü yaratmak istemedim. Obje bulma işinin temelini (ve hatta nasıl yapılabileceğini) o siteden de öğrenebilirsiniz. Faydalı paylaşımı için Talha KOÇ'a teşekkür ederim.
Not: Program bir yerden alıntı değil, kendi emeğimdir.
PROJE HAKKINDA GENEL BİLGİLER
Geliştirme ortamı: Visual Studio 2015 Community
Proje türü: C++ > ConsoleApplication
Proje adı: ConsoleApplication1
Çalıştığım sayfa: ConsoleApplicatin1.cpp
OpenCV sürümü: 3.1.0
BAŞLARKEN...
Bazı hazırlıklar yapmamız gerekiyor. Bir Console Application projesi oluşturduysanız, OpenCv'yi projemizde kullanmak için yapmamız gereken işlemleri de yapın. Bunun nasıl yapılacağını ilk başlıkta anlatmıştım.
OpenCv'nin Visual Studio ile ilişkisini de kurdunuz. Şimdi, projemizin çalıştığı klasörde bazı dosyalar oluşturmalıyız. Siz projenizi nereye kaydettiniz bilmiyorum ama fark etmez. Visual Studio'da sağdaki Solution Explorer'de projenizin adına
(ConsoleApplication1) sağ tık > Open Folder in File Explorer
deyin. Projenizin çalıştığı klasör açılacaktır. Ben bu klasöre bu yayın boyunca hep kök klasör diyeceğim.
Kök klasörümüz içine pozitif, negatif ve cascade adında üç klasör oluşturun. Bunların yanına pozitif.txt ve negatif.txt adında iki de metin belgesi oluşturun. Ayrıca OpenCv 3.1.0'ı kurduğunuz dizinden de opencv_createsamples.exe, opencv_traincascade.exe ve haarcascade_frontalface_default.xml dosyalarını da kopyalayıp kök klasörümüze yapıştırın. Eğer OpenCv'yi ilk başlıkta anlattığım yere kurduysanız, C:\OpenCV-3.1.0\ klasöründe bulunuyor olmalı. Değilse de siz nereye kurduysanız oraya bakarak bu dosyaları bulmalısınız...
Kök klasörümüze şu eklemeleri yapdınız:
negatif (boş bir klasör)
pozitif (boş bir klasör)
cascade (boş bir klasör)
negatif.txt (boş bir metin belgesi)
pozitif.txt (boş bir metin belgesi)
opencv_createsamples.exe (C:\OpenCV-3.1.0\build\x64\vc14\bin dizininde)
opencv_traincascade.exe (C:\OpenCV-3.1.0\build\x64\vc14\bin dizininde)
haarcascade_frontalface_default.xml (C:\OpenCV-3.1.0\build\etc\haarcascades dizininde)
pozitif (boş bir klasör)
cascade (boş bir klasör)
negatif.txt (boş bir metin belgesi)
pozitif.txt (boş bir metin belgesi)
opencv_createsamples.exe (C:\OpenCV-3.1.0\build\x64\vc14\bin dizininde)
opencv_traincascade.exe (C:\OpenCV-3.1.0\build\x64\vc14\bin dizininde)
haarcascade_frontalface_default.xml (C:\OpenCV-3.1.0\build\etc\haarcascades dizininde)
Proje sayfamıza (ConsoleApplication1.cpp) işimize yarayacak kütüphaneleri include edelim, namespace'leri çağıralım, fonksiyonlar ekleyelim, değişkenler oluşturalım:
#include "stdafx.h" // Her C++ projemizin başında bulunuyor
#include <fstream> // Dosya işlemleri için include ediyoruz
#include <opencv2\opencv.hpp> // OpenCv işlemleri için include ediyoruz
using namespace cv;
using namespace std;
// Farklı fonksiyonlarda kullanmak üzere global değişkenlerimizi belirliyoruz:
int mod; // Yapacağımız farklı işlemler arasında dolaşırken hangi işlemde olduğumuzu tutacağız.
int xx1, xx2, yy1, yy2; // Fare imleci ile seçtiğimiz alanın koordinatlarını tutacağız.
bool cizim; // Fare imleciyle çizim yapılıp yapılmayacağını tutacağız.
ofstream pozitif_txt, negatif_txt; // pozitif.txt ve negatif.txt dosyalarını belirteceğiz.
// main metodunun altında tanımlayacağımız metotları önce burada belirtiyoruz.
// Çünkü C++ dilinde, bir metot kullanıldığında, üst satırlarda o metot tanımlanmamışsa hata verir.
void TurkceKarakter(); // Konsol ekranında Türkçe karakterleri kullanabilmek için metot.
void ModYonlendir(); // Farklı işlemlerimiz (ben mod diyorum) arasında geçiş yapacak metot.
void AnaMenu(); // Konsol ekranında ana menü görünümünü oluşturacak metot.
void Mod1(); // Sadece kamera görüntüsünü alıp göstereceğimiz basit bir mod olacak.
void Mod2(); // Pozitif örneği nasıl oluşturmak istediğimizi soran bir alt menü göstereceğiz.
void Mod21(); // Fare imleci yardımıyla arayacağımız objeyi işaretleyebileceğiz ve kaydedeceğiz.
void Mod22(); // Yüz bulma amacımız varsa, görüntüde yüz göründüğü her kareyi kaydedebileceğiz.
void Mod3(); // Negatif örnekler oluşturmak için kullanacağız.
void Mod4(); // Pozitif görüntülerden bir *.vec dosyası oluşturacağız.
void Mod5(); // Oluşturduğumuz vec dosyasındaki görüntüleri tek tek kontrol edebileceğiz.
void Mod6(); // Her şey hazırsa artık eğitimi gerçekleştireceğiz.
int main() {
return 0;
}
// Bu yayın boyunca teker teker içini dolduracağımız metotlarımız:
void TurkceKarakter() { setlocale(LC_ALL, "Turkish"); } // Kısa olduğu için bunu hemen yazdım.
void ModYonlendir() { }
void AnaMenu() { }
void Mod1() { }
void Mod2() { }
void ImlecKoordinatKontrolu(int event, int x, int y, int flags, void *ek) { }
void Mod21() { }
void Mod22() { }
void Mod3() { }
void Mod4() { }
void Mod5() { }
void Mod6() { }
#include <fstream> // Dosya işlemleri için include ediyoruz
#include <opencv2\opencv.hpp> // OpenCv işlemleri için include ediyoruz
using namespace cv;
using namespace std;
// Farklı fonksiyonlarda kullanmak üzere global değişkenlerimizi belirliyoruz:
int mod; // Yapacağımız farklı işlemler arasında dolaşırken hangi işlemde olduğumuzu tutacağız.
int xx1, xx2, yy1, yy2; // Fare imleci ile seçtiğimiz alanın koordinatlarını tutacağız.
bool cizim; // Fare imleciyle çizim yapılıp yapılmayacağını tutacağız.
ofstream pozitif_txt, negatif_txt; // pozitif.txt ve negatif.txt dosyalarını belirteceğiz.
// main metodunun altında tanımlayacağımız metotları önce burada belirtiyoruz.
// Çünkü C++ dilinde, bir metot kullanıldığında, üst satırlarda o metot tanımlanmamışsa hata verir.
void TurkceKarakter(); // Konsol ekranında Türkçe karakterleri kullanabilmek için metot.
void ModYonlendir(); // Farklı işlemlerimiz (ben mod diyorum) arasında geçiş yapacak metot.
void AnaMenu(); // Konsol ekranında ana menü görünümünü oluşturacak metot.
void Mod1(); // Sadece kamera görüntüsünü alıp göstereceğimiz basit bir mod olacak.
void Mod2(); // Pozitif örneği nasıl oluşturmak istediğimizi soran bir alt menü göstereceğiz.
void Mod21(); // Fare imleci yardımıyla arayacağımız objeyi işaretleyebileceğiz ve kaydedeceğiz.
void Mod22(); // Yüz bulma amacımız varsa, görüntüde yüz göründüğü her kareyi kaydedebileceğiz.
void Mod3(); // Negatif örnekler oluşturmak için kullanacağız.
void Mod4(); // Pozitif görüntülerden bir *.vec dosyası oluşturacağız.
void Mod5(); // Oluşturduğumuz vec dosyasındaki görüntüleri tek tek kontrol edebileceğiz.
void Mod6(); // Her şey hazırsa artık eğitimi gerçekleştireceğiz.
int main() {
return 0;
}
// Bu yayın boyunca teker teker içini dolduracağımız metotlarımız:
void TurkceKarakter() { setlocale(LC_ALL, "Turkish"); } // Kısa olduğu için bunu hemen yazdım.
void ModYonlendir() { }
void AnaMenu() { }
void Mod1() { }
void Mod2() { }
void ImlecKoordinatKontrolu(int event, int x, int y, int flags, void *ek) { }
void Mod21() { }
void Mod22() { }
void Mod3() { }
void Mod4() { }
void Mod5() { }
void Mod6() { }
Önce modlar arasında geçiş yapmamızı sağlayacak metodumuzu oluşturalım. ModYonetimi() { ... } metodumuzun içine şunları yazalım:
if (mod == 0 ) AnaMenu();
else if (mod == 1 ) Mod1(); // Kamera modu
else if (mod == 2 ) Mod2(); // Pozitif örnek oluşturma menüsü
else if (mod == 21) Mod21(); // > İmleç yardımıyla işaretleyerek
else if (mod == 22) Mod22(); // > Otomatik yüz tespiti yardımıyla
else if (mod == 3 ) Mod3(); // Negatif örnek oluşturma modu
else if (mod == 4 ) Mod4(); // Vec dosyası oluşturma modu
else if (mod == 5 ) Mod5(); // Vec dosyası kontrolü modu
else if (mod == 6 ) Mod6(); // CascadeClassifier eğitim modu
Ben böyle mod diyorum ama umarım kafa karıştırmıyorumdur. Mod değimiz olay sadece hangi fonksiyonun çalışacağı olayı...else if (mod == 1 ) Mod1(); // Kamera modu
else if (mod == 2 ) Mod2(); // Pozitif örnek oluşturma menüsü
else if (mod == 21) Mod21(); // > İmleç yardımıyla işaretleyerek
else if (mod == 22) Mod22(); // > Otomatik yüz tespiti yardımıyla
else if (mod == 3 ) Mod3(); // Negatif örnek oluşturma modu
else if (mod == 4 ) Mod4(); // Vec dosyası oluşturma modu
else if (mod == 5 ) Mod5(); // Vec dosyası kontrolü modu
else if (mod == 6 ) Mod6(); // CascadeClassifier eğitim modu
Şimdi AnaMenu() { ... } metodumuzu yazalım:
system("CLS");
cout << " " << endl;
cout << " OpenCV Görüntü İşleme - Obje Tanıma Yazılımı " << endl;
cout << " *-----*------------------------------------* " << endl;
cout << " | 1 | Kamera modu | " << endl;
cout << " | 2 | Pozitif örnek oluşturma modu | " << endl;
cout << " | 3 | Negatif örnek oluşturma modu | " << endl;
cout << " | 4 | VEC dosyası oluşturma modu | " << endl;
cout << " | 5 | VEC dosyası kontrolü modu | " << endl;
cout << " | 6 | CascadeClassifier eğitim modu | " << endl;
cout << " *-----*------------------------------------* " << endl;
cout << " | 0 | Çıkış | " << endl;
cout << " *-----*------------------------------------* " << endl;
cout << " Çalıştırmak istediğiniz mod numarası: ";
cin >> mod;
// Ana menüdeyken mod 0 yapılırsa program kapatılır:
if (mod != 0) ModYonlendir();
system("CLS"); komutuyla konsol ekranını temizliyorum. Global olan mod değişkeninin değerini alıyorum. Daha sonra ModYonlendir(); metodunu çağırıyorum. O da mod değişkeninin değerine göre ilgili metodu çağırıyor.cout << " " << endl;
cout << " OpenCV Görüntü İşleme - Obje Tanıma Yazılımı " << endl;
cout << " *-----*------------------------------------* " << endl;
cout << " | 1 | Kamera modu | " << endl;
cout << " | 2 | Pozitif örnek oluşturma modu | " << endl;
cout << " | 3 | Negatif örnek oluşturma modu | " << endl;
cout << " | 4 | VEC dosyası oluşturma modu | " << endl;
cout << " | 5 | VEC dosyası kontrolü modu | " << endl;
cout << " | 6 | CascadeClassifier eğitim modu | " << endl;
cout << " *-----*------------------------------------* " << endl;
cout << " | 0 | Çıkış | " << endl;
cout << " *-----*------------------------------------* " << endl;
cout << " Çalıştırmak istediğiniz mod numarası: ";
cin >> mod;
// Ana menüdeyken mod 0 yapılırsa program kapatılır:
if (mod != 0) ModYonlendir();
Şimdi sadece kameradan görüntü alıp göstermeye yarayan, aslında projemizle hiçbir alakası olmasa da böyle bir projede yine de bulunsun diyebileceğimiz Mod1() {...} metodunu yazalım:
system("CLS");
cout << " " << endl;
cout << " << KAMERA MODU ETKİNLEŞTİRİLDİ >>" << endl;
cout << " Ana menüye dönmek için \"Kamera\" penceresindeyken ESC tuşuna basınız.";
VideoCapture capture(0);
Mat frame;
namedWindow("Kamera");
while (true) {
capture.read(frame);
flip(frame, frame,1);
imshow("Kamera", frame);
if (waitKey(50) == 27) break;
}
system("CLS");
cout << " " << endl;
cout << " << KAMERA MODU KAPATILIYOR -> Ana Menüye Dönülüyor... >>";
destroyWindow("Kamera");
capture.release();
frame.release();
mod = 0;
ModYonlendir();
Burada yine sisteme CLS komutu vererek konsol ekranını temizliyorum.cout << " " << endl;
cout << " << KAMERA MODU ETKİNLEŞTİRİLDİ >>" << endl;
cout << " Ana menüye dönmek için \"Kamera\" penceresindeyken ESC tuşuna basınız.";
VideoCapture capture(0);
Mat frame;
namedWindow("Kamera");
while (true) {
capture.read(frame);
flip(frame, frame,1);
imshow("Kamera", frame);
if (waitKey(50) == 27) break;
}
system("CLS");
cout << " " << endl;
cout << " << KAMERA MODU KAPATILIYOR -> Ana Menüye Dönülüyor... >>";
destroyWindow("Kamera");
capture.release();
frame.release();
mod = 0;
ModYonlendir();
Ekrana bilgilendirici yazılar falan yazdırıyorum.
Klavyeden ESC'ye basılana kadar da while döngüsü içinde kamera görüntüsünü gösteriyorum.
Halen asıl meseleye geçmiş değiliz. Mod2() {...} metodumuz da yine tasarımla alakalı. Burada pozitif resim oluşturmak için iki seçenek sunacağız.
Kamera görüntüsünde aradığınız nesneyi fare ile işaretleyerek mi pozitif örnek oluşturmak istiyorsun, yoksa yüz tanıma işlemi mi yapacaksın? Çünkü yüz tanıma işlemi yapacaksan yüzü ben senin için kameradan tespit edeyim ve yüz gördüğüm her anı kaydedeyim... diyeceğiz.
system("CLS");
cout << " " << endl;
cout << " OpenCV Görüntü İşleme - Pozitif Örnek Menüsü " << endl;
cout << " *-----*------------------------------------* " << endl;
cout << " | 1 | İmleç yardımıyla işaretleyerek | " << endl;
cout << " | 2 | Otomatik yüz tespiti yardımıyla | " << endl;
cout << " *-----*------------------------------------* " << endl;
cout << " | 0 | Ana menü | " << endl;
cout << " *-----*------------------------------------* " << endl;
cout << " Çalıştırmak istediğiniz mod numarası: ";
cin >> mod;
if (mod == 1) mod = 21;
else if (mod == 2) mod = 22;
else mod = 0;
ModYonlendir();
cout << " " << endl;
cout << " OpenCV Görüntü İşleme - Pozitif Örnek Menüsü " << endl;
cout << " *-----*------------------------------------* " << endl;
cout << " | 1 | İmleç yardımıyla işaretleyerek | " << endl;
cout << " | 2 | Otomatik yüz tespiti yardımıyla | " << endl;
cout << " *-----*------------------------------------* " << endl;
cout << " | 0 | Ana menü | " << endl;
cout << " *-----*------------------------------------* " << endl;
cout << " Çalıştırmak istediğiniz mod numarası: ";
cin >> mod;
if (mod == 1) mod = 21;
else if (mod == 2) mod = 22;
else mod = 0;
ModYonlendir();
Şimdi asıl noktaya geliyoruz. Pozitif görüntü örnekleri oluşturmak için fare ile işaretleme yöntemi. Bu yöntemde kamera anlık olarak görüntüyü Mod1()de olduğu gibi pencerede gösteriyor. Eğer klavyeden S tuşuna basılırsa kayıt moduna geçiyor. Kayıt moduna geçildiğinin anlaşılabilmesi için pencerenin sol üst köşesine bir daire çiziyoruz. Sonra fare ile ekranda çizim yapabiliyoruz. Çizdiğimiz koordinatlarla beraber pozitif görüntüyü oluşturmak için de fareyi tıklamayı bırakmadan klavyeden boşluk tuşuna basılınca görüntüyü kaydediyoruz.
Önce, farenin sol tuşuna tıklandığında farenin koordinatlarını yakalayıp xx1, xx2, yy1, yy2 adlı global değişkenlerimize gönderdiğimiz ImlecKoordinatKontrolu() metodumuzu oluşturalım:
if (event == EVENT_LBUTTONDOWN) { cizim = true; xx1 = x; yy1 = y; xx2 = x; yy2 = y;}
if (event == EVENT_MOUSEMOVE && cizim) { xx2 = x; yy2 = y; }
if (event == EVENT_LBUTTONUP) { cizim = false; }
if (event == EVENT_MOUSEMOVE && cizim) { xx2 = x; yy2 = y; }
if (event == EVENT_LBUTTONUP) { cizim = false; }
Şimdi de bu değerlere göre pencerede istenilen yeri işaretleyen ve boşluk tuşuna basınca da pozitif görüntü örneği oluşturan (hem resmi kaydeden, hem de pozitif.txt dosyasına koordinat bilgisiyle birlikte resmin adını yazan) metodumuz olan Mod21() metodumuzu oluşturalım:
pozitif_txt.open("pozitif.txt", ios::app);
int pozitifGoruntuNo = 0;
system("CLS");
cout << " " << endl;
cout << " Kaçıncı pozitif resimde kaldığınızı giriniz: ";
cin >> pozitifGoruntuNo;
pozitifGoruntuNo++;
if (pozitifGoruntuNo != 1) pozitif_txt << "\r" << endl;
system("CLS");
cout << " " << endl;
cout << " << POZİTİF ÖRNEK OLUŞTURUCU MOD-1 ETKİNLEŞTİRİLDİ >>" << endl;
cout << " S harfi tuşuna basarak oluşturucu modunu açıp kapatabilirsiniz." << endl;
cout << " İmleç yardımıyla, objenin görüntüsünü dikdörtgen içine alınız." << endl;
cout << " İşaretlenmiş görüntünün kaydı için fareyi bırakmadan boşluk tuşuna basınız." << endl;
cout << " Ana menüye dönmek için, kamera akarken ESC tuşuna basınız.";
VideoCapture capture(0);
Mat frame,yanFrame;
namedWindow("Kamera");
bool cizimModu = false;
int buton = 0;
char goruntuAdi[100];
while (true) {
buton = waitKey(50);
if (buton == 83 || buton == 115) cizimModu = (cizimModu) ? false : true;
capture.read(frame);
flip(frame, frame, 1);
cvtColor(frame, yanFrame, CV_BGR2GRAY);
equalizeHist(yanFrame, yanFrame);
if (cizimModu) { // S tuşuna basıldığında cizimModu açılır ve fare tıklamaları dikkate alınır.
circle(frame, Point(30, 30), 12, Scalar(0, 0, 255),-1);
setMouseCallback("Kamera", ImlecKoordinatKontrolu, NULL);
if (cizim) { // Fareye tıklandığında bu blok işler
rectangle(frame, Point(xx1, yy1), Point(xx2, yy2), Scalar(0, 0, 255));
if (buton == 32) { // cizimModu açıkken boşluk tuşuna basılınca pozitif örnek kaydedilir.
_snprintf_s(goruntuAdi, 100, "pozitif/img%d.jpg", pozitifGoruntuNo);
// Pencerede normal görüntü gösteriliyor olsa da
// gri skalada histogram eşitlenmiş görüntü kaydediliyor.
// Orijinal görüntüyü de kaydedebilirdik. Mecburi değil:
imwrite(goruntuAdi, yanFrame, { CV_IMWRITE_JPEG_QUALITY ,100 });
_snprintf_s(goruntuAdi, 250, "pozitif\\img%d.jpg", pozitifGoruntuNo);
pozitif_txt
<< goruntuAdi << " 1 "
<< xx1 << " "
<< yy1 << " "
<< xx2 - xx1 << " "
<< yy2 - yy1 << endl;
pozitifGoruntuNo++;
cizim = false;
}
}
}
putText(
frame,
to_string(pozitifGoruntuNo - 1),
Point(70, 40),
HersheyFonts::FONT_HERSHEY_COMPLEX,
1,
Scalar(255, 0, 0));
imshow("Kamera", frame);
if (buton == 27) break;
}
destroyWindow("Kamera");
pozitif_txt.close();
capture.release();
frame.release();
yanFrame.release();
mod = 0;
ModYonlendir();
int pozitifGoruntuNo = 0;
system("CLS");
cout << " " << endl;
cout << " Kaçıncı pozitif resimde kaldığınızı giriniz: ";
cin >> pozitifGoruntuNo;
pozitifGoruntuNo++;
if (pozitifGoruntuNo != 1) pozitif_txt << "\r" << endl;
system("CLS");
cout << " " << endl;
cout << " << POZİTİF ÖRNEK OLUŞTURUCU MOD-1 ETKİNLEŞTİRİLDİ >>" << endl;
cout << " S harfi tuşuna basarak oluşturucu modunu açıp kapatabilirsiniz." << endl;
cout << " İmleç yardımıyla, objenin görüntüsünü dikdörtgen içine alınız." << endl;
cout << " İşaretlenmiş görüntünün kaydı için fareyi bırakmadan boşluk tuşuna basınız." << endl;
cout << " Ana menüye dönmek için, kamera akarken ESC tuşuna basınız.";
VideoCapture capture(0);
Mat frame,yanFrame;
namedWindow("Kamera");
bool cizimModu = false;
int buton = 0;
char goruntuAdi[100];
while (true) {
buton = waitKey(50);
if (buton == 83 || buton == 115) cizimModu = (cizimModu) ? false : true;
capture.read(frame);
flip(frame, frame, 1);
cvtColor(frame, yanFrame, CV_BGR2GRAY);
equalizeHist(yanFrame, yanFrame);
if (cizimModu) { // S tuşuna basıldığında cizimModu açılır ve fare tıklamaları dikkate alınır.
circle(frame, Point(30, 30), 12, Scalar(0, 0, 255),-1);
setMouseCallback("Kamera", ImlecKoordinatKontrolu, NULL);
if (cizim) { // Fareye tıklandığında bu blok işler
rectangle(frame, Point(xx1, yy1), Point(xx2, yy2), Scalar(0, 0, 255));
if (buton == 32) { // cizimModu açıkken boşluk tuşuna basılınca pozitif örnek kaydedilir.
_snprintf_s(goruntuAdi, 100, "pozitif/img%d.jpg", pozitifGoruntuNo);
// Pencerede normal görüntü gösteriliyor olsa da
// gri skalada histogram eşitlenmiş görüntü kaydediliyor.
// Orijinal görüntüyü de kaydedebilirdik. Mecburi değil:
imwrite(goruntuAdi, yanFrame, { CV_IMWRITE_JPEG_QUALITY ,100 });
_snprintf_s(goruntuAdi, 250, "pozitif\\img%d.jpg", pozitifGoruntuNo);
pozitif_txt
<< goruntuAdi << " 1 "
<< xx1 << " "
<< yy1 << " "
<< xx2 - xx1 << " "
<< yy2 - yy1 << endl;
pozitifGoruntuNo++;
cizim = false;
}
}
}
putText(
frame,
to_string(pozitifGoruntuNo - 1),
Point(70, 40),
HersheyFonts::FONT_HERSHEY_COMPLEX,
1,
Scalar(255, 0, 0));
imshow("Kamera", frame);
if (buton == 27) break;
}
destroyWindow("Kamera");
pozitif_txt.close();
capture.release();
frame.release();
yanFrame.release();
mod = 0;
ModYonlendir();
Mod22() metodunda, kamerada yüz tespiti otomatik olarak yapılıyor. Eğer boşluk tuşuna basılıp kayıt başlatılmışsa da ekranda yüz tespit edilen her bir kare direkt olarak kaydediliyor. Eğer yüz tanıma işlemi yapacaksak görüntülerin çoğunu bu mod sayesinde hızlıca hazırlayabileceğiz. Buyurun kodlar:
pozitif_txt.open("pozitif.txt", ios::app);
int pozitifGoruntuNo = 0;
system("CLS");
cout << " " << endl;
cout << " Kaçıncı pozitif resimde kaldığınızı giriniz: ";
cin >> pozitifGoruntuNo;
pozitifGoruntuNo++;
if (pozitifGoruntuNo != 1) pozitif_txt << "\r" << endl;
system("CLS");
cout << " " << endl;
cout << " << POZİTİF ÖRNEK OLUŞTURUCU MOD-2 ETKİNLEŞTİRİLDİ >>" << endl;
cout << " Boşluk tuşuna basarak kayıt modunu başlatıp durdurabilirsiniz." << endl;
cout << " Kayıt modu açıksa pencerenin sol üst köşesinde kırmızı bir daire belirecektir." << endl;
cout << " Yazılım, ekranda yüz bulduğu her an otomatik olarak kayıt yapacaktır." << endl;
cout << " Ana menüye dönmek için, kamera akarken ESC tuşuna basınız.";
VideoCapture capture(0);
Mat frame, yanFrame;
bool kayitModu = false;
int buton = 0;
namedWindow("Kamera");
char goruntuAdi[100];
CascadeClassifier dedektor_frontalFace("haarcascade_frontalface_default.xml");
int minKomsu = 10;
double scaleStep = 1.1;
Size minNesne(100, 100);
Size maxNesne(250, 250);
vector<Rect> bulunan_frontalFace;
while (true) {
buton = waitKey(50);
if (buton == 32) kayitModu = (kayitModu) ? false : true;
capture.read(frame);
flip(frame, frame, 1);
cvtColor(frame, yanFrame, CV_BGR2GRAY);
equalizeHist(yanFrame, yanFrame);
bulunan_frontalFace.clear();
dedektor_frontalFace.detectMultiScale(yanFrame, bulunan_frontalFace, scaleStep, minKomsu, 2, minNesne, maxNesne);
if (bulunan_frontalFace.size() > 0) {
if (kayitModu) {
_snprintf_s(goruntuAdi, 100, "pozitif/img%d.jpg", pozitifGoruntuNo);
imwrite(goruntuAdi, yanFrame, { CV_IMWRITE_JPEG_QUALITY ,100 });
_snprintf_s(goruntuAdi, 100, "pozitif\\img%d.jpg", pozitifGoruntuNo);
pozitif_txt
<< goruntuAdi << " 1 "
<< bulunan_frontalFace[0].x << " "
<< bulunan_frontalFace[0].y << " "
<< bulunan_frontalFace[0].width << " "
<< bulunan_frontalFace[0].height << endl;
pozitifGoruntuNo++;
circle(frame, Point(30, 30), 12, Scalar(0, 0, 255), -1);
rectangle(frame, bulunan_frontalFace[0].br(), bulunan_frontalFace[0].tl(), Scalar(0, 0, 255));
}
else rectangle(frame, bulunan_frontalFace[0].br(), bulunan_frontalFace[0].tl(), Scalar(0, 0, 0));
}
putText(
frame,
to_string(pozitifGoruntuNo - 1),
Point(70, 40),
HersheyFonts::FONT_HERSHEY_COMPLEX,
1,
Scalar(255, 0, 0));
imshow("Kamera", frame);
if (buton == 27) break;
}
destroyWindow("Kamera");
capture.release();
frame.release();
yanFrame.release();
pozitif_txt.close();
mod = 0;
ModYonlendir();
int pozitifGoruntuNo = 0;
system("CLS");
cout << " " << endl;
cout << " Kaçıncı pozitif resimde kaldığınızı giriniz: ";
cin >> pozitifGoruntuNo;
pozitifGoruntuNo++;
if (pozitifGoruntuNo != 1) pozitif_txt << "\r" << endl;
system("CLS");
cout << " " << endl;
cout << " << POZİTİF ÖRNEK OLUŞTURUCU MOD-2 ETKİNLEŞTİRİLDİ >>" << endl;
cout << " Boşluk tuşuna basarak kayıt modunu başlatıp durdurabilirsiniz." << endl;
cout << " Kayıt modu açıksa pencerenin sol üst köşesinde kırmızı bir daire belirecektir." << endl;
cout << " Yazılım, ekranda yüz bulduğu her an otomatik olarak kayıt yapacaktır." << endl;
cout << " Ana menüye dönmek için, kamera akarken ESC tuşuna basınız.";
VideoCapture capture(0);
Mat frame, yanFrame;
bool kayitModu = false;
int buton = 0;
namedWindow("Kamera");
char goruntuAdi[100];
CascadeClassifier dedektor_frontalFace("haarcascade_frontalface_default.xml");
int minKomsu = 10;
double scaleStep = 1.1;
Size minNesne(100, 100);
Size maxNesne(250, 250);
vector<Rect> bulunan_frontalFace;
while (true) {
buton = waitKey(50);
if (buton == 32) kayitModu = (kayitModu) ? false : true;
capture.read(frame);
flip(frame, frame, 1);
cvtColor(frame, yanFrame, CV_BGR2GRAY);
equalizeHist(yanFrame, yanFrame);
bulunan_frontalFace.clear();
dedektor_frontalFace.detectMultiScale(yanFrame, bulunan_frontalFace, scaleStep, minKomsu, 2, minNesne, maxNesne);
if (bulunan_frontalFace.size() > 0) {
if (kayitModu) {
_snprintf_s(goruntuAdi, 100, "pozitif/img%d.jpg", pozitifGoruntuNo);
imwrite(goruntuAdi, yanFrame, { CV_IMWRITE_JPEG_QUALITY ,100 });
_snprintf_s(goruntuAdi, 100, "pozitif\\img%d.jpg", pozitifGoruntuNo);
pozitif_txt
<< goruntuAdi << " 1 "
<< bulunan_frontalFace[0].x << " "
<< bulunan_frontalFace[0].y << " "
<< bulunan_frontalFace[0].width << " "
<< bulunan_frontalFace[0].height << endl;
pozitifGoruntuNo++;
circle(frame, Point(30, 30), 12, Scalar(0, 0, 255), -1);
rectangle(frame, bulunan_frontalFace[0].br(), bulunan_frontalFace[0].tl(), Scalar(0, 0, 255));
}
else rectangle(frame, bulunan_frontalFace[0].br(), bulunan_frontalFace[0].tl(), Scalar(0, 0, 0));
}
putText(
frame,
to_string(pozitifGoruntuNo - 1),
Point(70, 40),
HersheyFonts::FONT_HERSHEY_COMPLEX,
1,
Scalar(255, 0, 0));
imshow("Kamera", frame);
if (buton == 27) break;
}
destroyWindow("Kamera");
capture.release();
frame.release();
yanFrame.release();
pozitif_txt.close();
mod = 0;
ModYonlendir();
Mod3() { ... } ile negatif görüntüleri oluşturacağız.
negatif_txt.open("negatif.txt", ios::app);
int negatifGoruntuNo;
system("CLS");
cout << " " << endl;
cout << " Kaçıncı negatif örnekte kaldığınızı giriniz: ";
cin >> negatifGoruntuNo;
negatifGoruntuNo++;
if (negatifGoruntuNo != 1) negatif_txt << "\r" << endl;
system("CLS");
cout << " " << endl;
cout << " << NEGATİF ÖRNEK OLUŞTURUCU MOD ETKİNLEŞTİRİLDİ >>" << endl;
cout << " Boşluk tuşuna basarak negatif örneği kaydedebilirsiniz" << endl;
cout << " Ana menüye dönmek için \"Kamera\" penceresindeyken ESC tuşuna basınız.";
int buton = 0;
VideoCapture capture(0);
Mat frame;
namedWindow("Kamera");
char goruntuAdi[100];
bool kayitModu = false;
while (true) {
buton = waitKey(50);
capture.read(frame);
flip(frame, frame, 1);
if (buton == 32) kayitModu = (kayitModu) ? false : true;
if (kayitModu) {
_snprintf_s(goruntuAdi, 200, "negatif/img%d.jpg", negatifGoruntuNo);
imwrite(goruntuAdi, frame, { CV_IMWRITE_JPEG_QUALITY ,100 });
_snprintf_s(goruntuAdi, 250, "negatif\\img%d.jpg", negatifGoruntuNo);
negatif_txt << goruntuAdi << endl;
negatifGoruntuNo++;
circle(frame, Point(30, 30), 10, Scalar(0, 0, 255), -1);
}
putText(
frame,
to_string(negatifGoruntuNo-1),
Point(70, 40),
HersheyFonts::FONT_HERSHEY_COMPLEX,
1,
Scalar(255, 0, 0));
imshow("Kamera", frame);
if (buton == 27) break;
}
destroyWindow("Kamera");
capture.release();
frame.release();
negatif_txt.close();
mod = 0;
ModYonlendir();
int negatifGoruntuNo;
system("CLS");
cout << " " << endl;
cout << " Kaçıncı negatif örnekte kaldığınızı giriniz: ";
cin >> negatifGoruntuNo;
negatifGoruntuNo++;
if (negatifGoruntuNo != 1) negatif_txt << "\r" << endl;
system("CLS");
cout << " " << endl;
cout << " << NEGATİF ÖRNEK OLUŞTURUCU MOD ETKİNLEŞTİRİLDİ >>" << endl;
cout << " Boşluk tuşuna basarak negatif örneği kaydedebilirsiniz" << endl;
cout << " Ana menüye dönmek için \"Kamera\" penceresindeyken ESC tuşuna basınız.";
int buton = 0;
VideoCapture capture(0);
Mat frame;
namedWindow("Kamera");
char goruntuAdi[100];
bool kayitModu = false;
while (true) {
buton = waitKey(50);
capture.read(frame);
flip(frame, frame, 1);
if (buton == 32) kayitModu = (kayitModu) ? false : true;
if (kayitModu) {
_snprintf_s(goruntuAdi, 200, "negatif/img%d.jpg", negatifGoruntuNo);
imwrite(goruntuAdi, frame, { CV_IMWRITE_JPEG_QUALITY ,100 });
_snprintf_s(goruntuAdi, 250, "negatif\\img%d.jpg", negatifGoruntuNo);
negatif_txt << goruntuAdi << endl;
negatifGoruntuNo++;
circle(frame, Point(30, 30), 10, Scalar(0, 0, 255), -1);
}
putText(
frame,
to_string(negatifGoruntuNo-1),
Point(70, 40),
HersheyFonts::FONT_HERSHEY_COMPLEX,
1,
Scalar(255, 0, 0));
imshow("Kamera", frame);
if (buton == 27) break;
}
destroyWindow("Kamera");
capture.release();
frame.release();
negatif_txt.close();
mod = 0;
ModYonlendir();
Pozitif ve negatif örnekleri oluşturabileceğimiz metotlarımız hazır olduğuna göre artık pozitif örneklerden vec dosyası oluşturma işine geçebiliriz. Mod4() metodumuz daha küçük ve genellikle yazılardan oluşuyor:
int sayi = 0;
char komut[200];
system("CLS");
cout << " " << endl;
cout << " << EĞİTİM VERİSİ OLUŞTURMA MODU >>" << endl;
cout << " İşlem yapmadan ana menüye dönmek için 0 giriniz." << endl;
cout << " " << endl;
cout << " Pozitif görüntülerden VEC dosyası oluşturmak için," << endl;
cout << " Kaydedilmiş pozitif görüntü sayısını giriniz: ";
cin >> sayi;
system("CLS");
cout << " " << endl;
cout << " << EĞİTİM VERİSİ OLUŞTURMA MODU ETKİNLEŞTİRİLDİ >>" << endl;
_snprintf_s(komut, 200, "opencv_createsamples.exe -info pozitif.txt -num %d -vec egitimseti.vec -w 24 -h 24", sayi);
cout << " " << sayi << " sayıda pozitif görüntüden vektorel egitim seti olusturuluyor..." << endl;
system(komut);
cout << " Vektorel egitim seti olusturuldu." << endl;
cout << " Ana menüye dönmek için 0 girin." << endl;
cout << " Eğitim verisi elemanlarını tek tek kontrol etmek için 1 girin." << endl;
cout << " Yapmak istediğiniz işlem: "; cin >> sayi;
if (sayi == 1) mod = 5;
else mod = 0;
ModYonlendir();
char komut[200];
system("CLS");
cout << " " << endl;
cout << " << EĞİTİM VERİSİ OLUŞTURMA MODU >>" << endl;
cout << " İşlem yapmadan ana menüye dönmek için 0 giriniz." << endl;
cout << " " << endl;
cout << " Pozitif görüntülerden VEC dosyası oluşturmak için," << endl;
cout << " Kaydedilmiş pozitif görüntü sayısını giriniz: ";
cin >> sayi;
system("CLS");
cout << " " << endl;
cout << " << EĞİTİM VERİSİ OLUŞTURMA MODU ETKİNLEŞTİRİLDİ >>" << endl;
_snprintf_s(komut, 200, "opencv_createsamples.exe -info pozitif.txt -num %d -vec egitimseti.vec -w 24 -h 24", sayi);
cout << " " << sayi << " sayıda pozitif görüntüden vektorel egitim seti olusturuluyor..." << endl;
system(komut);
cout << " Vektorel egitim seti olusturuldu." << endl;
cout << " Ana menüye dönmek için 0 girin." << endl;
cout << " Eğitim verisi elemanlarını tek tek kontrol etmek için 1 girin." << endl;
cout << " Yapmak istediğiniz işlem: "; cin >> sayi;
if (sayi == 1) mod = 5;
else mod = 0;
ModYonlendir();
Mod5() metodumuz, hazırladığımız vec dosyasının kontrolünü yapmaya yarayacak:
system("CLS");
cout << " " << endl;
cout << " << EĞİTİM VERİSİ KONTROL MODU >>" << endl;
cout << " Kontrol modu etkinleştirilsin mi? (e/h) ";
char cevap; cin >> cevap;
if (cevap == 'E' || cevap == 'e' || cevap == 'Y' || cevap == 'y' || cevap == '1') {
system("CLS");
cout << " " << endl;
cout << " << EĞİTİM VERİSİ KONTROL MODU ETKİNLEŞTİRİLDİ >>" << endl;
cout << " Sıradaki görüntüye geçmek için boşluk tuşuna basınız." << endl;
cout << " Görüntüler bittiğinde otomatik olarak ana sayfaya yönlendirileceksiniz." << endl;
system("opencv_createsamples.exe -vec egitimseti.vec PAUSE");
}
mod = 0;
ModYonlendir();
cout << " " << endl;
cout << " << EĞİTİM VERİSİ KONTROL MODU >>" << endl;
cout << " Kontrol modu etkinleştirilsin mi? (e/h) ";
char cevap; cin >> cevap;
if (cevap == 'E' || cevap == 'e' || cevap == 'Y' || cevap == 'y' || cevap == '1') {
system("CLS");
cout << " " << endl;
cout << " << EĞİTİM VERİSİ KONTROL MODU ETKİNLEŞTİRİLDİ >>" << endl;
cout << " Sıradaki görüntüye geçmek için boşluk tuşuna basınız." << endl;
cout << " Görüntüler bittiğinde otomatik olarak ana sayfaya yönlendirileceksiniz." << endl;
system("opencv_createsamples.exe -vec egitimseti.vec PAUSE");
}
mod = 0;
ModYonlendir();
Mod6() metodumuz da asıl işi yaparak bize bir xml dosyası sunacak:
system("CLS");
cout << " " << endl;
cout << " << EĞİTİM VERİSİ KONTROL MODU >>" << endl;
cout << " Bu modu etkinleştirdiğinizde uzun sürebilecek olan eğitim gerçekleştirilir." << endl;
cout << " Eğitim sonucunda XML dosyası oluşturulur." << endl;
cout << " Eğitim modunu etkinleştirmek istiyor musunuz? (e/h) ";
char cevap; cin >> cevap;
if (cevap == 'E' || cevap == 'e' || cevap == 'Y' || cevap == 'y' || cevap == '1') {
int pozGor;
int negGor;
float minHitRate = 0.995;
int asamaSayisi;
cout << " Pozitif görüntü sayınızı giriniz: "; cin >> pozGor;
cout << " Negatif görüntü sayınızı giriniz: "; cin >> negGor;
cout << " Eğitim aşama sayısını giriniz: "; cin >> asamaSayisi;
int numPos = floor((pozGor - negGor) / (1 + (asamaSayisi - 1)*(1 - minHitRate)));
char komut[500];
_snprintf_s(komut, 500, "opencv_traincascade.exe -data cascade/ -vec egitimseti.vec -bg negatif.txt -numPos %d -numNeg %d -numStages %d -minHitRate 0.995 -maxFalseAlarmRate 0.25 -mem 1024 -w 24 -h 24", numPos, negGor, asamaSayisi);
system(komut);
system("PAUSE");
}
mod = 0;
ModYonlendir();
cout << " " << endl;
cout << " << EĞİTİM VERİSİ KONTROL MODU >>" << endl;
cout << " Bu modu etkinleştirdiğinizde uzun sürebilecek olan eğitim gerçekleştirilir." << endl;
cout << " Eğitim sonucunda XML dosyası oluşturulur." << endl;
cout << " Eğitim modunu etkinleştirmek istiyor musunuz? (e/h) ";
char cevap; cin >> cevap;
if (cevap == 'E' || cevap == 'e' || cevap == 'Y' || cevap == 'y' || cevap == '1') {
int pozGor;
int negGor;
float minHitRate = 0.995;
int asamaSayisi;
cout << " Pozitif görüntü sayınızı giriniz: "; cin >> pozGor;
cout << " Negatif görüntü sayınızı giriniz: "; cin >> negGor;
cout << " Eğitim aşama sayısını giriniz: "; cin >> asamaSayisi;
int numPos = floor((pozGor - negGor) / (1 + (asamaSayisi - 1)*(1 - minHitRate)));
char komut[500];
_snprintf_s(komut, 500, "opencv_traincascade.exe -data cascade/ -vec egitimseti.vec -bg negatif.txt -numPos %d -numNeg %d -numStages %d -minHitRate 0.995 -maxFalseAlarmRate 0.25 -mem 1024 -w 24 -h 24", numPos, negGor, asamaSayisi);
system(komut);
system("PAUSE");
}
mod = 0;
ModYonlendir();
Son olarak da eğittiğimiz Cascade sınıflandırıcımızı test edebileceğimiz Mod7() metodumuzu yazalım:
VideoCapture capture(0);
Mat frame, yanFrame;
bool kayitModu = false;
int buton = 0;
namedWindow("Kamera");
CascadeClassifier dedektor_frontalFace("cascade/cascade.xml");
int minKomsu = 10;
double scaleStep = 1.1;
Size minNesne(50, 50);
Size maxNesne(300, 300);
vector<Rect> bulunan_obje;
Scalar kareRengi = Scalar(0,0,0);
while (true) {
buton = waitKey(50);
capture.read(frame);
flip(frame, frame, 1);
cvtColor(frame, yanFrame, CV_BGR2GRAY);
equalizeHist(yanFrame, yanFrame);
bulunan_obje.clear();
dedektor_frontalFace.detectMultiScale(yanFrame, bulunan_obje, scaleStep, minKomsu, 2, minNesne, maxNesne);
if (bulunan_obje.size() > 0) {
for (int i = 0;i < bulunan_obje.size();i++) {
switch (i) {
case 0: kareRengi = Scalar(0, 0, 0); break;
case 1: kareRengi = Scalar(0, 0, 255); break;
case 2: kareRengi = Scalar(0, 255, 0); break;
case 3: kareRengi = Scalar(0, 255, 255); break;
case 4: kareRengi = Scalar(255, 0, 0); break;
case 5: kareRengi = Scalar(255, 0, 255); break;
case 6: kareRengi = Scalar(255, 255, 0); break;
case 7: kareRengi = Scalar(255, 255, 255); break;
}
rectangle(frame, bulunan_obje[i].br(), bulunan_obje[i].tl(), kareRengi,2);
}
}
imshow("Kamera", frame);
if (buton == 27) break;
}
destroyWindow("Kamera");
capture.release();
frame.release();
yanFrame.release();
mod = 0;
ModYonlendir();
Mat frame, yanFrame;
bool kayitModu = false;
int buton = 0;
namedWindow("Kamera");
CascadeClassifier dedektor_frontalFace("cascade/cascade.xml");
int minKomsu = 10;
double scaleStep = 1.1;
Size minNesne(50, 50);
Size maxNesne(300, 300);
vector<Rect> bulunan_obje;
Scalar kareRengi = Scalar(0,0,0);
while (true) {
buton = waitKey(50);
capture.read(frame);
flip(frame, frame, 1);
cvtColor(frame, yanFrame, CV_BGR2GRAY);
equalizeHist(yanFrame, yanFrame);
bulunan_obje.clear();
dedektor_frontalFace.detectMultiScale(yanFrame, bulunan_obje, scaleStep, minKomsu, 2, minNesne, maxNesne);
if (bulunan_obje.size() > 0) {
for (int i = 0;i < bulunan_obje.size();i++) {
switch (i) {
case 0: kareRengi = Scalar(0, 0, 0); break;
case 1: kareRengi = Scalar(0, 0, 255); break;
case 2: kareRengi = Scalar(0, 255, 0); break;
case 3: kareRengi = Scalar(0, 255, 255); break;
case 4: kareRengi = Scalar(255, 0, 0); break;
case 5: kareRengi = Scalar(255, 0, 255); break;
case 6: kareRengi = Scalar(255, 255, 0); break;
case 7: kareRengi = Scalar(255, 255, 255); break;
}
rectangle(frame, bulunan_obje[i].br(), bulunan_obje[i].tl(), kareRengi,2);
}
}
imshow("Kamera", frame);
if (buton == 27) break;
}
destroyWindow("Kamera");
capture.release();
frame.release();
yanFrame.release();
mod = 0;
ModYonlendir();
Böylelikle programımız tamamlandı. Denemek için programı çalıştırın. 100 tane pozitif örnek, 50 tane de negatif örnek oluşturun. Eğitim modunda da eğitim aşama sayısını 2 verin. Size çok kötü hazırlanmış bir xml dosyası sunacaktır. Çünkü Talha KOÇ'un ilgili yazısını veya opencv.org'daki konuyla alakalı yayını okuduysanız bu işi binlerce pozitif ve negatif örnek oluşturarak yapmanız gerektiğini görürsünüz. Ancak böyle binlerce görüntüyle bu işi yapmaya kalkarsanız eğitim aşaması belki 1 günden uzun sürecektir. İşlenecek veri sayısını iyice bollaştırıp "4 gündür eğitim devam ediyor" diyeni bile gördüm ben yani o derece. Eğitimden sonra 7 numaralı modda eğittiğiniz sınıflandırıcıyı direkt çalıştırabilirsiniz ama büyük ihtimalle rengarenk karelerle dolu bir görüntü akışı olacak çünkü sınıflandırıcınız aradığınız şey hakkında o kadar az şey biliyor ki görüntüdeki birçok şeyi ona benzetiyor olacak. :) Ama neticede 7.modda bir kamera görüntüsü ve kareler pencerenizde beliriyorsa bu aşamaya kadar sorunsuz geldiniz demektir. Tebrikler.
Bu paylaşımı yaparken her şeyi açıklayarak yapmayı planlıyordum ama sonra bu düşüncemden vazgeçtim. Aklınıza takılan, merak ettiğiniz, iyi anlamadığınız, eksik gördüğünüz şeyleri, eleştirilerinizi, teşekkürlerinizi, yeni yayınlar için önerilerinizi vs. yorumlarda belirtebilirsiniz. Neyi ne kadar anlatacağımı yorumlarınız belirleyecek. Yorumlarınıza göre bu yayında düzenlemeler yaparak bu yayını zamanla hep birlikte zenginleştirelim istiyorum.
Program daha da geliştirilebilir, ham bir halde. Programın hata verip kapanabileceği açıkları (mod seçerken sayı değil harf girilmesi, pozitif.txt dosyasının silinmiş olması gibi açıklar kapatılabilir veya daha görsel bir arayüz oluşturulabilir mesela) siz kapatabilirsiniz. Ben programımda bu açıklara yönelik çalışmadım çünkü bu meseleler C++ meseleleri...
Büyük ihtimalle nesne takibi gibi bir konuda yazacağım yeni bir yayında görüşmek üzere :)
Yararlandığım Bazı Kaynaklar:
1) http://talhakoc.net/haar-cascade-egitimi/
2) http://mesutpiskin.com/blog/
3) http://docs.opencv.org/2.4/doc/user_guide/ug_traincascade.html
4) OpenCv Görüntü İşleme ve Yapay Öğrenme kitabı (Birol KUYUMCU)
Kodda HersheyFonts kısmı hata veriyor. Çözüm yolunu bilen yardımcı olabilir mi?
YanıtlaSilTeşekkürler paylaşım için. Burak Kuyumcu değil de Birol Kuyumcu diye hatırlıyorum bahsettiğiniz kitabın yazarını bir araştırın isterseniz.
YanıtlaSilKodda hata yok 2 tane uyarı veriyor sadece, çalıştırdığımda hiçbirşey olmadan kapanıyor tekrar
YanıtlaSil