Python OpenCV:具有opecv视频流的多线程

问题描述

我想与opencv视频流一起运行一个多线程。如果在视频不断流传输的过程中检测到对象3秒钟,我想激活GPIO。我尝试使用多线程(join方法),但视频在线程调用期间暂停,因为它具有time.sleep()。有什么办法可以使视频不断并并行地运行线程?下面是具有相同方式的代码。如果我删除连接,那么time.sleep根本没有任何作用。

import threading 
import time
import numpy as np
import cv2

def print_hello():
    print("Hello")
    time.sleep(3)
    print ("World")

t1 = threading.Thread(target=print_hello)  

cap = cv2.VideoCapture(0)

while(True):
    # Capture frame-by-frame
    ret,frame = cap.read()

    # Our operations on the frame come here
    gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)

    # Display the resulting frame
    cv2.imshow('frame',gray)

    t1.start()
    t1.join()

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

# When everything done,release the capture
cap.release()
cv2.destroyAllWindows()

解决方法

.join()等待线程结束,并阻塞了代码-因此它不发送任何内容以在循环内运行它,但您应在循环后或程序结尾处运行它。

另一个问题是.start()处于循环中,因为.start()只能运行一次线程,因此在循环中多次使用它会产生错误。

您可以在循环之前启动线程,并在线程内部运行一些循环以使其始终运行。

import threading 
import time
import numpy as np
import cv2

# --- functions ---

running = True

def print_hello():
    while running:
        print("Hello World")
        time.sleep(3)

# --- main ---

t1 = threading.Thread(target=print_hello)  
t1.start()

# --- loop ---

cap = cv2.VideoCapture(0)

while True:
    # Capture frame-by-frame
    ret,frame = cap.read()

    # Our operations on the frame come here
    gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)

    # Display the resulting frame
    cv2.imshow('frame',gray)

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

# --- after loop ---

running = False # to stop loop in thread
t1.join()

cap.release()
cv2.destroyAllWindows()

如果必须启动循环线程,则还必须在循环内部创建新线程。

在此示例中,我使用键t启动新线程-否则,它将在每个循环中创建新线程,因此将在短时间内创建数百个线程,因此毫无意义。

import threading 
import time
import numpy as np
import cv2

# --- functions ---

def print_hello():
    print("Hello")
    time.sleep(3)
    print("World")

# --- main ---

all_threads = []

# --- loop ---

cap = cv2.VideoCapture(0)

while True:
    # Capture frame-by-frame
    ret,gray)

    key = cv2.waitKey(1) & 0xFF
    if key == ord('q'):
        break
    if key == ord('t'):
        t = threading.Thread(target=print_hello)  
        t.start()
        all_threads.append(t)

# --- after loop ---

for t in all_threads:
    t.join()

cap.release()
cv2.destroyAllWindows()

但是即使多次按下t,您也可以同时创建多个线程,它们将一起工作。如果您不需要它,则必须控制威胁是否仍在起作用,仅在不再起作用时才创建新威胁-使用is_alive()-这样可以使其变得更加复杂。

import threading 
import time
import numpy as np
import cv2

# --- functions ---

def print_hello():
    print("Hello")
    time.sleep(3)
    print("World")

# --- main ---

t = None

# --- loop ---

cap = cv2.VideoCapture(0)

while True:
    # Capture frame-by-frame
    ret,gray)

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

    if key == ord('t'):
        if t is None or not t.is_alive():
            t = threading.Thread(target=print_hello)  
            t.start()
        else:
            print('previous thread is still running')
            
# --- after loop ---

if t is not None:
    t.join()

cap.release()
cv2.destroyAllWindows()
,

这几乎从来不是一个好主意:

{{ x }}

问题是,它破坏了线程的 only 目的,即能够同时处理两个两个不同的事物。

这更有意义,因为在t1做t1所做的事情时可能会发生“ ... some_other_thing ...()”。

t1.start()
t1.join()

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...