168 lines
5.0 KiB
Python
168 lines
5.0 KiB
Python
# 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://admin:123456@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()
|