cvGetCaptureProperty von OpenCV unter Ubuntu nutzen
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).