Aşağıdaki kodlar kamera görüntüsünü pencerede gösteriyor.
Pencerenin üstüne "Kayit baslatmak/durdurmak icin bosluk tusuna basin" yazısı bulunuyor.
Klavyeden boşluk tuşuna basıldığında yazı kayboluyor ve video kaydı başlıyor.
Eğer boşluk tuşuna yeniden basılırsa kayıt kesiliyor ve yazı yine üstte beliriyor.
Bunları nasıl yapacağımızı görelim:
#include "stdafx.h"
#include "opencv2/opencv.hpp"
using namespace cv;
int main()
{
VideoCapture kamera(0);
Mat frame;
bool kayit = false;
int satir = kamera.get(CV_CAP_PROP_FRAME_HEIGHT);
int sutun = kamera.get(CV_CAP_PROP_FRAME_WIDTH);
Size videoBoyutu(sutun,satir);
VideoWriter video("C:/calisma/video.avi", CV_FOURCC_DEFAULT, 30, videoBoyutu, true);
namedWindow("Video Kayıt");
while (true) {
kamera.read(frame);
flip(frame, frame, 1);
if (waitKey(30) == 32) kayit = (kayit == true) ? false : true;
if (kayit == true) video.write(frame);
else {
String yazi = "Kayit baslatmak/durdurmak icin bosluk tusuna basin";
putText(frame, yazi, Point(10, 30), CV_FONT_NORMAL, 0.7, Scalar(255, 200, 200));
}
imshow("Video Kayıt", frame);
if (waitKey(30) == 27) break;
}
return 0;
}
Yeni gördüğünüz komutlara ve programın nasıl işlediğine değinelim.
bool kayit = false;
Bu değişkeni, boşluk tuşuna basıldığında true, bir kez daha basılırsa false şeklinde değiştireceğiz. Böylece bu değişkeni kontrol ederek true ise kayıt yapılmasını, false ise yapılmamasını sağlayacağız.
int satir = kamera.get(CV_CAP_PROP_FRAME_HEIGHT);
int sutun = kamera.get(CV_CAP_PROP_FRAME_WIDTH);
Kamera görüntüsü kaç satır ve sütundan oluşuyor? VideoCapture nesnemizin get fonksiyonu ile bu değerleri alıyoruz. Parametrenin mantığına bakarsak:
CV ~ OpenCV'nin kısaltması
_CAP ~ Capture'nin kısaltması
_PROP ~ Properties'in kısaltması
_FRAME ~ Görüntü karesi
_HEIGHT ~ Yükseklik (satır/row sayısı)
_WIDTH ~ Genişlik (sütun/col sayısı)
Size videoBoyutu(sutun,satir);
Size türünde videoBoyutu adında bir nesne oluşturuyoruz ve değerlerine de yukarıda aldığımız değerleri giriyoruz. ilk parametre width, sonraki parametre height.
VideoWriter video("C:/calisma/video.avi", CV_FOURCC_DEFAULT, 25, videoBoyutu, true);
Burada oluşturduğumuz video adlı nesnemiz, kaydedilmek üzere video ayarlarını belirliyor.
~ İlk parametrede videomuzu kaydedeceğimiz yolu belirliyoruz.
~ İkinci parametrede video formatını belirliyoruz. Buraya CV_FOURCC('M','P','4','2') yazsaydık, videomuz MPEG-4 formatında olurdu. Tüm formatları, fourcc.org/codecs.php sayfasında bulabilirsiniz. Ben bu sayfanın altında örnek birkaç format ekledim... Burayı çok doldurmayalım.
~ Üçüncü parametre FPS (Frame Per Second / Saniye başına kare) değerini belirliyor. Burada dikkat etmeniz gereken şey, her video formatı her istenen FPS sayısına sahip olamaz. Hepsinin maksimum FPS değeri vardır. Bazıları en fazla 20 FPS, bazıları 50 FPS...
~ Dördüncü parametre ile Size türündeki video boyutumuzu veriyoruz. Buradaki video boyutunu, kameramızın gösterildiği karenin boyutu kadar yaptık.
~ Beşinci parametreye true diyerek renkli bir video kaydedeceğimizi belirttik.
flip(frame,frame,1);
Bu komut, frame adlı Mat nesnemizi aynadaki tersi gibi çevirerek yine frame adlı Mat nesnemize yazıyor. İlk parametre kaynak Mat nesnesini, ikinci parametre de bu işlemden sonra oluşacak Mat nesnesini belirtiyor. Son parametre de hangi eksende yansımasını yapacağımızı belirliyor. Burayı 2 yapsaydık tepetaklak görünürdük. :)
if (waitKey(10) == 32) kayit = (kayit == true) ? false : true;
klavyeden bir tuşa basılması için 10 milisaniye bekliyoruz. Eğer basılan tuş boşluk tuşu ise (boşluk tuşunun ASCII kodu 32'dir) kayit adlı bool değişkenimizin değerini değiştiriyoruz. true ise false, false ise true yapıyoruz. Bu yazım şeklini bilmiyorsanız, yukarıdaki kod aşağıdaki kodla aynı işi yapmaktadır:
if (waitKey(10) == 32) { if( kayit == true ) { kayit = false; } else { kayit = true; } }
if (kayit) video.write(frame);
Eğer kayıt değişkeni true ise video nesnemizin write fonksiyonu ile frame'yi videomuza ekliyoruz.
Bu komut her işlediğinde ( sonsuz while döngümüz ile sürekli işliyor) kare kare video oluşmaktadır. Bu komut işlediği sürece videomuz kare kare büyüyecektir.
else {
String yazi = "Kayit baslatmak/durdurmak icin bosluk tusuna basin";
putText(frame, yazi, Point(10, 10), CV_FONT_NORMAL, 1, Scalar(255, 200, 200)); }
Bu else blokuna düştüysek, belli ki kayıt başlamamıştır. O halde kameradan aldığımız görüntüye bu durumu bildiren bir yazı yazalım ve kullanıcıya kamera görüntüsünü bu şekilde sunalım...
putText(frame, yazi, Point(10, 10), CV_FONT_NORMAL, 1, Scalar(255, 200, 200)); }
Bu komutu Merhaba Dünya yayınımda da anlatmıştım. Yine anlatalım.
~ İlk parametre ile hangi Mat nesnesine yazı yazacağımızı belirliyoruz.
~ İkinci parametre ile yazının hangi x-y koordinatlarından itibaren yazılacağını belirliyoruz.
~ Üçüncü parametre ile fontumuzu belirliyoruz. Kullanabileceğiniz fontları CV_FONT yazdığınızda VisualStudio2015'imiz size tamamlama şeklinde listeleyecektir.
~ Dördüncü parametrede double türünde yazımızın büyüklüğünü belirtiyoruz. Yani 0.7 veya 1.2 gibi değerler de verebilirsiniz.
~ Dördüncü parametre ile de yazı rengimizi belirtiyoruz. Scalar(Blue, Green, Red)
imshow("Video Kayıt", frame);
frame'mizin son (yazılı veya yazısız) halini kullanıcıya gösteriyoruz.
if (waitKey(10) == 27) break;
10 milisaniye de ESC tuşuna basılacak mı diye bekleyelim ve basılırsa while döngümüzü kıralım...
Böylece video kaydetme işini de yapabilirsiniz. Tebrikler, artık bir kameradan görüntü alıp kaydetmeyi de biliyorsunuz. :)
Gelin bu kez de bu komutlarımızı birazcık değiştirerek, boşluk tuşuna bastığımızda o anki ekran görüntüsünü kaydeden bir program yazalım.
#include "stdafx.h"
#include "opencv2/opencv.hpp"
using namespace cv;
int main() {
VideoCapture kamera(0);
Mat frame;
namedWindow("Frame Kayıt");
while (true) {
kamera.read(frame);
flip(frame, frame, 1);
if (waitKey(10) == 32) {
std::vector<int> sParam;
sParam.push_back(CV_IMWRITE_JPEG_QUALITY);
sParam.push_back(100);
bool kontrol = imwrite("C:/Users/ebykdrms/Desktop/resim.jpg", frame, sParam);
if(!kontrol) std::cout << "Resim kaydedilemedi!" << std::endl;
else std::cout << "Resim kaydedildi" << std::endl;
}
imshow("Frame Kayıt", frame);
if (waitKey(10) == 27) break;
}
return 0;
}
bool kayit = false;
Bu değişkeni, boşluk tuşuna basıldığında true, bir kez daha basılırsa false şeklinde değiştireceğiz. Böylece bu değişkeni kontrol ederek true ise kayıt yapılmasını, false ise yapılmamasını sağlayacağız.
int satir = kamera.get(CV_CAP_PROP_FRAME_HEIGHT);
int sutun = kamera.get(CV_CAP_PROP_FRAME_WIDTH);
Kamera görüntüsü kaç satır ve sütundan oluşuyor? VideoCapture nesnemizin get fonksiyonu ile bu değerleri alıyoruz. Parametrenin mantığına bakarsak:
CV ~ OpenCV'nin kısaltması
_CAP ~ Capture'nin kısaltması
_PROP ~ Properties'in kısaltması
_FRAME ~ Görüntü karesi
_HEIGHT ~ Yükseklik (satır/row sayısı)
_WIDTH ~ Genişlik (sütun/col sayısı)
Size videoBoyutu(sutun,satir);
Size türünde videoBoyutu adında bir nesne oluşturuyoruz ve değerlerine de yukarıda aldığımız değerleri giriyoruz. ilk parametre width, sonraki parametre height.
VideoWriter video("C:/calisma/video.avi", CV_FOURCC_DEFAULT, 25, videoBoyutu, true);
Burada oluşturduğumuz video adlı nesnemiz, kaydedilmek üzere video ayarlarını belirliyor.
~ İlk parametrede videomuzu kaydedeceğimiz yolu belirliyoruz.
~ İkinci parametrede video formatını belirliyoruz. Buraya CV_FOURCC('M','P','4','2') yazsaydık, videomuz MPEG-4 formatında olurdu. Tüm formatları, fourcc.org/codecs.php sayfasında bulabilirsiniz. Ben bu sayfanın altında örnek birkaç format ekledim... Burayı çok doldurmayalım.
~ Üçüncü parametre FPS (Frame Per Second / Saniye başına kare) değerini belirliyor. Burada dikkat etmeniz gereken şey, her video formatı her istenen FPS sayısına sahip olamaz. Hepsinin maksimum FPS değeri vardır. Bazıları en fazla 20 FPS, bazıları 50 FPS...
~ Dördüncü parametre ile Size türündeki video boyutumuzu veriyoruz. Buradaki video boyutunu, kameramızın gösterildiği karenin boyutu kadar yaptık.
~ Beşinci parametreye true diyerek renkli bir video kaydedeceğimizi belirttik.
flip(frame,frame,1);
Bu komut, frame adlı Mat nesnemizi aynadaki tersi gibi çevirerek yine frame adlı Mat nesnemize yazıyor. İlk parametre kaynak Mat nesnesini, ikinci parametre de bu işlemden sonra oluşacak Mat nesnesini belirtiyor. Son parametre de hangi eksende yansımasını yapacağımızı belirliyor. Burayı 2 yapsaydık tepetaklak görünürdük. :)
if (waitKey(10) == 32) kayit = (kayit == true) ? false : true;
klavyeden bir tuşa basılması için 10 milisaniye bekliyoruz. Eğer basılan tuş boşluk tuşu ise (boşluk tuşunun ASCII kodu 32'dir) kayit adlı bool değişkenimizin değerini değiştiriyoruz. true ise false, false ise true yapıyoruz. Bu yazım şeklini bilmiyorsanız, yukarıdaki kod aşağıdaki kodla aynı işi yapmaktadır:
if (waitKey(10) == 32) { if( kayit == true ) { kayit = false; } else { kayit = true; } }
if (kayit) video.write(frame);
Eğer kayıt değişkeni true ise video nesnemizin write fonksiyonu ile frame'yi videomuza ekliyoruz.
Bu komut her işlediğinde ( sonsuz while döngümüz ile sürekli işliyor) kare kare video oluşmaktadır. Bu komut işlediği sürece videomuz kare kare büyüyecektir.
else {
String yazi = "Kayit baslatmak/durdurmak icin bosluk tusuna basin";
putText(frame, yazi, Point(10, 10), CV_FONT_NORMAL, 1, Scalar(255, 200, 200)); }
Bu else blokuna düştüysek, belli ki kayıt başlamamıştır. O halde kameradan aldığımız görüntüye bu durumu bildiren bir yazı yazalım ve kullanıcıya kamera görüntüsünü bu şekilde sunalım...
putText(frame, yazi, Point(10, 10), CV_FONT_NORMAL, 1, Scalar(255, 200, 200)); }
Bu komutu Merhaba Dünya yayınımda da anlatmıştım. Yine anlatalım.
~ İlk parametre ile hangi Mat nesnesine yazı yazacağımızı belirliyoruz.
~ İkinci parametre ile yazının hangi x-y koordinatlarından itibaren yazılacağını belirliyoruz.
~ Üçüncü parametre ile fontumuzu belirliyoruz. Kullanabileceğiniz fontları CV_FONT yazdığınızda VisualStudio2015'imiz size tamamlama şeklinde listeleyecektir.
~ Dördüncü parametrede double türünde yazımızın büyüklüğünü belirtiyoruz. Yani 0.7 veya 1.2 gibi değerler de verebilirsiniz.
~ Dördüncü parametre ile de yazı rengimizi belirtiyoruz. Scalar(Blue, Green, Red)
imshow("Video Kayıt", frame);
frame'mizin son (yazılı veya yazısız) halini kullanıcıya gösteriyoruz.
if (waitKey(10) == 27) break;
10 milisaniye de ESC tuşuna basılacak mı diye bekleyelim ve basılırsa while döngümüzü kıralım...
Böylece video kaydetme işini de yapabilirsiniz. Tebrikler, artık bir kameradan görüntü alıp kaydetmeyi de biliyorsunuz. :)
Gelin bu kez de bu komutlarımızı birazcık değiştirerek, boşluk tuşuna bastığımızda o anki ekran görüntüsünü kaydeden bir program yazalım.
#include "stdafx.h"
#include "opencv2/opencv.hpp"
using namespace cv;
int main() {
VideoCapture kamera(0);
Mat frame;
namedWindow("Frame Kayıt");
while (true) {
kamera.read(frame);
flip(frame, frame, 1);
if (waitKey(10) == 32) {
std::vector<int> sParam;
sParam.push_back(CV_IMWRITE_JPEG_QUALITY);
sParam.push_back(100);
bool kontrol = imwrite("C:/Users/ebykdrms/Desktop/resim.jpg", frame, sParam);
if(!kontrol) std::cout << "Resim kaydedilemedi!" << std::endl;
else std::cout << "Resim kaydedildi" << std::endl;
}
imshow("Frame Kayıt", frame);
if (waitKey(10) == 27) break;
}
return 0;
}
Buradaki yeni komutlara bakalım.
if (waitKey(10) == 32) { ... }
Klavyeden boşluk tuşuna basılacak mı bakalım diye 10 milisaniye bekleyen bir if bloku... Tuşa basıldığında, o anki ekran görüntüsünü bakalım bu blok içinde nasıl kaydediyoruz...
std::vector<int> sParam;
std namespacesinin vector<int> türünde ve sParam adında bir nesne oluşturuyoruz. Görüntüyü kaydetmek için gerekli parametreleri bu nesnemizle belirleyeceğiz.
Bu std:: kısmını yazmamak için ne yapacağınızı Merhaba Dünya yayınımızdan da biliyorsunuz.
using namespace cv; satırının hemen altına using namespace std; yazarak bu namespace'yi her seferinde std:: ifadesiyle çağırmaktan kurtulabileceğinizi biliyorsunuz. (Eğer zaten C++ biliyorsanız böyle anlatmam sizi gıcık ediyordur belki ama ben C++'ı da az biraz bilenler için böyle açıklamalar yapıyorum. Zira ben de C++'ı çok iyi bildiğimi söyleyemem. :) )
sParam.push_back(CV_IMWRITE_JPEG_QUALITY);
Resmimizi JPEG formatında sıkıştıracağız.
sParam.push_back(100);
0-100 aralığında, görüntünün hangi kaliteyle kaydedileceğini belirliyoruz. Biz görüntümüzü tam kaliteyle, olduğu gibi kaydedelim.
bool kontrol = imwrite("C:/calisma/resim.jpg", frame, sParam);
imwrite() fonksiyonu, OpenCV'nin resim kaydetmeye yarayan fonksiyonudur (image write). İlk parametreye resmin yolunu, ikinci parametreye hangi Mat nesnesini kaydedeceğimizi, üçüncü parametrede ise sıkıştırma parametresini belirtiyoruz.
Bu fonksiyon eğer kaydetme işlemi başarıyla gerçekleştiyse true döndürür. Bunu da kontrol değişkenimizle yakalayalım.
if(!kontrol) std::cout << "Resim kaydedilemedi!" << std::endl;
Eğer kontrol==false ise, "Resim kaydedilemedi! şeklinde bir yazı yaz. Bunlar da C++ komutlarıdır. Yani cout << "yazı"; diyerek ekrana bir yazı yazarız. Bunun peşine << endl; eklersek bir alt satıra geçilmesini sağlarız.
Artık resim de kaydedebiliyorsunuz. Siz bu iki ayrı programı tek programda da birleştirebilirsiniz tabii ki... Yani Space'ye basılınca video kaydı yapan ve Enter'e basınca da foto çeken program falan... Ne bileyim ok tuşlarına basınca flip() fonksiyonu ile görüntünün farklı ayna yansımalarının gösterilmesi mesela... Başka tuşlarla, ileride öğreneceğimiz resmi bulanıklaştırma, kenarları belirleme, renklerle oynama falan gibi işlemleri yaptırabilirsiniz.
Umuyorum ki ileride sizinle birlikte resimde yüz bulmak, nesne tanımak falan gibi projeler de geliştireceğiz. Sonra bunları bir de C# ile yapmaya çalışacağız. Sonra belki ses tanıma gibi farklı şeyler de yaparak ve bunları tek bir projede birleştirerek kendimize bir Samaritan (Person of Interest) yaparız ve sonra makinelerin dünyayı ele geçirip Terminatörleri üretmeleri ve bizi Matrix'e bağlamaları gibi olayları başlatırız. :D
Video formatları:
Video formatları:
- CV_FOURCC('D', 'I', 'V', '3') ~ DivX MPEG-4 codec
- CV_FOURCC('M', 'P', '4', '2') ~ MPEG-4 codec
- CV_FOURCC('D', 'I', 'V', 'X') ~ DivX codec
- CV_FOURCC('P','I','M','1') ~ MPEG-1 codec
- CV_FOURCC('I', '2', '6', '3') ~ ITU H.263 codec
- CV_FOURCC('M', 'P', 'E', 'G') ~ MPEG-1 codec
Örnek kullanım: VideoWriter video("D:/videom.avi", CV_FOURCC('P','I','M','1'), 20, boyut, true);
Sıradaki yayında görüşmek üzere...
Hiç yorum yok:
Yorum Gönder