We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hello everyone,
I am trying to create a sketch that simulates a long exposure shot captured on camera. I searched for smth similar on the web and found this reference which proposes to append different layers using different opacities. I did that with the following code, but it doesn't seem to quite do the job properly.
Anybody tried to do that before?
Any other suggestions?
Thanks for your time! :-)
// This patch proposes to simulate a long exposure shot using Processing.
import processing.video.*;
Capture video;
void setup() {
size(640, 480);
printArray(Capture.list());
video = new Capture(this, 640, 480, 30);
video.start();
}
void mousePressed()
{
int steps = 10; // also means amount of pictures taken and merged later
long opac = 255 / steps;
for (int i = 1; i <= steps; i++)
{
if (video.available())
{
video.read();
image(video, 0, 0);
tint(255, opac * i); // changes the opacity every step
delay (100); // delay between each step
print(i);
println(" " + opac * i);
}
}
}
void keyPressed()
{
background(0);
}
void draw() {
// Step 5. Display the video image.
}
Answers
Just figured that I had increasing opacity values as the step counter went up. Inverting the opacity value from ascending to descending produced my desired effect. changed
to
It is still not polished. Doesn't seem to merge images properly. Maybe because the opacity declines in a linear way? Is there a way to change blending mode on Processing? anyone? thanks !
re:
blendMode()
https://processing.org/reference/blendMode_.htmlYou probably don't need to freeze the sketch between frames in the mousePressed function and use
delay()
-- instead, you could just use draw andframeRate()
Changing the opacity over time doesn't actually model how a long exposure photgraph works. Instead, set a fixed opacity and blendMode, and simple draw to the canvas without clearing. This will "expose" the canvas over time.
Due to how float-based averaging works, some blend modes will never reach a perfectly black or perfectly bright frame, no matter how long they are shown a still exposure -- they will max out at ~10-240 instead of 0-255.
Hey Jeremy, thanks for your reply! I noticed in other posts that's possible to use framerate instead of using delay. I'm actually using it to be sure how long the capture will be. I'd like it to take around 3.2 seconds to do it all.
I'm also trying to store each frame in an Array, but with no luck. I managed to record each frame in jpegs but i can't access the images on the array. I guess I'm missing something...
Also I have to use a kinect as a webcam for what i'm developing, so I changed my original code a little bit.
Also couldn't get the real difference between ArrayList and Array[]... :-(
thanks again for your help !
Can you be more specific than saying you didn't have luck, or you couldn't access the images? What happened when you tried?
Edit: I see now in your comments that the frames all show the latest. (Please include this information outside your code so it's easy to read.)
My guess is you need to copy the current frame into a new image, and then store that image in your ArrayList.
And the difference between an array and an ArrayList is an ArrayList allows you to add elements to it, and it will automatically resize itself. Arrays are fixed-size.
Two relevant posts:
For forum goers: https://forum.processing.org/two/discussion/14661/storing-retrieving-video-camera-frames-in-an-arraylist#latest
For OP: https://forum.processing.org/two/discussion/20967/rgb-delayed#latest
Kf
Re:
That is what
frameRate()
does -- and the sketch keeps running and accepts input if you don't use delay().If you set it to 10 in
setup()
, thats one frame every 100ms.Then in your header create a global shutter flag and duration value:
...and in
keyPressed()
open the shutter and set a timer:...and in
draw()
do something each moment the shutter is open -- draw is your loop:...and don't forget in draw() to close the shutter once it gets to a draw frame when you are done.
With this approach, you could set the exposure duration for 30 seconds -- or 10 minutes -- and you could still still interact with the sketch, see a preview of the results forming on the screen, or hit cancel -- and the sketch would respond. With the delay approach, you just locked the sketch up for 10 minutes, and forcing it to quit entirely is your only escape.
Hey Jeremy, and kfrajer, thanks for your reply! I got what you mean by not having the sketch stuck inside the delay() loop. Thanks!
Now I am considering the reference kfrajer posted earlier. I noticed they talk about a "circular loop" which involves the creation of an array with a know amount of elements. This way the sketch would be always storing the last X frames inside of it and showing it on screen.
So I guess the scope of the project would be: 1. to keep a live image onscreen and waiting the hit of a button to start the "capture". 2. When a button is pressed, the image should be seen evolving on the screen showing the image trails as it records (during the shutterOpen time). 3. After finishing the capture time, the image should be kept on screen and recorded on a jpg file. 4. wait 5 seconds and go back to step 1.
That's pretty much that.
I guess I'm having some real beginner issues here, I'm currently trying to store images recorded from camera to the circular loop array. I'm trying to flick thru the array using mouseX coordinates. Any clues about what i'm doing wrong?
Thanks you so much for your attention again! :-)
This is a concept of a photobooth. The question is how do display multiple images together in a single screen. In the links to the RGB delay post, I believe different tint values is applied to each image, working with the RGB channels - One image is based only on red, second image only on blue and third image on green - then they are plot together. In your case, I will try either applying a fix tint to each image before is drawn or you could re-define each image's alpha channel to certain fix value.
Related to your post, the reason you are getting a NPE is very simple: You are trying to draw a image object that is null. You can fix this by using something simple like:
if(framesB[frame_mouse]!=null){..}
Related to showing certain frame on your circular buffer, as it is, the image being displayed depends on the mouse position and current value of the pointer variable which changes after a new frame is acquired. I don't think this is doing what you want it to do. Here below I show my version for you to explore.
Kf
Hey kfrajer!
Thanks for your response! The selection of each state using the keyboard works great!
I have implemented the "SHOW LE EFFECT" function as shown in the code below. There's an issue on the code, which could be done to make it more "elegant". I tried to implement the command using the loop
the same way you do here:
... but it didn't produced the same image as when done all commands one by one (quite weird, but that's what i've noticed).
Besides, I noticed that it still seems that the resulting image shows mostly the last images captured. It seems that the first images don't have the same weigh as the last ones even though all of them receive the same "tint(255, opac);" command.
Any ideas?
Thank you sooo much for your help!!
F.
This is my attempt.
Kf
Hello Kf! Thanks for your attempt! Image quality is a key feature on what I'm trying to do... I noticed what you mean by image degradation. I'll try to keep using the same technique I used before. Maintaining 10 shots is still working fine.
I'm focusing on changing screens right now, moving from one stage to the other. Will keep you posted as I move on.
Thank you so much for your help! ^:)^
F.