Ask Your Question
0

How to clear frames from buffer with USB webcam?

asked 2016-08-12 06:23:15 -0600

Kashby gravatar image

updated 2016-08-12 09:30:46 -0600

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 flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2016-08-12 06:54:08 -0600

berak gravatar image

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
edit flag offensive delete link more

Comments

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

Kashby gravatar imageKashby ( 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 .

berak gravatar imageberak ( 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...

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

Question Tools

1 follower

Stats

Asked: 2016-08-12 06:23:15 -0600

Seen: 16,662 times

Last updated: Aug 12 '16