python - Python OpenCV:使用 opecv 视频流进行多线程处理
问题描述
我想与 opencv 视频流一起运行一个多线程。如果在视频不断流式传输时检测到对象 3 秒,我想激活 GPIO。我尝试过使用多线程(加入方法),但视频在线程调用期间暂停,因为它有 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()
如果您必须在循环中启动线程,那么您还必须在循环内创建新线程。
在这个例子中,我使用 keyt
来启动新线程——没有这个,它会在每个循环中创建新线程,所以它会在短时间内创建数百个线程,所以没有意义。
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, 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)
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, 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)
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()
推荐阅读
- javascript - Netlify 错误混合内容,该页面通过 HTTPS 加载,但请求的 HTTP 不安全脚本
- outlook - 更改订阅日历的位置以便更新
- python-3.x - 强制子类的重写方法由 mypy 具有相同的类型签名
- laravel-livewire - 为什么 AppHeader 组件的方法不会在发出时触发?
- apache-spark - 在 lambda 中使用 pyspark sql 函数导致 pickle 错误
- flutter - 如何在 HorizontalPicker Flutter 中显示来自 JSON 的时间?
- amazon-web-services - 如果我使用 ECR 映像/容器,我的 AWS Lambda 函数的冷启动会需要更长时间吗?
- azure - 了解 Azure Web App 日志文件输出中的 HTTP 错误
- css - Sass/SCSS 没有在本地编译
- python - response.json 不工作,现在 python 很时髦