Bonjour tout le monde,
Pour un projet, je cherche à reproduire un effet de "photographie scanner" sur une vidéo afin de synthétiser le temps passé en une image en gros. je me souviens d'un exemple sur processing qui est celui-ci :
/**
* Spatiotemporal
* by David Muth
*
* Records a number of video frames into memory, then plays back the video
* buffer by turning the time axis into the x-axis and vice versa
*/
import processing.video.*;
Capture video;
int signal = 0;
//the buffer for storing video frames
ArrayList frames;
//different program modes for recording and playback
int mode = 0;
int MODE_NEWBUFFER = 0;
int MODE_RECORDING = 1;
int MODE_PLAYBACK = 2;
int currentX = 0;
void setup() {
size(640, 480);
// This the default video input, see the GettingStartedCapture
// example if it creates an error
video = new Capture(this, width, height);
// Start capturing the images from the camera
video.start();
}
void captureEvent(Capture c) {
c.read();
//create a new buffer in case one is needed
if (mode == MODE_NEWBUFFER) {
frames = new ArrayList();
mode = MODE_RECORDING;
}
//record into the buffer until there are enough frames
if (mode == MODE_RECORDING) {
//copy the current video frame into an image, so it can be stored in the buffer
PImage img = createImage(width, height, RGB);
video.loadPixels();
arrayCopy(video.pixels, img.pixels);
frames.add(img);
//in case enough frames have been recorded, switch to playback mode
if (frames.size() >= width) {
mode = MODE_PLAYBACK;
}
}
}
void draw() {
loadPixels();
//code for the recording mode
if (mode == MODE_RECORDING) {
//set the image counter to 0
int currentImage = 0;
//begin a loop for displaying pixel columns
for (int x = 0; x < video.width; x++) {
//go through the frame buffer and pick an image using the image counter
if (currentImage < frames.size()) {
PImage img = (PImage)frames.get(currentImage);
//display a pixel column of the current image
if (img != null) {
img.loadPixels();
for (int y = 0; y < video.height; y++) {
pixels[x + y * width] = img.pixels[x + y * video.width];
}
}
//increase the image counter
currentImage++;
}
else {
break;
}
}
}
//code for displaying the spatiotemporal transformation
if (mode == MODE_PLAYBACK) {
//begin a loop for displaying pixel columns
for (int x = 0; x < video.width; x++) {
//get an image from the buffer using loopcounter x as the index
PImage img = (PImage)frames.get(x);
if (img != null) {
img.loadPixels();
//pick the same column from each image for display,
//then distribute the columns over the x-axis on the screen
for(int y = 0; y < video.height; y++) {
pixels[x + y * width] = img.pixels[currentX + y * video.width];
}
}
}
//a different column shall be used next time draw() is being called
currentX++;
//if the end of the buffer is reached
if(currentX >= video.width) {
//create a new buffer when the next video frame arrives
mode = MODE_NEWBUFFER;
//reset the column counter
currentX = 0;
}
}
updatePixels();
}J'aimerais savoir si vous saviez comment retranscrire ce programme sur une vidéo plutôt qu'une webcam en permettant d'en gérer le temps, ou si vous connaissiez un autre moyen de réaliser ce procédé.
Merci d'avance pour les réponses !
Hors ligne
Bonsoir,
Il suffit de remplacer la variable video en utilisant la classe Movie au lieu de Capture. Voilà ce que cela donne :
/**
* Spatiotemporal
* by David Muth
*
* Records a number of video frames into memory, then plays back the video
* buffer by turning the time axis into the x-axis and vice versa
*/
import processing.video.*;
Movie video;
int signal = 0;
//the buffer for storing video frames
ArrayList frames;
//different program modes for recording and playback
int mode = 0;
int MODE_NEWBUFFER = 0;
int MODE_RECORDING = 1;
int MODE_PLAYBACK = 2;
int currentX = 0;
void setup() {
size(640, 360);
// This the default video input, see the GettingStartedCapture
// example if it creates an error
video = new Movie(this, "transit.mov");
// Start capturing the images from the camera
video.loop();
}
void movieEvent(Movie c) {
c.read();
//create a new buffer in case one is needed
if (mode == MODE_NEWBUFFER) {
frames = new ArrayList();
mode = MODE_RECORDING;
}
//record into the buffer until there are enough frames
if (mode == MODE_RECORDING) {
//copy the current video frame into an image, so it can be stored in the buffer
PImage img = createImage(width, height, RGB);
video.loadPixels();
arrayCopy(video.pixels, img.pixels);
frames.add(img);
//in case enough frames have been recorded, switch to playback mode
if (frames.size() >= width) {
mode = MODE_PLAYBACK;
}
}
}
void draw() {
loadPixels();
//code for the recording mode
if (mode == MODE_RECORDING) {
//set the image counter to 0
int currentImage = 0;
//begin a loop for displaying pixel columns
for (int x = 0; x < video.width; x++) {
//go through the frame buffer and pick an image using the image counter
if (currentImage < frames.size()) {
PImage img = (PImage)frames.get(currentImage);
//display a pixel column of the current image
if (img != null) {
img.loadPixels();
for (int y = 0; y < video.height; y++) {
pixels[x + y * width] = img.pixels[x + y * video.width];
}
}
//increase the image counter
currentImage++;
}
else {
break;
}
}
}
//code for displaying the spatiotemporal transformation
if (mode == MODE_PLAYBACK) {
//begin a loop for displaying pixel columns
for (int x = 0; x < video.width; x++) {
//get an image from the buffer using loopcounter x as the index
PImage img = (PImage)frames.get(x);
if (img != null) {
img.loadPixels();
//pick the same column from each image for display,
//then distribute the columns over the x-axis on the screen
for(int y = 0; y < video.height; y++) {
pixels[x + y * width] = img.pixels[currentX + y * video.width];
}
}
}
//a different column shall be used next time draw() is being called
currentX++;
//if the end of the buffer is reached
if(currentX >= video.width) {
//create a new buffer when the next video frame arrives
mode = MODE_NEWBUFFER;
//reset the column counter
currentX = 0;
}
}
updatePixels();
}Hors ligne
Merci !
J'ai fais un test en réécrivant le code car ça ne marchait toujours pas, mais j'ai à nouveau un souci, j'utilise la vidéo des exemples de processing pour être sur :
import processing.video.*;
Movie myMovie;
int x = 0;
void setup() {
size(1280, 480);
myMovie = new Movie(this, "transit.mov");
myMovie.play();
myMovie.loop();
}
void movieEvent(Capture m) {
m.read();
}
void draw() {
//image(myMovie, 0, 0, width, height);
int w = width;
int h = height;
print(w, h, x);
copy(myMovie, w/2, 0, 1, h, x, 0, 1, h);
x = x + 1;
if (x > width) {
saveFrame("slit-scan-######.png");
x = 0;
}
}Voilà le nouveau code, en revanche rien ne s'affiche, et parfois j'ai un code d'erreur selon ce que je modifie :
width (0) and height (0) cannot be <= 0
Voilà , je sais pas trop si je touche au but.
Hors ligne
Bon déjà j'avais une belle erreur :
void movieEvent(Capture m) {
m.read();
}Que j'ai remplacé par :
void movieEvent(Movie m) {
m.read();
}Maintenant ça se lance bien, mon print "w, h, x" fonctionne mais ma vidéo ne se lance pas du tout, j'ai un rendu vierge encore.
Hors ligne
Pages: 1