Files
Intelligent-Elderly-Care/Class/detection/algorithm_fall.py
2020-08-02 11:29:42 +08:00

119 lines
4.3 KiB
Python

import datetime
import threading
import cv2
import numpy as np
import statistics
import math
from Post import post
from PIL import ImageDraw, ImageFont
from PIL import Image
def fall_detect(cnts, defined_min_area, frame, prevX, prevY, xList, yList, centerV, alert, pre):
for c in cnts:
# exclusion
if cv2.contourArea(c) < defined_min_area:
continue
# outer bounding box
(x_b, y_b, w_b, h_b) = cv2.boundingRect(c)
cv2.rectangle(frame, (x_b, y_b), (x_b + w_b, y_b + h_b), (0, 255, 255), 2) # 黄色矩形
# rotating bounding box
rect = cv2.minAreaRect(c) # 得到最小外接矩形的(中心(x,y), (宽,高), 旋转角度)
box = cv2.boxPoints(rect) # 获取最小外接矩形的4个顶点坐标
box = np.int0(box)
cv2.drawContours(frame, [box], 0, (0, 0, 255), 2)
# averaging line
rows, cols = frame.shape[:2]
[vx, vy, x, y] = cv2.fitLine(c, cv2.DIST_L2, 0, 0.01, 0.01)
lefty = (-x * vy / vx) + y
righty = ((cols - x) * vy / vx) + y
cv2.line(frame, (cols - 1, righty), (0, lefty), (255, 0, 0), 2)
# ellipse
elps = cv2.fitEllipse(c)
(x, y), (MA, ma), angle = cv2.fitEllipse(c)
cv2.ellipse(frame, elps, (255, 0, 0), 3) # red
# Aspect Ratio
AR = MA / ma
# Center Speed - acceleration
prevX = 0.0
prevY = 0.0
centerSpeed = 0
if xList.full():
prevX = statistics.median(list(xList.queue))
prevY = statistics.median(list(yList.queue))
xList.get()
yList.get()
xList.put(elps[0][0])
yList.put(elps[0][1])
X = statistics.median(list(xList.queue))
Y = statistics.median(list(yList.queue))
if xList.full():
dx = abs(prevX - X)
dy = abs(prevY - Y)
centerV = math.sqrt(dx ** 2 + dy ** 2)
# calculate probabilities for the 4 features
pAngle = (abs(angle - 90) - 50) / 10
pAngle = 1 / (math.exp(pAngle) + 1)
pAR = 10 * AR - 5
pAR = 1 / (math.exp(pAR) + 1)
ACS = centerV - 9
try:
ACS = 1 / (math.exp(ACS) + 1)
except:
ACS = 1 / (float('inf') + 1)
# print("pAngle : ", pAngle)
# print("pAR : ", pAR)
# print("ACS : ", ACS)
# confidence
P_FALL = pAngle * pAR * ACS + 0.5
# print("P_FALL1 : ", P_FALL)
P_FALL = 1 / (math.exp(-(P_FALL - 0.65) * 10) + 1)
# print("P_FALL2: ", P_FALL)
# status display
# cv2.putText(frame, "Status : ", (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 14)
# cv2.putText(frame, "Fall Confidence: {0:.2f} ".format(P_FALL), (10, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.5,
# (0, 128, 255), 14)
# cv2.putText(frame, "Angle: {0:.2f}".format(angle), (10, 220),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 14)
# cv2.putText(frame, "AR: {0:.2f}".format(AR), (10, 237),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 14)
# cv2.putText(frame, "Center Speed: {0:.2f}".format(centerV), (10, 256),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 14)
# fall
if P_FALL > 0.88:
if alert > 3:
# print("fall")
font = ImageFont.truetype("simsun.ttc", 30, index=1)
img_rd = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
draw = ImageDraw.Draw(img_rd)
draw.text((10, 10), text="Fall Detected", font=font,
fill=(255, 0, 0))
frame = cv2.cvtColor(np.array(img_rd), cv2.COLOR_RGB2BGR)
time_snap = datetime.datetime.now()
cv2.imwrite('fall_detection' + str(time_snap).replace(':', '') + '.jpg', frame)
if (datetime.datetime.now() - pre).total_seconds() > 5:
t = threading.Thread(
target=post(event=3, imagePath='fall_detection' + str(time_snap).replace(':', '') + '.jpg'))
t.setDaemon(False)
t.start()
pre = datetime.datetime.now()
# cv2.imwrite("report.jpg", frame)
# send_alert.SendMail("report.jpg")
alert = alert + 1
else:
alert = alert + 1
return frame, alert, pre