LISHUZUOXUN_yangjiang/Exercise3/sit_up_new.py

327 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.

from copy import deepcopy
import numpy as np
from MCamera.mp_algorithm import MediapipeAlgorithmPlugin
from MCamera.mp_camera import MP_RESULT
from MCamera.camera import *
from Speaker.speak_base import beep
from Database.manager_database import *
from score_doc import get_fin_score
from .base_exercise import BaseExercise
class SitUp_New(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.range = 0
self.count = 0
# 当前状态
self.hand_state = 0
self.direction = 0
self.countdown = 120
self.pre_pos = 0
self.speak_state = 0
self.state = 0
# 初始化
self.initial_palm_1_y = 0
self.initial_palm_1_x = 0
self.initial_palm_2_x = 0
self.initial_palm_2_y = 0
self.initial_torso_1 = 0
self.initial_torso_2 = 0
self.distance = 24
# 动作持续帧数
self.time = 0
self.time_1 = 0
self.time_2 = 0
# 开始标志
self.form = 0
# 状态反馈
self.feedback = "开始"
self.sign = 0
self.state = 0
# 目标朝向
self.dir = 0
self.exercise_type = "仰卧起坐"
# 仰卧起坐参数
self.corner = (160, 460, 120, 500)
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
}
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.isSet()
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)
self.speak_driver.add_speak(f"时间到,考试结束")
self.is_start = False
def display(self, img):
if self.dir == 1 and self.sign == 1 and self.countdown_flag.is_set():
self.detector.drawPoint(img, 11, 19, 25, bias_x=120, bias_y=160)
elif self.dir == 2 and self.sign == 1 and self.countdown_flag.is_set():
self.detector.drawPoint(img, 12, 20, 26, bias_x=120, bias_y=160)
cv2.rectangle(img, (self.corner[2], self.corner[0]), (self.corner[3], self.corner[1]), (0, 255, 0), 2)
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 len(lm_list) != 0:
palm_1_x = self.detector.findPosition(img, False)[19][1]
palm_1_y = self.detector.findPosition(img, False)[19][2]
palm_2_x = self.detector.findPosition(img, False)[20][1]
palm_2_y = self.detector.findPosition(img, False)[20][2]
hip_1 = self.detector.findAngle(img, 11, 23, 25, False)
hip_2 = self.detector.findAngle(img, 12, 24, 26, False)
knee_1 = self.detector.findAngle(img, 23, 25, 27, False)
knee_2 = self.detector.findAngle(img, 24, 26, 28, False)
arm_1 = self.detector.findAngle(img, 11, 13, 15, False)
arm_2 = self.detector.findAngle(img, 12, 14, 16, False)
torso_1 = self.detector.findAngle(img, 11, 23, 29, False)
torso_2 = self.detector.findAngle(img, 12, 24, 30, False)
vis_wrist_1 = self.detector.findPosition(img, False)[15][4]
vis_wrist_2 = self.detector.findPosition(img, False)[16][4]
if self.pre_pos == 0:
self.pre_pos = 1
self.speak_driver.add_speak("请进入准备状态")
if self.form == 0:
if (torso_1 >= 160 and arm_1 >= 160 and 60 <= knee_1 <= 110) or (
torso_2 >= 160 and arm_2 >= 160 and 60 <= knee_2 <= 110):
if self.pre_pos == 1:
if vis_wrist_1 > 0.8:
self.time_1 += 1
if self.time_1 > 3:
self.dir = 1
self.sign = 1
self.time_1 = 0
self.form = 1
self.initial_palm_1_y = palm_1_y
self.initial_palm_1_x = palm_1_x
elif vis_wrist_2 > 0.8:
self.time_2 += 1
if self.time_2 > 3:
self.dir = 2
self.sign = 1
self.time_2 = 0
self.form = 1
self.initial_palm_2_y = palm_2_y
self.initial_palm_2_x = palm_2_x
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():
self.per = np.interp(hip_1, (90, 140), (100, 0))
self.bar = np.interp(hip_1, (90, 140), (62, 280))
if self.count >= 1:
if 140 <= arm_1 and 160 <= torso_1:
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.distance = 25
self.speak_state = 0
self.initial_palm_1_x = palm_1_x
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.distance = 25
self.speak_state = 0
if self.initial_palm_1_x - self.distance >= palm_1_x and torso_1 <= 160:
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
if self.count % 1 == 0:
self.speak_driver.add_speak("{}".format(int(self.count)))
if self.initial_palm_1_y - 30 > palm_1_y:
self.time += 1
if self.time > 3:
self.state = 1
self.time = 0
if self.speak_state == 0:
self.speak_driver.add_speak('手过高')
self.speak_state = 1
# elif knee_1 < 45:
# self.time += 1
# if self.time > 3:
# self.time = 0
# if self.speak_state == 0:
# self.speak_driver.add_speak('膝部角度过小')
# self.speak_state = 1
# elif knee_1 > 130:
# self.time += 1
# if self.time > 3:
# self.time = 0
# if self.speak_state == 0:
# self.speak_driver.add_speak('膝部角度过大')
# self.speak_state = 1
# elif arm_1 < 90:
# self.time += 1
# if self.time > 3:
# self.time = 0
# if self.speak_state == 0:
# self.speak_driver.add_speak('手未伸直')
# self.speak_state = 1
elif self.dir == 2 and self.sign == 1 and self.countdown_flag.is_set():
self.per = np.interp(hip_2, (90, 140), (100, 0))
self.bar = np.interp(hip_2, (90, 140), (62, 280))
if 140 <= arm_2 and 160 <= torso_2:
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.distance = 25
self.speak_state = 0
self.initial_palm_2_x = palm_2_x
if self.initial_palm_2_x + self.distance <= palm_2_x and torso_2 <= 160:
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
if self.count % 1 == 0:
self.speak_driver.add_speak("{}".format(int(self.count)))
if self.initial_palm_2_y - 30 > palm_2_y:
self.time += 1
if self.time > 3:
self.state = 1
self.time = 0
if self.speak_state == 0:
self.speak_driver.add_speak('手过高')
self.speak_state = 1
# elif knee_2 < 60:
# self.time += 1
# if self.time > 3:
# self.time = 0
# if self.speak_state == 0:
# self.speak_driver.add_speak('膝部角度过小')
# self.speak_state = 1
# elif knee_2 > 110:
# self.time += 1
# if self.time > 3:
# self.time = 0
# if self.speak_state == 0:
# self.speak_driver.add_speak('膝部角度过大')
# self.speak_state = 1
# elif arm_2 < 140:
# self.time += 1
# if self.time > 3:
# self.time = 0
# if self.speak_state == 0:
# self.speak_driver.add_speak('手未申直')
# self.speak_state = 1