-
Notifications
You must be signed in to change notification settings - Fork 0
/
testingvolunteeractivity.py
175 lines (144 loc) · 6.23 KB
/
testingvolunteeractivity.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# -*- coding: utf-8 -*-
'''
义工是否和老人有互动主程序
用法:
python testingvolunteeractivity.py
python testingvolunteeractivity.py --filename tests/desk_01.mp4
'''
from pymysql.converters import escape_string
from oldcare.facial import FaceUtil
from scipy.spatial import distance as dist
from oldcare.utils import fileassistant
from PIL import Image, ImageDraw, ImageFont
import cv2
import time
import imutils
import numpy as np
import argparse
import os
from inserting import insertDatabase
# 传入参数
ap = argparse.ArgumentParser()
ap.add_argument("-f", "--filename", required=False, default = '',
help="")
args = vars(ap.parse_args())
# 全局变量
pixel_per_metric = None
input_video = args['filename']
model_path = 'models/face_recognition_hog.pickle'
people_info_path = 'info/people_info.csv'
output_active_path = 'supervision/active'
# 全局常量
FACE_ACTUAL_WIDTH = 20 # 单位厘米 姑且认为所有人的脸都是相同大小
VIDEO_WIDTH = 640
VIDEO_HEIGHT = 480
ACTUAL_DISTANCE_LIMIT = 100# cm
# 得到 ID->姓名的map 、 ID->职位类型的map
id_card_to_name, id_card_to_type = fileassistant.get_people_info(
people_info_path)
# 初始化摄像头
if not input_video:
vs = cv2.VideoCapture(0)
time.sleep(2)
else:
vs = cv2.VideoCapture(input_video)
# 加载模型
faceutil = FaceUtil(model_path)
print('[INFO] 开始检测义工和老人是否有互动...')
# 不断循环
counter = 0
while True:
counter += 1
# grab the current frame
(grabbed, frame) = vs.read()
# if we are viewing a video and we did not grab a frame, then we
# have reached the end of the video
if input_video and not grabbed:
break
if not input_video:
frame = cv2.flip(frame, 1)
frame = imutils.resize(frame,
width = VIDEO_WIDTH,
height = VIDEO_HEIGHT)#压缩,加快识别速度
face_location_list, names = faceutil.get_face_location_and_name(
frame)
people_type_list = list(set([id_card_to_type[i] for i in names]))
volunteer_centroids = []
old_people_centroids = []
old_people_name = []
# loop over the face bounding boxes
for ((left, top, right, bottom), name) in zip(face_location_list,
names): #处理单个人
person_type = id_card_to_type[name]
# 将人脸框出来
rectangle_color = (0, 0, 255)
if person_type == 'old_people':
rectangle_color = (0, 0, 128)
elif person_type == 'employee':
rectangle_color = (255, 0, 0)
elif person_type == 'volunteer':
rectangle_color = (0, 255, 0)
else:
pass
cv2.rectangle(frame, (left, top), (right, bottom),
rectangle_color, 2)
if 'volunteer' not in people_type_list: #如果无义工则跳出循环
continue
if person_type == 'volunteer': # 如果检测到有义工存在
# 获得义工位置
volunteer_face_center = (int((right + left)/2),
int((top + bottom)/2))
volunteer_centroids.append(volunteer_face_center)
cv2.circle(frame,
(volunteer_face_center[0],
volunteer_face_center[1]),
8, (255, 0, 0), -1)
elif person_type == 'old_people': # 如果没有发现义工
old_people_face_center = (int((right + left)/2),
int((top + bottom)/2))
old_people_centroids.append(old_people_face_center)
old_people_name.append(name)
cv2.circle(frame,
(old_people_face_center[0],
old_people_face_center[1]),
4, (0, 255, 0), -1)
else:
pass
#把人名写上(同时处理中文显示问题)
img_PIL = Image.fromarray(cv2.cvtColor(frame,cv2.COLOR_BGR2RGB))
draw = ImageDraw.Draw(img_PIL)
final_label = id_card_to_name[name]
#draw.text((left, top - 30), final_label,font=ImageFont.truetype('NotoSansCJK-Black.ttc',40), fill=(255,0,0)) # linux
draw.text((left, top - 30), final_label,font=ImageFont.truetype('oldcare/resource/MSYH.ttc',40),fill=(255,0,0))
# 转换回OpenCV格式
frame = cv2.cvtColor(np.asarray(img_PIL),cv2.COLOR_RGB2BGR)
# 在义工和老人之间划线
for i in volunteer_centroids:
for j_index, j in enumerate(old_people_centroids):
pixel_distance = dist.euclidean(i, j)
face_pixel_width = sum([i[2] - i[0] for i in
face_location_list])/len(face_location_list)
pixel_per_metric = face_pixel_width/FACE_ACTUAL_WIDTH
actual_distance = pixel_distance/pixel_per_metric
if actual_distance < ACTUAL_DISTANCE_LIMIT:
cv2.line(frame, (int(i[0]), int(i[1])),
(int(j[0]), int(j[1])),(255, 0, 255), 2)
label= 'distance: %dcm' %(actual_distance)
cv2.putText(frame, label, (frame.shape[1] - 150, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.5,
(0, 0, 255), 2)
current_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
print('[EVENT] %s, 房间桌子, %s 正在与义工交互.'%(current_time,id_card_to_name[old_people_name[j_index]]))
cv2.imwrite(os.path.join(output_active_path,'snapshot_%s.jpg'%(time.strftime('%Y%m%d_%H%M%S'))), frame)
photoid='snapshot_%s.jpg' % (time.strftime('%Y%m%d_%H%M%S'))
command = "INSERT INTO cv_interactive(EVENT_NAME,PHOTO_ID,TIME)VALUES ( '%s', '%s','%s')" %(escape_string('interactive'),escape_string(photoid),escape_string(time.strftime('%Y%m%d_%H%M%S')))
insertDatabase(command)
# show our detected faces along with smiling/not smiling labels
cv2.imshow("Checking Volunteer's Activities", frame)
# Press 'ESC' for exiting video
k = cv2.waitKey(1) & 0xff
if k == 27:
break
# cleanup the camera and close any open windows
vs.release()
cv2.destroyAllWindows()