Sambhav Kumar
Sambhav Kumar

Reputation: 388

How can I run a parallel thread for applying a function on each frame of a video stream?

I am trying to make an application with a flask that

The problem is that due to a function operation, the result renders with a bit of lag. To overcome this I tried to run the function over another thread. Can you please help in running the function over each frame of the video and displaying the resultant frames in the form of a video? My main function looks somewhat like :

def detect_barcode():
global vs, outputFrame, lock


total = 0

# loop over frames from the video stream
while True:
    frame = vs.read()
    frame = imutils.resize(frame, width=400)
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (7, 7), 0)
    timestamp = datetime.datetime.now()
    cv2.putText(frame, timestamp.strftime(
        "%A %d %B %Y %I:%M:%S%p"), (10, frame.shape[0] - 10),
        cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 255), 1)
    if total > frameCount:
        # detect barcodes in the image
        barcodes = md.detect(gray)

        # check to see if barcode was found
        if barcode in barcodes:
            x,y,w,h = cv2.boundRect(barcode)
        cv2.rectangle(frame,x,y,(x+w),(y+h),(255,0,0),2)
    total += 1
    # lock
    with lock:
        outputFrame = frame.copy()
if __name__ == '__main__':

# start a thread that will perform motion detection
t = threading.Thread(target=detect_barcode)
t.daemon = True
t.start()
app.run(debug=True)

vs.stop()

Upvotes: 1

Views: 329

Answers (1)

Pascal
Pascal

Reputation: 95

I literally just did something like this. My solution was asyncio's concurrent.futures module.

import concurrent.futures as futures

Basically, you create your executor and 'submit' your blocking method as a parameter. It returns something called Future, which you can check the result of (if any) every frame.

executor = futures.ThreadPoolExecutor()

would initialize the executor

future_obj = executor.submit(YOUR_FUNC, *args)

would start execution. Sometime later on you could check its status

if future_obj.done():
    print(future_obj.result())
else:
    print("task running")
    # come back next frame and check again

Upvotes: 1

Related Questions