# How to clear frames from buffer with USB webcam?

Hi everyone, I'm new to Python and OpenCV, using versions 3.4 and 3.0 respectively. I'm trying to use two USB webcams to grab 2 sets of frames each and then retrieve the frames. In this code the first two frames are taken with LEDs off, then the second two frames are taken with LEDs on. It is in a loop which runs 'nframes' number of times to produce 'nframes' final images 'framer' and 'framel'. 'nframes' is specified earlier in my code which I haven't included.

However when I use grab it seems to use a frame from before I call the command, so I think it has some buffer saved in its memory. I was getting around this by calling grab twice for each frame, however I'm sure there must be a more efficient way of clearing the memory. I've looked in the documentation and can't find anything about clearing the camera memory.

Here is my relevant code:

# Define camera names

    cap1 = cv2.VideoCapture(0) # define right side as cap1
cap2 = cv2.VideoCapture(1) # define left side as cap2


# Background frame

           # turn LEDS off
print('Get in position!')
print('Capture in progress...')
myoutput.WriteAnalogScalarF64(True,timeout,0,None) # LEDs off
time.sleep(1)
#ret, framer1 = cap1.grab() # to throw
#ret, framel1 = cap2.grab()
retr1 = cap1.grab() # take background frame
retl1 = cap2.grab()
time.sleep(.5)


# Waveguide frame

        # turn LEDS on
myoutput.WriteAnalogScalarF64(True,timeout,5,None)
time.sleep(.5)
#ret, framer2 = cap1.grab() # to throw
#ret, framel2 = cap2.grab()
retr2 = cap1.grab()         # take a waveguide frame
retl2 = cap2.grab()

if retr1 == True and retl1 ==  True:
pass
else:
print('Background frame error')
if retr2 == True and retl2 ==  True:
pass
else:
print('LED-on frame error')


# Remove background light & write to file

        # Right
retr1, framer1 = cap1.retrieve(retr1)
retl1, framel1 = cap2.retrieve(retl1)
retr2, framer2 = cap1.retrieve(retr2)
retl2, framel2 = cap2.retrieve(retl2)
framer = cv2.subtract(framer2,framer1)
# Left
framel = cv2.subtract(framel2,framel1)

edit retag close merge delete

Sort by » oldest newest most voted

unfortunately, the av-based linux capture code is using an internal fifo (5 frames, iirc), and you cannot clean (or say, flush) it.

so, change your logic. instead of sleeping for a long time (which will only queue up more buffers), you should read as fast as you can continuously, but only use frames, when you need them.

(pseudo code, sorry)

triggerTime=0
while True:
retr = cap1.grab()
retl = cap2.grab()
retr1, framer1 = cap1.retrieve(retr)
retl1, framel1 = cap2.retrieve(retl)
if triggerTime >= 2.0: #some  value
#
#  process both frames NOW !
#
triggerTime = 0 # reset
triggerTime += something

more

Thanks for your reply. My only issue is that how can I include my calls to switch on and off the LEDs? I feel like I would need to run two scripts simultaneously for that to be achieved if I used a loop like this. Thanks

( 2016-08-12 08:03:46 -0600 )edit

ah, i assumed, you code would be running in a loop initially.

how would i know about your led requirements ? maybe you'll have to explain a bit more .

( 2016-08-12 08:35:48 -0600 )edit
1

As I have indicated in the code, the first two frames are taken with LEDs off, then the second two frames are taken with LEDs on. It is in a loop which runs 'nframes' number of times to produce 'nframes' final images 'framer' and 'framel'. 'nframes' is specified earlier in my code which I haven't included. I think I have implemented your suggestion successfully using two loops and putting the commands to use the LEDs within this loop but PyDAQmx ( which is how I'm switching on and off the LEDs) doesn't seem to be behaving right, so it's hard to see if it is working or not...

( 2016-08-12 09:29:11 -0600 )edit

Official site

GitHub

Wiki

Documentation