LISHUZUOXUN_yangjiang/Exercise3/sit_up_new.py

327 lines
14 KiB
Python
Raw Normal View History

2024-09-23 14:54:15 +08:00
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