Kamerabild verzögert abspielen in Processing

Hinzugefügt am von Jonas Loh
Das simpelsten Beispiel stellt das aktuelle Kamerabild in 'nahezu' Echtzeit dar. Ein Ablegen des Bildes bzw. Modifizieren der Farbwerte einzelner Pixel findet nicht statt. Im nächsten Schritt wird das verzögerte Abspielen des Videoinputs vorgestellt.

Den Kern stellt ein PImage Array namens buffer. Zu Beginn wird im setup() dessen Größe berechnet, um später die gewünschte Anzahl an Einzelbildern zu speichern. Je nach Länge der Verzögerung wird demnach beim Start kein Videobild im Sketch angezeigt. Die Abspiel- und Speicherposition, in welchem Feld das aktuelle Bild abgelegt/abgerufen werden soll, definiert die Variable index. Dabei wird das Array nicht von Anfang bis ins Endlose mit Bilder versorgt, sondern beim Erreichen des letzten Feldes auf das erste verwiesen. Die Variable index verursacht demnach einen Loop durch den Bildspeicher buffer. Bilder die älter als die Angegebene lagSeconds sind wurden abgespielt und werden überschrieben.

Der Sketch

import processing.video.*;

// Schnittstelle zur Kamera
Capture cam;

// Speicher für die Einzelbilder aus 
// der 'Vergangenheit'
PImage[] buffer;

// Anzahl der Einzelbilder pro 
// Sekunde für Sketch und Aufnahme 
int fps = 20;

// Zeitverzögerung in Sekunden
int lagSeconds = 2;

// Abspielposition und damit Schlüssel
// für das Einfügen/Auslesen aus dem Buffer
int index = 0;

// Status ob der Bildspeicher schon 
// einmalig komplett gefüllt wurde
boolean filled = false;

void setup () {
  size (320, 240);
  frameRate (fps);
  cam    = new Capture (this, width, height, 20);
  buffer = new PImage[lagSeconds * fps];
}

void draw () {
  // Wenn der Bildspeicher einmal 
  // komplett gefüllt wurde...
  if (filled == true) {
    // Stelle das Bild im Sketch dar
    image (buffer[index], 0, 0);
  }
}

void captureEvent (Capture theCam) {
  // Lies das aktuelle Kamerabild aus
  theCam.read ();
  // Speicher eine Kopie im Buffer an 
  // der Position des Bildes welches 
  // gerade ausgelesen wurde
  buffer[index] = theCam.get ();
  // Erhöhe die Position für das Auslesen
  // um eins, auf das älteste Bild im Buffer
  index++;
  
  // Wenn am Ende des Buffers angekommen,
  // springe wieder an den Anfang.
  if (index >= buffer.length) {
    index = 0;
    if (!filled) {
      filled = true;
    }
  }
}