华荣三照明、合信、荣欣八组合馈电
This commit is contained in:
236
QT5_Project/KD_ZM_6/opencv/MultiFunc_V2.py
Normal file
236
QT5_Project/KD_ZM_6/opencv/MultiFunc_V2.py
Normal file
@ -0,0 +1,236 @@
|
||||
import sys
|
||||
import cv2
|
||||
import time
|
||||
import numpy as np
|
||||
import threading
|
||||
import socket
|
||||
import struct, os, select
|
||||
|
||||
|
||||
class GlobVar:
|
||||
server_ip = '192.168.1.17'
|
||||
server_port = 8000
|
||||
name_namelist = '' # 人脸匹配结果
|
||||
|
||||
event2 = threading.Event() # 用于告知socket进程,数据已准备好,可以发送给服务器了
|
||||
event3 = threading.Event() # 用于告知socket进程,允许或不允许修改name_namelist
|
||||
|
||||
flag = 0
|
||||
|
||||
st_time = 0 # 记录定时1秒的起始时间
|
||||
nd_time = 0 # 记录定时1秒的结束时间
|
||||
|
||||
frame_new = []
|
||||
frame_old = []
|
||||
|
||||
sys_path = sys.path[0].replace("\\", "/")
|
||||
|
||||
# 加载人脸检测模型
|
||||
tensorflowWeightFile = sys_path + "/opencv_face_detector.pbtxt"
|
||||
tensorflowModelFile = sys_path + "/opencv_face_detector_uint8.pb"
|
||||
|
||||
conf_threshold = 0.7
|
||||
|
||||
# net = cv2.dnn.readNetFromCaffe(caffeWeightFile, caffeModel=None) # 未找到caffee的模型文件
|
||||
net = cv2.dnn.readNetFromTensorflow(tensorflowModelFile, tensorflowWeightFile)
|
||||
|
||||
faces = np.array([])
|
||||
|
||||
|
||||
class ClientNetworkThread(threading.Thread):
|
||||
|
||||
def __init__(self):
|
||||
self._running = True # 定义线程状态变量
|
||||
super().__init__()
|
||||
|
||||
def terminate(self):
|
||||
self._running = False
|
||||
|
||||
def run(self):
|
||||
while self._running:
|
||||
if GlobVar.event2.isSet():
|
||||
sock_client_image()
|
||||
time.sleep(0.02)
|
||||
|
||||
|
||||
def sock_client_image():
|
||||
# 1、建立socket
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect((GlobVar.server_ip, GlobVar.server_port))
|
||||
s.setblocking(0) # 设置为非阻塞模式
|
||||
except socket.error as msg:
|
||||
print("%s L102" % msg)
|
||||
print("未连接到服务器 L103")
|
||||
try:
|
||||
s.close()
|
||||
except socket.error as msg:
|
||||
print(msg)
|
||||
return
|
||||
# 2、发送图片数据,如果发送成功则等待接收,如果不成功则不进行接收
|
||||
flag = socket_send(s)
|
||||
# 3、接收识别结果
|
||||
if flag: socket_recv(s)
|
||||
# 4、关闭socket
|
||||
try:
|
||||
s.close()
|
||||
except socket.error as msg:
|
||||
print(msg)
|
||||
|
||||
|
||||
def action():
|
||||
if len(GlobVar.faces) == 1: # 检测到有且仅有一张人脸,并且保持静止1秒
|
||||
if GlobVar.flag == 0:
|
||||
GlobVar.flag = 1
|
||||
GlobVar.frame_old = GlobVar.frame_new
|
||||
GlobVar.st_time = time.time() # 开始计时
|
||||
else:
|
||||
if moving_detect(GlobVar.frame_old, GlobVar.frame_new): # 画面静止
|
||||
GlobVar.nd_time = time.time() # 计算时间是否达到1秒
|
||||
# print("已保持不动 {0} 秒".format(end - start))
|
||||
if GlobVar.nd_time - GlobVar.st_time >= 1 and GlobVar.flag == 1: # 计时1秒,时间到
|
||||
GlobVar.flag = 2
|
||||
print('存在单张人脸L55')
|
||||
|
||||
else: # 画面有变动
|
||||
GlobVar.flag = 0
|
||||
else: # 无人脸或有多张人脸
|
||||
GlobVar.flag = 0
|
||||
if len(GlobVar.faces) > 1:
|
||||
print("Error: More than one person!!!")
|
||||
else:
|
||||
print("No person!")
|
||||
|
||||
|
||||
def function(image):
|
||||
GlobVar.faces = [] # 清空
|
||||
GlobVar.name_namelist = "" # 清空
|
||||
GlobVar.event2.clear()
|
||||
GlobVar.event3.set()
|
||||
GlobVar.frame_new = image
|
||||
|
||||
(h, w) = image.shape[:2]
|
||||
blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0,
|
||||
(300, 300), (104.0, 177.0, 123.0))
|
||||
|
||||
GlobVar.net.setInput(blob)
|
||||
detections = GlobVar.net.forward()
|
||||
|
||||
for i in range(0, detections.shape[2]):
|
||||
# extract the confidence (i.e., probability) associated with the
|
||||
# prediction
|
||||
confidence = detections[0, 0, i, 2]
|
||||
# filter out weak detections by ensuring the `confidence` is
|
||||
# greater than the minimum confidence
|
||||
if confidence < GlobVar.conf_threshold:
|
||||
continue
|
||||
# compute the (x, y)-coordinates of the bounding box for the
|
||||
# object
|
||||
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
|
||||
(startX, startY, endX, endY) = box.astype("int")
|
||||
|
||||
GlobVar.faces.append(i)
|
||||
GlobVar.faces[i] = [startX, startY, endX, endY]
|
||||
# cv2.rectangle(frame, (startX, startY), (endX, endY), (0, 255, 255), 1)
|
||||
|
||||
# 再根据人脸个数做出判断
|
||||
action()
|
||||
|
||||
# 若存在单张人脸且静止时间达到1秒
|
||||
if GlobVar.flag == 2:
|
||||
print("返回人脸位置坐标,并且发送图片到server")
|
||||
GlobVar.flag = 0
|
||||
saveimage(h, w)
|
||||
GlobVar.event2.set() # 告知子进程数据已准备好
|
||||
|
||||
GlobVar.event3.clear()
|
||||
name = GlobVar.name_namelist
|
||||
GlobVar.event3.set()
|
||||
|
||||
# 返回faces和name
|
||||
return GlobVar.faces, name
|
||||
|
||||
|
||||
def moving_detect(img1, img2): # 比较两幅画面,判断是否静止
|
||||
grey_diff = cv2.absdiff(img1, img2) # 计算两幅图的像素差
|
||||
change = np.average(grey_diff)
|
||||
if change > 10:
|
||||
return False # 画面有明显变动,返回False
|
||||
else:
|
||||
return True # 画面无明显变动,返回True
|
||||
|
||||
|
||||
def saveimage(height, width):
|
||||
# 提取人脸区域并保存成图片
|
||||
for (x, y, endx, endy) in GlobVar.faces:
|
||||
(w, h) = (endx - x, endy - y)
|
||||
left = int(x - 0.25 * w)
|
||||
if left < 0: left = 0
|
||||
right = int(x + 1.25 * w)
|
||||
if right > width: right = width
|
||||
top = int(y - 0.25 * h)
|
||||
if top < 0: top = 0
|
||||
bottom = int(y + 1.25 * h)
|
||||
if bottom > height: bottom = height
|
||||
|
||||
cropped_image = GlobVar.frame_new[top:bottom, left:right]
|
||||
cv2.imwrite("singleface.jpg", cropped_image)
|
||||
|
||||
|
||||
def socket_send(s):
|
||||
file_path = 'singleface.jpg' # 输入当前目录下的图片名
|
||||
# pack按照图片格式、图片名字、图片大小
|
||||
|
||||
fsend = struct.pack(b'128sq', # 图片打包的格式为128sq
|
||||
bytes(os.path.basename(file_path), encoding='utf-8'), # 返回图片文件名,编码字节化
|
||||
os.stat(file_path).st_size) # 返回读取文件的相关属性,然后得到其中st_size的数据(记录文件大小)
|
||||
try:
|
||||
s.send(fsend)
|
||||
except socket.error as msg:
|
||||
print(msg)
|
||||
return 0 # 数据发送失败,返回0
|
||||
|
||||
fp = open(file_path, 'rb') # 打开要传输的图片
|
||||
|
||||
while True:
|
||||
data = fp.read(1024) # 读入图片数据,data是图片的数据字节流(由于图片字节很多,这里一次只读取1024个字节)
|
||||
if not data: # 如果读到字节的数据没有了
|
||||
print('{0} send over...'.format(len(data)))
|
||||
break
|
||||
try:
|
||||
s.send(data) # 以二进制格式发送图片数据(每次发1024个字节)
|
||||
except socket.error as msg:
|
||||
print(msg)
|
||||
return 0 # 数据发送出错,返回0
|
||||
|
||||
print("数据已发送,开始接收...")
|
||||
GlobVar.event2.clear()
|
||||
return 1 # 数据发送完毕,返回1
|
||||
|
||||
|
||||
def socket_recv(s):
|
||||
st1 = time.time()
|
||||
response = ""
|
||||
|
||||
while True:
|
||||
infds, outfds, errfds = select.select([s, ], [], [])
|
||||
if len(infds) > 0: # 有数据返回,不管是否成功接收,均跳出while循环
|
||||
try:
|
||||
buf = s.recv(1024).decode('utf-8')
|
||||
print("received: " + str(buf))
|
||||
response += str(buf)
|
||||
break
|
||||
except socket.error as msg:
|
||||
print(msg)
|
||||
break
|
||||
except BlockingIOError:
|
||||
break
|
||||
|
||||
else:
|
||||
print("no data comes back")
|
||||
|
||||
st2 = time.time()
|
||||
if st2 - st1 > 0.5:
|
||||
break # 等待超时
|
||||
if GlobVar.event3.isSet():
|
||||
GlobVar.name_namelist = response
|
||||
Reference in New Issue
Block a user