получить доступ к OpenCV + Python в другом потоке, используя глобальный? - PullRequest
0 голосов
/ 02 мая 2020

спасибо за проверку моего вопроса. Я использую OpenCV в Python36 32bit и пытаюсь выполнить микширование видео sh с помощью модуля потоков. У меня есть два imshow windows, отображающие кадры из двух веб-камер. Я хочу, чтобы в третьем окне отображался кадр, который вычисляется с использованием кадров двух веб-камер в качестве входных данных, то есть я смешиваю два видеокамеры с использованием cv2.addWeighted.

Вот однопоточный код, который выполняет что я пытаюсь сделать :: После этого будет многопоточный код, который не работает. Также я отмечу, что если есть только одно изображение, это потому, что вы подключили обе веб-камеры к одному USB-концентратору, и я думаю, это не сработает.

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()

Это многопоточный код, который я изначально пытался приступить к работе: строка, в которой написано cv2.imshow ("Mix", handle1), - вот где у меня проблема Я просто побелел в этом окне, и эта нить зависла. Любая подсказка, что я здесь делаю не так? или подсказка о том, что происходит? Кроме того, было бы целесообразно использовать многопроцессорность для получения большей производительности из-за глобальной блокировки интерпретатора, применяемой к многопоточному процессу, или это будет слишком сложно, поскольку вам потребуется межпроцессное взаимодействие? Заранее спасибо!

#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 Ответ

0 голосов
/ 02 мая 2020

хорошо, я понял это. Проблема заключалась в том, что если вы не вызываете cv2.waitKey после вызова cv2.imshow, то при работе с opencv это вызывает белый экран и зависание / зависание / не отвечает окно. Так что я думаю, что у меня работает многопотоковое микширование видео. Теперь посмотрим, смогу ли я использовать ползунок wx python для управления параметрами модуляции микса.

#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")
...