Python OpenCV:多线程与 opencv 视频流
Python OpenCV: Mutithreading with opecv video streaming
我想要 运行 一个多线程以及 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()
这几乎不是一个好主意:
t1.start()
t1.join()
问题是,它违背了线程的 唯一 目的,即能够同时处理两个不同的事情。
这更有意义,因为“...some_other_thing...()”可以在 t1 执行 t1 执行的任何操作时发生。
t1.start()
do_some_other_thing_concurrently_with_t1()
t1.join()
.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, 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()
我想要 运行 一个多线程以及 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()
这几乎不是一个好主意:
t1.start()
t1.join()
问题是,它违背了线程的 唯一 目的,即能够同时处理两个不同的事情。
这更有意义,因为“...some_other_thing...()”可以在 t1 执行 t1 执行的任何操作时发生。
t1.start()
do_some_other_thing_concurrently_with_t1()
t1.join()
.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, 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()