There was a time, when I shared a blog. This post was written by Stephan.
See all blogpost from him or stalk him on github.
Nachdem ich bei der Einarbeitung in OpenCV einige Probleme hatte, mit Hilfe der Funktion cvGetCaptureProperty() die Eigenschaften des geöffneten Videos korrekt auszulesen, bin ich bei der Forensuche auf eine Lösung gekommen, die es zumindest ermöglicht, die Anzahl der Bilder des Videos korrekt auszulesen. Dazu müsst ihr in eurem Quellcode folgende Funktion hinzufügen:
#include "iostream";
#include "fstream";
#include "highgui.h"
#include "cv.h"
using namespace std;
int getAVIFrames(char * fname) {
char tempSize[4];
// Trying to open the video file
ifstream videoFile(fname, ios::in | ios::binary);
// Checking the availablity of the file
if (!videoFile) {
cout << "Couldn't open the input file " << fname << endl;
exit(1);
};
// get the number of frames
videoFile.seekg(0x30, ios::beg);
videoFile.read(tempSize, 4);
int frames = (unsigned char) tempSize[0] + 0x100 * (unsigned char) tempSize[1] + 0x10000 * (unsigned char) tempSize[2] + 0x1000000 * (unsigned char) tempSize[3];
videoFile.close();
return frames;
}
Nun könnt ihr durch Aufruf dieser Funtkion zumindest die Anzahl der Frames erhalten. Ein Aufruf in eurem Programmcode könnte zum Beispiel so aussehen:
int video_frames = getAVIFrames(argv[1]);
Beim Start des Programmes müsst ihr natürlich den Namen des Videos mit übergeben.
Alle anderen Ausleseversuche der folgenden Eigenschaften lieferten bei mir immer wieder nur 0:
printf("CV_CAP_PROP_POS_MSEC: %f\n",
cvGetCaptureProperty(capture, CV_CAP_PROP_POS_MSEC));
printf("CV_CAP_PROP_POS_FRAMES: % f\n",
cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES));
printf("CV_CAP_PROP_FRAME_WIDTH: %f\n",
cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH));
printf("CV_CAP_PROP_FRAME_HEIGHT: %f\n",
cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT));
printf("CV_CAP_PROP_FPS: %f\n",
cvGetCaptureProperty(capture, CV_CAP_PROP_FPS));
printf("CV_CAP_PROP_POS_AVI_RATIO: %f\n",
cvGetCaptureProperty(capture, CV_CAP_PROP_POS_AVI_RATIO));
printf("CV_CAP_PROP_FRAME_COUNT: %f\n",
cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT));
Das als mögliche Fehlerquelle der verwendete Codec in Frage kommen könnte, kann ich nicht bestätigen.
Ich habe mittels ffmpeg verschiedene Varianten des selben Videos angefertigt, jedoch ergab sich keine Besserung.
Das muss wohl ein Linuxproblem der neueren Versionen von OpenCV sein (und laut den Forenbeiträgen besteht es auch schon länger, weiteres hier, inklusive der hier geposteten Lösung aus dem O'Reilly Buch Learning OpenCV).
There was a time, when I shared a blog. This post was written by Stephan.
See all blogpost from him or stalk him on github.
Um die Open Source Computer Vision Library unter Netbeans 6.8 zu nutzen musst du folgendes einstellen:
- Starte Netbeans und erzeuge ein neues C/C++ Projekt
- Gehe im Menü auf Extras >> Optionen
- Ein neues Fenster erscheint, in dem du nun den Reiter C/C++wählst
- Im Unterpunkt Code Assistance fügst du in der Include Directories Liste den Pfad zur OpenCV-Bibliothek ein. Dies kannst du wahlweise für den C bzw. C++ Compiler tun. Der Standardpfad für OpenCV ist unter Ubuntu /usr/include/opencv
- Nun klicke mit der rechten Maustaste auf dein aktuelles Projekt und gehe auf den Punkt Eigenschaften
- Ein neues Fenster erscheint. In der Kategorie Build >> C bzw. C++ gibst du folgendes in das Feld Additional Options ein:
pkg-config --cflags opencv
- Als letztes musst du nur noch in der Kategorie Build >> Linker folgendes bei Additional Options angeben:
pkg-config --libs opencv
Führst du nun folgenden Code aus und kompilierst ihn, sollte dein erstes OpenCV-Programm erfolgreich gestartet werden:
/*
* File: main.cpp
* Author: stephan
*
* Created on 11. Mai 2010, 22:33
*/
#include "highgui.h"
#include "cv.h"
int main(int argc, char** argv) {
IplImage* img = cvLoadImage("image.jpg"); // oder als Argument cvLoadImage(argv[1]);
cvNamedWindow("Example1", CV_WINDOW_AUTOSIZE);
cvShowImage("Example1", img);
cvWaitKey(0);
cvReleaseImage(&img);
cvDestroyWindow("Example1");
};
In diesem Beispiel wird das Bild image.jpg in fest in den Quellcode eingebunden. Möchtest du Argumente bei Programmstart übergeben und per argv[] der Main-methode darauf zugreifen, kannst du dies über den Eigenschaftsdialog des Projektes in der Kategorie Run tun.
Der Parameter dafür heißt Arguments.
Im Quellcode enthält dann argv[1] den Wert image.jpg (siehe Bild 4)
Manchmal möchte man seine Processing Animation als Video weiterverwenden, um es beispielsweise bei Vimeo oder Youtube hochladen zu können.
Dazu sollte man sein Processing programm folgendermaßen aufbauen:
boolean capture = false;
long frameCounter = 0;
void setup() {
size(1280, 720, P2D);
frameRate(30);
}
void draw() {
//draw your stuff here
if(capture) {
saveFrame("screen-" + nf(frameCounter,6) + ".tif");
frameCounter++;
}
}
void keyPressed() {
if(key == ' '){
if(capture) {
capture = false;
} else {
capture = true;
}
}
}
Jetzt kann man seinen Processsing Sketch starten. Mit der Leertaste kann man nun seine Aufnahme beginnen. Vorsicht: Das kann ziemlich hohe Last für die Festplatte bedeuten. Falls die nicht hinterherkommt, einfach die FrameRate auf einen kleineren Wert setzen.
Ist man mit dem Capturen fertig, wechselt man in den Ordner des Sketches und kann mit
ffmpeg -f image2 -i screen-%06d.tif -b 5000000 -r 25 -s hd720 -vcodec mpeg4 -f mp4 -an -threads 2 shuffle.mp4
ein Video erzeugen. Die ffmpeg Einstellungen sind hier auf Vimeo abgestimmt und müssen ggf. an deine Auflösung/Codec/Bitrate/Computer angepasst werden.