Ask Your Question
-1

Is OpenCV frames passed by referenced?

asked 2018-10-24 04:24:55 -0600

akmalhakimi1919 gravatar image

I want to display my camera output in 2 different windows. I want to do some drawing in one of them and display the original image in the other. So what I did is I create a thread that fetches the camera stream and assigned it to a global variable. Then, 2 separate thread retrieved these frames and assigned it to a local variable. However, upon displaying, both are showing the drawings.

import cv2
import time
from threading import Thread

camip = 0
camera_frame = None

def read():
    cam = cv2.VideoCapture(camip)
    while True:
        ret,frame = cam.read()
        global camera_frame
        camera_frame = frame

def display(x):
    print "Starting camera "+str(x)
    while True:
        temp_frame = camera_frame
        cv2.rectangle(temp_frame,(130,130),(430,430),(0,255,0),2)
        cv2.imshow("Camera "+str(x),temp_frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

def display2(x):
    print "Starting camera "+str(x)
    while True:
        temp_frame = camera_frame
        cv2.imshow("Camera "+str(x),temp_frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

t0 = Thread(target=read)
t0.start()
time.sleep(1)

t1 = Thread(target=display, args=(1,))
t1.start()
time.sleep(1)

t2 = Thread(target=display2, args=(2,))
t2.start()
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2018-10-24 05:08:15 -0600

berak gravatar image

please AVOID multithreading with opencv code, esp. with the gui parts

(those HAVE TO stay on the main thread !).

global vars are EVIL, too.

again you should use a single loop only:

import cv2
import time

camip = 0

def main():
    cam = cv2.VideoCapture(0) # if you *wanted* to open2 webcams, you need 2 of those !
    if not cam.isOpened():
        return # only fools do not check !
    while True:
        ret,frame = cam.read()
        if not ret:
             return # again, only fools ...

        temp_frame = frame.copy() # else it's *really* a reference only !
        cv2.rectangle(temp_frame,(130,130),(430,430),(0,255,0),2)
        cv2.imshow("Camera 0",frame)
        cv2.imshow("Camera 1",temp_frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
main()
edit flag offensive delete link more

Comments

Care to elaborate why multithreading is bad? The reason why I put the read() in a separate thread and run it continuously is that previously I had an issue (in a separate program) where if I didn't do the cam.read() continuously (e.g. if there's a time.sleep(x) after the first cam.read()), the next cam.read() will return the frame from a few seconds ago.

akmalhakimi1919 gravatar imageakmalhakimi1919 ( 2018-10-24 06:22:19 -0600 )edit

you don't need it. also a lot of opencv's functions are not threadsafe by design.

and you should not use sleep(), else the internal queue in the capture does not get flushed, and you're indeed late.

if you ever need to share something between threads, you also have to use locks, not global variables.

berak gravatar imageberak ( 2018-10-24 06:45:07 -0600 )edit
1

I think this example is not bad

LBerger gravatar imageLBerger ( 2018-10-24 08:44:54 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2018-10-24 04:24:55 -0600

Seen: 758 times

Last updated: Oct 24 '18