如何解决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()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。