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