LISHUZUOXUN_yangjiang/Exercise3/sit_up_old_3.py

299 lines
14 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.

import time
from MCamera.mp_algorithm import MediapipeAlgorithmPlugin
from MCamera.mp_camera import MP_RESULT
from MCamera.camera import *
import cv2
import numpy as np
from score_doc import get_fin_score
from Speaker.speak_base import beep
from copy import deepcopy
from Database.manager_database import *
from .base_exercise import BaseExercise
import pyttsx3
class SitUp_Old_3(BaseExercise):
def __init__(self, info, statistic_time=120, camera=None):
super().__init__(info, statistic_time, camera=camera)
self.countdown_flag = threading.Event() # 计时线程
# 个数统计
self.bar = None
self.per = None
self.count = 0
# 当前状态
self.countdown = 120
self.pre_pos = 0
self.speak_state = 0
self.state = 0
self.direction = 0
self.is_storard = True
# 初始化
# 动作持续帧数
self.time = 0
self.time_1 = 0
self.time_2 = 0
self.last_time = 0
self.interval = 0.5
# 开始标志
self.form = 0
# 状态反馈
self.feedback = "开始"
self.sign = 0
self.had_done = False
# 目标朝向
self.dir = 0
self.exercise_type = "仰卧起坐"
# 仰卧起坐参数
self.corner = (160, 460, 100, 520)
self.config = (True, 1, True, False, True, 0.75, 0.8)
MediapipeAlgorithmPlugin.set_corner(corner=self.corner)
MediapipeAlgorithmPlugin.set_config(config=self.config)
def get_result(self):
# 人员年龄
age = self.info.get(AGE)
# 人员性别
gender = "woman" if self.info.get(GENDER) == "" else "man"
score = get_fin_score.Military(gender, int(age), sitUpsResult=int(self.count)).SitUpsScoreEvaluation()
result = {
"count": int(self.count),
"score": score,
"countdown": self.countdown,
"had_done": self.had_done
}
return result
def retail_counting(self):
retail_counting = 3
counting = 0
first_time = time.time()
while True:
this_time = time.time()
if this_time - first_time > counting:
if retail_counting > 0:
self.speak_driver.add_speak(f"{retail_counting}")
self.speak_driver.wait_4_speak()
counting += 1
retail_counting -= 1
else:
break
threading.Thread(target=beep, daemon=True).start()
self.countdown_flag.set()
self.start_time = time.time()
def speak_counting(self, counting_times, name):
self.speak_driver.start()
self.speak_driver.speed_control(200)
self.speak_driver.volume_control(1)
self.speak_driver.add_speak("考试人员{}".format(name))
self.speak_driver.add_speak(f"考试项目{self.exercise_type}")
def count_down(self):
seconds = 120
while True:
self.countdown_flag.wait()
this_time = time.time()
count_time = this_time - self.start_time
second = int(seconds - count_time)
self.countdown = f"{second}"
time.sleep(0.1)
if second == 0:
self.countdown_flag.clear()
break
def run(self) -> None:
self.speak_counting(5, self.info[NAME])
# 准备倒计时
threading.Thread(target=self.count_down).start()
self.is_start = True
# 不停更新计算和更新画面
threading.Thread(target=self.thread_counting_streaming, daemon=True).start()
while not self.is_done():
_img = deepcopy(self.cap.get_frame())
self.img = self.display(_img)
if self.countdown == 120:
self.speak_driver.add_speak(f"长时间未进入准备状态,考试结束")
elif int(self.countdown) <= 1:
self.had_done = True
self.speak_driver.add_speak(f"时间到,考试结束")
elif 1 < int(self.countdown) < 120:
self.speak_driver.add_speak(f"考试终止")
self.is_start = False
def display(self, img):
cv2.rectangle(img, (self.corner[2], self.corner[0]), (self.corner[3], self.corner[1]), (0, 255, 0), 2)
if self.form == 0:
self.detector.draw_dashed_line(img, 100, 400, 520, 440, (0, 0, 255))
if self.dir == 1 and self.sign == 1 and self.countdown_flag.is_set():
self.detector.drawPoint_more(img, [11, 13, 16, 23, 25, 27], bias_x=self.corner[2], bias_y=self.corner[0])
elif self.dir == 2 and self.sign == 1 and self.countdown_flag.is_set():
self.detector.drawPoint_more(img, [12, 14, 15, 24, 26, 28], bias_x=self.corner[2], bias_y=self.corner[0])
if self.sign == 1:
cv2.rectangle(img, (650 - 100, 60), (650 - 80, 282), (255, 255, 255), 2)
if self.bar and self.per:
cv2.rectangle(img, (650 - 98, int(self.bar)), (650 - 82, 280), (102, 106, 233),
cv2.FILLED)
cv2.putText(img, f'{int(self.per)}%', (650 - 125, 320), cv2.FONT_HERSHEY_PLAIN, 2,
(255, 255, 255), 2)
# 绘制计数器
cv2.rectangle(img, (0, 480 - 120), (120, 480), (102, 106, 233), cv2.FILLED)
cv2.putText(img, str(int(self.count)), (10, 480 - 35), cv2.FONT_HERSHEY_PLAIN, 5,
(255, 255, 255), 5)
# 展示状态反馈
cv2.rectangle(img, (640 - 160, 0), (640, 50), (102, 106, 233), cv2.FILLED)
img = self.cv2_img_add_text(img, self.feedback, 640 - 120, 5, (255, 255, 255), 38)
return img
def analysis(self, frame):
catch_time = frame[CATCH_TIME]
if catch_time < self.start_cal_time:
return
img = frame[FRAME_DAT]
lm_list = frame[MP_RESULT]
self.detector.set_result(lm_list)
if self.pre_pos == 0:
self.pre_pos = 1
self.speak_driver.add_speak("请进入准备状态")
if len(lm_list) != 0:
eye_1_y = self.detector.findPosition(img, False)[3][2]
eye_2_y = self.detector.findPosition(img, False)[6][2]
shoulder_1_x = self.detector.findPosition(img, False)[11][1]
shoulder_2_x = self.detector.findPosition(img, False)[11][1]
shoulder_1_y = self.detector.findPosition(img, False)[11][2]
shoulder_2_y = self.detector.findPosition(img, False)[11][2]
hip_1_x = self.detector.findPosition(img, False)[23][1]
hip_2_x = self.detector.findPosition(img, False)[24][1]
hip_1_y = self.detector.findPosition(img, False)[23][2]
hip_2_y = self.detector.findPosition(img, False)[24][2]
knee_1_x = self.detector.findPosition(img, False)[25][1]
knee_2_x = self.detector.findPosition(img, False)[26][1]
knee_1_y = self.detector.findPosition(img, False)[25][2]
knee_2_y = self.detector.findPosition(img, False)[26][2]
vis_hip_1 = self.detector.findPosition(img, False)[25][4]
vis_hip_2 = self.detector.findPosition(img, False)[26][4]
ankle_1_x = self.detector.findPosition(img, False)[27][1]
ankle_2_x = self.detector.findPosition(img, False)[28][1]
ankle_1_y = self.detector.findPosition(img, False)[27][2]
ankle_2_y = self.detector.findPosition(img, False)[28][2]
if self.form == 0:
angle_1 = self.detector.findIncludedAngle(hip_1_x, hip_1_y, ankle_1_x, ankle_1_y)
angle_2 = self.detector.findIncludedAngle(hip_2_x, hip_2_y, ankle_2_x, ankle_2_y)
if angle_1 < 40 and angle_2 < 40 and eye_1_y > knee_1_y and eye_2_y > knee_2_y:
if self.pre_pos == 1:
if vis_hip_1 > 0.8 and vis_hip_1 > vis_hip_2:
self.time_1 += 1
if self.time_1 > 3:
self.dir = 1
self.sign = 1
self.time_1 = 0
self.form = 1
elif vis_hip_2 > 0.8 and vis_hip_1 < vis_hip_2:
self.time_2 += 1
if self.time_2 > 3:
self.dir = 2
self.sign = 1
self.time_2 = 0
self.form = 1
if self.sign == 1:
self.speak_driver.add_speak("准备开始考试")
threading.Thread(target=self.retail_counting).start()
if self.dir == 1 and self.sign == 1 and self.countdown_flag.is_set():
shoulder_angle = self.detector.findIncludedAngle(hip_1_x, hip_1_y, shoulder_1_x, shoulder_1_y)
ankle_angle = self.detector.findIncludedAngle(ankle_1_x, ankle_1_y, hip_1_x, hip_1_y)
hand_range = self.detector.findRange(elbow_1_x, elbow_1_y, knee_1_x, knee_1_y)
range = self.detector.findRange(hip_1_x, hip_1_y, knee_1_x, knee_1_y) * 0.53
self.per = np.interp(shoulder_angle, (25, 65), (0, 100))
self.bar = np.interp(shoulder_angle, (25, 65), (62, 280))
if ankle_angle < 70:
if self.count >= 1:
if shoulder_angle <= 30:
self.feedback = "上升"
self.state = 0
if self.direction == 0:
self.time += 1
if self.time > 2:
self.count += 0.5
self.direction = 1
self.time = 0
self.speak_state = 0
else:
self.feedback = "上升"
self.state = 0
if self.direction == 0:
self.time += 1
if self.time > 2:
self.count += 0.5
self.direction = 1
self.time = 0
self.speak_state = 0
if shoulder_angle >= 60 and hand_range < range and time.time() - self.last_time > self.interval:
self.feedback = "下落"
if self.state == 0:
if self.direction == 1:
self.time += 1
if self.time > 2:
self.count += 0.5
self.direction = 0
self.time = 0
self.last_time = time.time()
if self.count % 1 == 0:
self.speak_driver.add_speak("{}".format(int(self.count)))
elif self.dir == 2 and self.sign == 1 and self.countdown_flag.is_set():
# 计算各点与腰点角度
shoulder_angle = self.detector.findIncludedAngle(hip_2_x, hip_2_y, shoulder_2_x, shoulder_2_y)
ankle_angle = self.detector.findIncludedAngle(ankle_2_x, ankle_2_y, hip_2_x, hip_2_y)
hand_range = self.detector.findRange(elbow_2_x, elbow_2_y, knee_2_x, knee_2_y)
range = self.detector.findRange(hip_2_x, hip_2_y, knee_2_x, knee_2_y) * 0.53
# 展示进度栏
self.per = np.interp(shoulder_angle, (25, 65), (0, 100))
self.bar = np.interp(shoulder_angle, (25, 65), (62, 280))
if ankle_angle < 70:
if self.count >= 1:
if shoulder_angle <= 30:
self.feedback = "上升"
self.state = 0
if self.direction == 0:
self.time += 1
if self.time > 2:
self.count += 0.5
self.direction = 1
self.time = 0
self.speak_state = 0
else:
self.feedback = "上升"
self.state = 0
if self.direction == 0:
self.time += 1
if self.time > 2:
self.count += 0.5
self.direction = 1
self.time = 0
self.speak_state = 0
if shoulder_angle >= 60 and hand_range < range and time.time() - self.last_time > self.interval:
self.feedback = "下落"
if self.state == 0:
if self.direction == 1:
self.time += 1
if self.time > 2:
self.count += 0.5
self.direction = 0
self.time = 0
self.last_time = time.time()
if self.count % 1 == 0:
engine = pyttsx3.init()
engine.setProperty('rate', 400)
self.speak_driver.add_speak("{}".format(int(self.count)))