1

The goal of my project is to take images every .2 sec, and when a certain condition is met, (in this case depressing a button connected to a GPIO input,) display the image taken 1 second before. The way I control the amount of time that elapses between each picture taken is:

start = time.time()
# picture taken
elapsed = time.time() - start
if elapsed < t:
    time.sleep(t - elapsed)

90% of the time this works like a charm, since the "picture taken" code usually only takes around .1 second to execute, however, every once in a while, the picture taking process will take longer - usually about a half second but sometimes up to 2 seconds. I am using a RPI 3 model B and a v2 camera module. Does anyone know how to eliminate this inconsistency?

Would a better way to do this be to somehow have a video running and pull individual frames from there? And if so, how would I do that? Regarding the video idea - it is important to note that this device needs to be able to run for hours or potentially days so having all of the video in one recording is not feasible.

Below is my program in its entirety. I am very new to Python and RPIs so please include example code along with any suggestions.

# import packages
import picamera
import time
import collections
import RPi.GPIO as GPIO
import rotate_and_overlay_script_low_res

# set frame rate and frames in buffer:
fps = 5
frames_in_buffer = 5

# setup input button
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(10, GPIO.IN)

# setup camera and let it adjust
camera = picamera.PiCamera()
camera.resolution = (864, 648)
time.sleep(2)

# setup other variables
fifo = collections.deque([], frames_in_buffer)
n = 0
t = 1.0 / float(fps)

# take pictures indefinitely, adding them to fifo buffer
while True:
        start = time.time()
        camera.capture("image_{:d}.jpg".format(n), use_video_port = True)
        print(time.time() - start)
        fifo.appendleft("image_{:d}.jpg".format(n))
        # make sure each image in the buffer has a unique name
        if n == (frames_in_buffer - 1):
                n = 0
        else:
                n += 1
        print(fifo)
        elapsed = time.time() - start
        if elapsed < t:
                time.sleep(t - elapsed)
        print(time.time() - start)
        # display image
        if GPIO.input(10) == False:
                rotate_and_overlay_script_low_res.overlay(fifo.pop())
  • So, you're constantly taking pictures, and are then trying to display whatever the picture from t - 1 second was? – Jacobm001 Aug 5 '16 at 21:27
1

If there's no additional processing to do on the image, I'd just use raspistill's timelapse option instead of Python:

--timelapse, -tl time-lapse mode.

The specific value is the time between shots in milliseconds. Note you should specify %04d at the point in the filename where you want a frame count number to appear. e.g:

-t 30000 -tl 2000 -o image%04d.jpg

will produce a capture every 2 seconds, over a total period of 30s, named image0001.jpg, image0002.jpg..image0015.jpg. Note that the %04d indicates a 4 digit number with leading zero's added to pad to the required number of digits. So, for example, %08d would result in an 8 digit number.

If a time-lapse value of 0 is entered, the application will take pictures as fast as possible. Note there is an minimum enforced pause of 30ms between captures to ensure that exposure calculations can be made.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.