Carlo
Carlo

Reputation: 1578

Sharing camera frames between threads

I'm trying to build a script to manage multiple threads that are supposed to be running in parallel, and exchange data between them. As a starting point, I have two threads...the first one should be reading frames from a USB camera and send them to queue, while the second should read them and display them.

I tried:

import json
import queue, threading
from queue import Queue
import cv2


class system_manager():
    def __init__(self, source):

        ## camera reader
        self.camera_queue = queue.Queue()
        self.camera_reader = threading.Thread(target=camera_reader, args=(source, self.camera_queue))
        self.camera_reader.daemon = True
        self.camera_reader.run()

        self.camera_display = threading.Thread(target=camera_display, args=(self.camera_queue))
        self.camera_display.daemon = True
        self.camera_display.run()


def camera_reader(source, camera_queue):
    print("Cam Loading...")
    cap = cv2.VideoCapture(source)
    print("Cam Loaded...")
    while(True):
        ret, frame = cap.read()
        camera_queue.put(frame)


def camera_display(camera_queue):
    print("doing something")
    while(True):
        frame = camera_queue.get()
        key = cv2.waitKey(1)
        if (key == ord('q')):
            break
        cv2.imshow("frame", frame)



if __name__ == "__main__":
    SM = system_manager(source=0)

but it's not really working. The first thread, the one supposed to read frames, is actually doing that, but the second one is not displaying anything (there's a print statement at the beginning, and it's not shown). Also, after running for a few minutes, it got my computer completely stuck, so I assume I'm accidentally continuously occupying memory. I'm fairly new to multiprocessing/multithreading, so I'm probably doing some very basic mistake somewhere.

EDIT Ok, fixed the memory problem by using:

self.camera_queue = queue.Queue(maxsize=5)

but the second thread is not working yet

Upvotes: 0

Views: 841

Answers (1)

Fadi Abu Raid
Fadi Abu Raid

Reputation: 841

Use thread.start() instead of thread.run() , fix the thread target method and add comma after the argument. This works.

import json
import queue, threading
from queue import Queue
import cv2


class system_manager():
    def __init__(self, source):

        ## camera reader
        self.camera_queue = queue.Queue(maxsize=5)
        self.camera_reader = threading.Thread(target=camera_reader, args=(source, self.camera_queue))
        self.camera_reader.daemon = True
        self.camera_reader.start()
        self.camera_display = threading.Thread(target=camera_display, args=(self.camera_queue,))
        self.camera_display.daemon = True
        self.camera_display.start()


def camera_reader(source, camera_queue):
    print("Cam Loading...")
    cap = cv2.VideoCapture(source)
    print("Cam Loaded...")
    while(True):
        ret, frame = cap.read()
        camera_queue.put(frame)


def camera_display(camera_queue):
    print("doing something")
    while(True):
        frame = camera_queue.get()
        key = cv2.waitKey(1)
        if (key == ord('q')):
            break
        cv2.imshow("frame", frame)



if __name__ == "__main__":
    SM = system_manager(source=0)

Upvotes: 2

Related Questions