0

thanks for checking out my question. I'm using OpenCV in Python36 32bit and trying to accomplish video mixing using the threading module. I have two imshow windows displaying the frames from the two webcams. I want a third window to display a frame that is computed using the two webcams' frames as input, that is, I'm blending the two cams using cv2.addWeighted.

Here is the single threaded code that does what I am trying to do:: Afterwards will be the multithreaded code that does not work. Also I'll note that if there is only one image, it's because you attached both webcams to the same USB hub, and I guess that won't work.

import numpy as np
import cv2

video_capture_0 = cv2.VideoCapture(0)
video_capture_1 = cv2.VideoCapture(1)

while True:
    # Capture frame-by-frame
    ret0, frame0 = video_capture_0.read()
    ret1, frame1 = video_capture_1.read()

    if (ret0):
        # Display the resulting frame
        cv2.imshow('Cam 0', frame0)

    if (ret1):
        # Display the resulting frame
        cv2.imshow('Cam 1', frame1)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

    dst = cv2.addWeighted(frame0, 0.5, cv2.bitwise_not(frame1), 0.5, 0.0)
    cv2.imshow("Mix",dst)

# When everything is done, release the capture
video_capture_0.release()
video_capture_1.release()
cv2.destroyAllWindows()

This is the multithreaded code that I was trying to get to work initially: The line that says cv2.imshow("Mix", handle1) is where I am having the issue. I just get white within that window and that thread hangs. Any clue what I'm doing wrong here? or clue as to what is happening? Also, would it be appropriate to use multiprocessing to get more performance due to the global interpreter lock applying to a multithreaded process or would it be too complex because you would need to do interprocess communication? Thanks in advance!

#https://stackoverflow.com/questions/29664399/capturing-video-from-two-cameras-in-opencv-at-once
import cv2
import threading

class camThread(threading.Thread):
    def __init__(self, previewName, camID):
        threading.Thread.__init__(self)
        self.previewName = previewName
        self.camID = camID
    def run(self):
        print("Starting " + self.previewName)
        camPreview(self.previewName, self.camID)

def camPreview(previewName, camID):
    cv2.namedWindow(previewName)
    cam = cv2.VideoCapture(camID)
    if cam.isOpened():  # try to get the first frame
        rval, frame = cam.read()
    else:
        rval = False

    while rval:
        if camID == 0:
            global handle1
            handle1 = frame
            print("cam0")
        elif camID == 1:
            global handle2
            handle2 = frame
            print("cam1")

        cv2.imshow(previewName, frame)
        rval, frame = cam.read()
        key = cv2.waitKey(20)
        if key == 27:  # exit on ESC
            break
    cv2.destroyWindow(previewName)

class mixThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.previewName = "Mix"
        self.camID = 2
    def run(self):
        print("Starting " + self.previewName)
        mixPreview()
def mixPreview():
    global handle1
    global handle2
    count = 0
    while 1:

        try:
            global handle1
            global handle2
            ###dst = cv2.addWeighted(frame0, 0.5, cv2.bitwise_not(frame1), 0.5, 0.0)
            ###cv2.imshow("Mix",dst)
            cv2.imshow("Mix", handle1)
        except:
            count = count + 1
            try:
                print(dir(handle1))
                print(dir(handle2))
            except:
                if count % 1000 == 0:
                    print("didnt work")

# Create two threads as follows
thread1 = camThread("Camera 1", 0)
thread2 = camThread("Camera 2", 1)
thread1.start()
thread2.start()
print("thread1 and thread2 .start() called")
thread3 = mixThread()
thread3.start()
print("thread3 started")

1 Answers1

0

okay i figured it out. The issue was that if you don't call cv2.waitKey after your cv2.imshow call, when working with opencv, it causes the white screen and hung / frozen / unresponsive window. So I guess I've got the multithreaded video mixing thing working. Now to see if I can use wxpython slider to control the mix modulation parameters.

#https://stackoverflow.com/questions/29664399/capturing-video-from-two-cameras-in-opencv-at-once
import cv2
import threading

class camThread(threading.Thread):
    def __init__(self, previewName, camID):
        threading.Thread.__init__(self)
        self.previewName = previewName
        self.camID = camID
    def run(self):
        print("Starting " + self.previewName)
        camPreview(self.previewName, self.camID)

def camPreview(previewName, camID):
    cv2.namedWindow(previewName)
    cam = cv2.VideoCapture(camID)
    if cam.isOpened():  # try to get the first frame
        rval, frame = cam.read()
    else:
        rval = False

    while rval:
        if camID == 0:
            global handle1
            handle1 = frame
            print("cam0")
        elif camID == 1:
            global handle2
            handle2 = frame
            print("cam1")

        cv2.imshow(previewName, frame)
        rval, frame = cam.read()
        key = cv2.waitKey(20)
        if key == 27:  # exit on ESC
            break
    cv2.destroyWindow(previewName)

class mixThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.previewName = "Mix"
        self.camID = 2
    def run(self):
        print("Starting " + self.previewName)
        mixPreview()
def mixPreview():
    global handle1
    global handle2
    count = 0
    while 1:

        try:
            global handle1
            global handle2
            dst = cv2.addWeighted(handle1, 0.5, cv2.bitwise_not(handle2), 0.5, 0.0)
            cv2.imshow("Mix",dst)
            key = cv2.waitKey(20)
        except:
            count = count + 1
            try:
                print(dir(handle1))
                print(dir(handle2))
            except:
                if count % 1000 == 0:
                    print("didnt work")

# Create two threads as follows
thread1 = camThread("Camera 1", 0)
thread2 = camThread("Camera 2", 1)
thread1.start()
thread2.start()
print("thread1 and thread2 .start() called")
thread3 = mixThread()
thread3.start()
print("thread3 started")