Files
MenuPython_QT/QT5_Project/KD_ZM_6/opencv/MultiThreadClient_V2.py

168 lines
5.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Client主进程
# 读取摄像头数据并显示
import MultiFunc_V2 as Func
import cv2
import threading
import numpy as np
import time
import queue
rtsp_ulr = 0 #"rtsp://192.168.1.206:554"
# rtsp_ulr = "rtsp://admin123456@192.168.1.123/video1"
# 自定义无缓存读视频类
class NetCameraCapture:
"""Customized VideoCapture, always read latest frame """
def __init__(self, camera_id):
# "camera_id" is a int type id or string name
self.cap = cv2.VideoCapture(camera_id)
self.q = queue.Queue(maxsize=3)
self.stop_threads = False # to gracefully close sub-thread
th = threading.Thread(target=self._reader)
th.daemon = True # 设置工作线程为后台运行
th.start()
# 实时读帧,只保存最后一帧
def _reader(self):
while not self.stop_threads:
if self.cap.isOpened(): # 判断是否已经打开
ret, frame = self.cap.read()
if not ret:
break
if not self.q.empty():
try:
self.q.get_nowait()
except queue.Empty:
pass
self.q.put(frame)
def read(self):
return True, self.q.get()
def get(self, id):
return self.cap.get(id)
def release(self):
self.stop_threads = True
self.cap.release()
class ClientThread(threading.Thread):
def __init__(self):
self._running = True # 定义线程状态变量
super().__init__()
def terminate(self):
self._running = False
def run(self):
while self._running:
if GlobalVar.event1.isSet():
GlobalVar.faces, temp_name = Func.function(GlobalVar.frame)
# 如果识别结果为空且少于15张图片约0.5s则不更新name
if len(temp_name) < 2 and GlobalVar.i < 15: # 识别结果为空
GlobalVar.i = GlobalVar.i + 1
else:
GlobalVar.name = temp_name
GlobalVar.i = 0
time.sleep(0.02)
class GlobalVar:
event1 = threading.Event() # 用于主进程读取摄像头图像时,不会同时取用图像
frame = []
faces = np.array([])
t = ClientThread() # 图片处理的子线程
sk = Func.ClientNetworkThread() # 与服务器通信的子线程
width = 0 # 图片宽度
height = 0 # 图片高度
name = "" # 识别结果
i = 0
def init():
GlobalVar.event1.clear
# 开启线程
GlobalVar.t.start()
GlobalVar.sk.start()
def draw_frame():
font = cv2.FONT_HERSHEY_COMPLEX
cv2.putText(GlobalVar.frame, "Press 'q': Quit", (20, GlobalVar.height - 30), font, 0.8, (84, 255, 159), 1,
cv2.LINE_AA)
# 显示人脸识别结果
cv2.putText(GlobalVar.frame, GlobalVar.name, (20, GlobalVar.height - 80), font, 0.8, (84, 255, 159), 1, cv2.LINE_AA)
if len(GlobalVar.faces) != 0:
cv2.putText(GlobalVar.frame, "Faces: " + str(len(GlobalVar.faces)), (20, 50), font, 1, (0, 0, 255), 1,
cv2.LINE_AA)
for kk, d in enumerate(GlobalVar.faces):
# 绘制矩形框
# cv2.rectangle(GlobalVar.frame, tuple([d.left(), d.top()]), tuple([d.right(), d.bottom()]),
cv2.rectangle(GlobalVar.frame, (d[0], d[1]), (d[2], d[3]), (0, 255, 255), 2)
# 显示人脸识别结果
cv2.putText(GlobalVar.frame, GlobalVar.name, (d[0], d[1] - 10), font, 0.8, (0, 255, 255), 1, cv2.LINE_AA)
else:
cv2.putText(GlobalVar.frame, "Faces: " + str(0), (20, 50), font, 1, (0, 0, 255), 1, cv2.LINE_AA)
def demo():
# 初始化
init()
# 创建 cv2 摄像头对象
# 获取摄像机来捕获实时流 参数0表示本台设备的序号为0的采集设备camera
# capture = cv2.VideoCapture(0)
# 使用网络摄像头
capture = NetCameraCapture(rtsp_ulr)
# 获取捕获图像分辨率
GlobalVar.width, GlobalVar.height = int(capture.get(3)), int(capture.get(4))
print("图像尺寸:", GlobalVar.width, "x", GlobalVar.height, "px")
i = 0
s1 = time.time()
while i < 1000:
i = i + 1
GlobalVar.event1.clear() # 置为false不允许子进程读取图片
ret, GlobalVar.frame = capture.read()
# if frame is read correctly ret is True
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
exit()
GlobalVar.event1.set() # 置为true允许子进程读取图片
# 在图片上绘制文字和框
draw_frame()
# 窗口显示 show with opencv
cv2.imshow("Face Recognition", GlobalVar.frame)
if cv2.waitKey(1) == ord('q') or cv2.waitKey(1) == ord('Q'):
# 关闭摄像头 释放窗口
capture.release()
cv2.destroyAllWindows()
GlobalVar.t.terminate()
break
s2 = time.time()
print(i, " 张图片共用时:", (s2 - s1))
GlobalVar.t.terminate()
GlobalVar.sk.terminate()
if __name__ == "__main__":
demo()