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).

OpenCV in Netbeans und Ubuntu

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:

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(&amp;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)

Eine Sinatra App mit Thin starten

thin -d -R config.ru -C config.yml start

MySQL Trigger über zwei Datenbanken

USE db_1;
DELIMITER |

CREATE TRIGGER test
BEFORE INSERT ON table_1
FOR EACH ROW
INSERT INTO db_2.table_2 SET table_2.field_2 = NEW.field_1;
|

Aus einem Processing Sketch ein Video machen

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.