def evaluate_angle_per_frame(self, frame, side): if (side == pose.Side.right): # calculate the vector between the required parts upper_arm = pose.Part(frame.relbow, frame.rshoulder) lower_arm = pose.Part(frame.relbow, frame.rwrist) torso = pose.Part(frame.rhip, frame.neck) else: upper_arm = pose.Part(frame.lelbow, frame.lshoulder) lower_arm = pose.Part(frame.lelbow, frame.lwrist) torso = pose.Part(frame.lhip, frame.neck) upper_arm_lower_arm_angle = upper_arm.calculate_angle(lower_arm) upper_arm_torso_angle = upper_arm.calculate_angle(torso) return (upper_arm_lower_arm_angle, upper_arm_torso_angle)
def evaluate_side_bicepcurl(self, frames: List[pose.PoseData]): side = detect_perspective(frames) # Angles to calculate upper_arm_lower_arm_angles = [] upper_arm_torso_angles = [] for frame in frames: if (side == pose.Side.right): upper_arm = pose.Part(frame.relbow, frame.rshoulder) lower_arm = pose.Part(frame.relbow, frame.rwrist) torso = pose.Part(frame.rhip, frame.neck) else: upper_arm = pose.Part(frame.lelbow, frame.lshoulder) lower_arm = pose.Part(frame.lelbow, frame.lwrist) torso = pose.Part(frame.lhip, frame.neck) upper_arm_lower_arm_angle = upper_arm.calculate_angle(lower_arm) upper_arm_torso_angle = upper_arm.calculate_angle(torso) upper_arm_lower_arm_angles.append(upper_arm_lower_arm_angle) upper_arm_torso_angles.append(upper_arm_torso_angle) # use thresholds learned from analysis upper_arm_torso_range = np.max(upper_arm_torso_angles) - np.min( upper_arm_torso_angles) upper_arm_lower_arm_min = np.min(upper_arm_lower_arm_angles) # print('Upper arm and torso angle range: {}'.format(upperarm_torso_range)) # print('Upper arm and forearm minimum angle: {}'.format(upperarm_forearm_min)) correct = True feedback = '' if upper_arm_torso_range > 35.0: correct = False feedback += 'Significant rotation in upper arm while curling\n' if upper_arm_lower_arm_min > 45.0: correct = False feedback += 'Curling not performed all the way to the top\n' if correct: feedback += 'Correctly performed\n' # print('-'*30) # print('Exercise correct: '+str(correct)) # print(feedback) return (correct, feedback)
def evaluate_angle_per_frame(frame, side): # Angles to calculate upperarm_forearm_angles = [] upperarm_torso_angles = [] if (side == pose.Side.right): upperarm = pose.Part(frame.relbow, frame.rshoulder) forearm = pose.Part(frame.relbow, frame.rwrist) torso = pose.Part(frame.rhip, frame.neck) else: upperarm = pose.Part(frame.lelbow, frame.lshoulder) forearm = pose.Part(frame.lelbow, frame.lwrist) torso = pose.Part(frame.lhip, frame.neck) angle1 = upperarm.calculate_angle(forearm) angle2 = upperarm.calculate_angle(torso) upperarm_forearm_angles.append(angle1) upperarm_torso_angles.append(angle2) frame_out = {} # Upper angle frame_out["a1"] = angle1 frame_out["a2"] = angle2 return frame_out
def evaluate_front_bicepcurl(frames): left_upperarm_forearm_angles = [] right_upperarm_forearm_angles = [] left_upperarm_torso_angles = [] right_upperarm_torso_angles = [] for frame in frames: # Define part vector right_upperarm = pose.Part(frame.relbow, frame.rshoulder) right_forearm = pose.Part(frame.relbow, frame.rwrist) left_upperarm = pose.Part(frame.lelbow, frame.lshoulder) left_forearm = pose.Part(frame.lelbow, frame.lwrist) torso = pose.Part(frame.neck, frame.mhip) # Calculate angles between upperarm and forearm as well as upperarm and torso for both side left_angle = left_upperarm.calculate_angle(left_forearm) right_angle = right_upperarm.calculate_angle(right_forearm) left_upperarm_torso_angle = left_upperarm.calculate_angle(torso) right_upperarm_torso_angle = right_upperarm.calculate_angle(torso) # Appned calculated angles to the list defined above left_upperarm_forearm_angles.append(left_angle) right_upperarm_forearm_angles.append(right_angle) left_upperarm_torso_angles.append(left_upperarm_torso_angle) right_upperarm_torso_angles.append(right_upperarm_torso_angle) left_upperarm_torso_range = np.max(left_upperarm_torso_angles) - np.min( left_upperarm_torso_angles) right_upperarm_torso_range = np.max(right_upperarm_torso_angles) - np.min( right_upperarm_torso_angles) left_upperarm_forearm_minm = np.min(left_upperarm_forearm_angles) right_upperarm_forearm_minm = np.min(right_upperarm_forearm_angles) # print("Left forearm and toro range:{}".format(left_upperarm_torso_range)) # print("Left upperarm and forearm min: {}".format (left_upperarm_forearm_minm)) # print('-'*30) # print("Right forearm and upperarm range:{}".format(right_upperarm_torso_range)) # print("Right upperarm and forearm min: {}".format (right_upperarm_forearm_minm)) correct = True feedback = '' if (left_upperarm_torso_range > 35.0): correct = False feedback += "Significant movement of Left Upper Arm" if (right_upperarm_torso_range > 35.0): correct = False feedback += "Significant movement of Right Upper Arm" if left_upperarm_forearm_minm > 45.0: correct = False feedback += 'Left Curling not performed all the way to the top\n' if right_upperarm_forearm_minm > 45.0: correct = False feedback += 'Right Curling not performed all the way to the top\n' if correct: feedback += 'Correctly performed\n' print('-' * 30) print('Exercise correct: ' + str(correct)) print(feedback) return (correct, feedback)
def evaluate_side_shoulderpress(frames: List[pose.PoseData]): side = detect_perspective(frames) upperarm_forearm_angles = [] upperarm_torso_angles = [] back_vectors = [] elbow_neck_x = [] for frame in frames: # IGnore all the 0 confidence frames if (side == pose.Side.right): if (frame.relbow.confidence == 0 or frame.rshoulder.confidence == 0 or frame.rwrist.confidence == 0 or frame.rhip.confidence == 0 or frame.neck.confidence == 0): continue else: if (frame.lelbow.confidence == 0 or frame.lshoulder.confidence == 0 or frame.lwrist.confidence == 0 or frame.lhip.confidence == 0 or frame.neck.confidence == 0): continue if (side == pose.Side.right): upperarm = pose.Part(frame.relbow, frame.rshoulder) forearm = pose.Part(frame.relbow, frame.rwrist) torso = pose.Part(frame.rhip, frame.neck) # Or back # elbow_neck = pose.Part(frame.neck, frame.relbow) back_vectors.append( np.array( [frame.neck.x - frame.rhip.x, frame.neck.y - frame.rhip.y])) elbow_neck_x.append(frame.relbow.x - frame.neck.x) else: upperarm = pose.Part(frame.lelbow, frame.lshoulder) forearm = pose.Part(frame.lelbow, frame.lwrist) torso = pose.Part(frame.lhip, frame.neck) # elbow_neck = pose.Part(frame.lelbow, frame.neck) back_vectors.append( np.array( [frame.neck.x - frame.lhip.x, frame.neck.y - frame.lhip.y])) elbow_neck_x.append(frame.neck.x - frame.lelbow.x) angle1 = upperarm.calculate_angle(forearm) angle2 = upperarm.calculate_angle(torso) upperarm_forearm_angles.append(angle1) upperarm_torso_angles.append(angle2) ##### Angle cleanup ############ upperarm_forearm_angles = np.array(upperarm_forearm_angles) upperarm_forearm_angles = upperarm_forearm_angles[np.logical_not( np.isnan(upperarm_forearm_angles))] upperarm_torso_angles = np.array(upperarm_torso_angles) upperarm_torso_angles = upperarm_torso_angles[np.logical_not( np.isnan(upperarm_torso_angles))] back_vectors = np.array(back_vectors) ### Calculation of required parameters ################# max_upperarm_forearm_angle = np.max(upperarm_forearm_angles) back_vector_range = np.max(back_vectors, axis=0) - \ np.min(back_vectors, axis=0) elbow_x = np.min(elbow_neck_x) # Only x axis print(elbow_x) correct = True feedback = "" if (max_upperarm_forearm_angle < 175): correct = False feedback += "Not lifted upto the top. \n" if (back_vector_range[0] > 0.16): correct = False feedback += "Back shows significant movement. \n" if (elbow_x < -0.12): correct = False feedback += "Shoulders are not steady/parallel. \n" return (correct, feedback)
def _bicep_curl(video): frames = parse_file(video) left_upperarm_forearm_angles = [] right_upperarm_forearm_angles = [] left_refer_angles = [] right_refer_angles = [] dire = ["Upward"] for i, frame in enumerate(frames): if (i == 0): initial_position_left = pose.Part(frame.lelbow, frame.lwrist) initial_position_right = pose.Part(frame.relbow, frame.rwrist) right_upperarm = pose.Part(frame.relbow, frame.rshoulder) right_forearm = pose.Part(frame.relbow, frame.rwrist) left_upperarm = pose.Part(frame.lelbow, frame.lshoulder) left_forearm = pose.Part(frame.lelbow, frame.lwrist) left_refer_angle = initial_position_left.calculate_angle(left_forearm) right_refer_angle = initial_position_right.calculate_angle( right_forearm) left_refer_angles.append(left_refer_angle) right_refer_angles.append(right_refer_angle) left_angle = left_upperarm.calculate_angle(left_forearm) right_angle = right_upperarm.calculate_angle(right_forearm) left_upperarm_forearm_angles.append(left_angle) right_upperarm_forearm_angles.append(right_angle) left_refer_angles = medfilt(left_refer_angles, 11) right_refer_angles = medfilt(right_refer_angles, 11) left_upperarm_forearm_angles = medfilt(left_upperarm_forearm_angles, 11) right_upperarm_forearm_angles = medfilt(right_upperarm_forearm_angles, 11) for i in range(1, len(left_refer_angles)): prev_angle = left_refer_angles[i - 1] current_angle = left_refer_angles[i] if (current_angle - prev_angle > 0): dire.append("Upward") elif (current_angle - prev_angle < 0): dire.append("Downward") else: dire.append("Stationary") feedback = '' reps = 0 for i in range(1, len(dire)): if (dire[i - 1] != dire[i] and dire[i] != dire[i + 1] and dire[i - 1] == dire[i + 1]): dire[i] = dire[i + 1] if (dire[i] == 'Stationary' and dire[i + 1] == "Upward"): reps += 1 print(reps) if (left_upperarm_forearm_angles[i] < 170.0): print("Stretch your arm all the way to bottom") if (dire[i] == 'Stationary' and dire[i + 1] == "Downward"): if (left_upperarm_forearm_angles[i] > 30.0 and left_upperarm_forearm_angles[i] < 160.0): print("Squeeze your arm all the way to top properly") print("Total reps:{}".format(reps)) #Rules left_upperarm_forearm_range = np.max( left_upperarm_forearm_angles) - np.min(left_upperarm_forearm_angles) right_upperarm_forearm_range = np.max( right_upperarm_forearm_angles) - np.min(right_upperarm_forearm_angles) left_upperarm_forearm_minm = np.min(left_upperarm_forearm_angles) right_upperarm_forearm_minm = np.min(right_upperarm_forearm_angles) print("Left forearm and upperarm range:{}".format( left_upperarm_forearm_range)) print( "Left upperarm and forearm min: {}".format(left_upperarm_forearm_minm)) print("Right forearm and upperarm range:{}".format( right_upperarm_forearm_range)) print("Right upperarm and forearm min: {}".format( right_upperarm_forearm_minm)) correct = True feedback = '' if (left_upperarm_forearm_minm > 30.0): correct = False feedback += "Curling not performed all the way to the top"
if is_video_good: video_index = abs(video_index % len(good_videos)) video = good_videos[video_index] side = detect_perspective(video) current_type = "Good" else: video_index = abs(video_index % len(bad_videos)) video = bad_videos[video_index] side = detect_perspective(video) current_type = "Bad" frame = video[index] # Angle if (side == pose.Side.right): upperarm = pose.Part(frame.relbow, frame.rshoulder) forearm = pose.Part(frame.relbow, frame.rwrist) torso = pose.Part(frame.rhip, frame.neck) else: upperarm = pose.Part(frame.lelbow, frame.lshoulder) forearm = pose.Part(frame.lelbow, frame.lwrist) torso = pose.Part(frame.lhip, frame.neck) angle1 = upperarm.calculate_angle(forearm) angle2 = upperarm.calculate_angle(torso) # Reps counter if (start_angle-threshold <= angle1 <= start_angle+threshold): down = True if (down and up): reps += 1 down = False
def visualize_front_vid(path): video = parse_file(path, False) cap = cv.VideoCapture('videos/bicep_8.mp4') if(cap.isOpened()==False): print("Error") i = 0 initial_frame = i start_angle=160 end_angle = 20 threshold = 10 down = False up = False down_exited = False reps = 0 reps_incorrect = 0 while (cap.isOpened()): ret, image = cap.read() frame = video[i] # User input k = cv.waitKey(1) & 0xFF if k == 27: break if ret==False: break if(k == 'p'): cv.waitKey(0) right_upperarm = pose.Part(frame.relbow, frame.rshoulder) right_forearm = pose.Part(frame.relbow, frame.rwrist) left_upperarm = pose.Part(frame.lelbow, frame.lshoulder) left_forearm = pose.Part(frame.lelbow, frame.lwrist) torso = pose.Part(frame.neck, frame.mhip) #Calculate angles between upperarm and forearm as well as upperarm and torso for both side left_angle = left_upperarm.calculate_angle(left_forearm) right_angle = right_upperarm.calculate_angle(right_forearm) left_upperarm_torso_angle = left_upperarm.calculate_angle(torso) right_upperarm_torso_angle = right_upperarm.calculate_angle(torso) #Reps Counter #Lower region if (start_angle-threshold <= left_angle <= start_angle+threshold): down = True if (down and down_exited): # reps += 1 down = False down_exited = False correct, feedback = evaluate_front_bicepcurl(video[initial_frame:i]) if (correct): reps += 1 else: reps_incorrect += 1 initial_frame = i print(reps,feedback) #Upper region if (end_angle-threshold <= left_angle <= end_angle+threshold): up = True #Downward region exit if (down and left_angle<start_angle-threshold): down_exited = True # Drawing cv.putText(image, f"{path} {i}", (250, 20), cv.FONT_HERSHEY_PLAIN, 2, (255, 255, 255), 1) cv.putText(image, f"Left Angle upperarm forearm: {left_angle}", (10, 50), cv.FONT_HERSHEY_PLAIN, 2, (255, 255, 255), 1) cv.putText(image, f"Angle upperarm torso: {right_angle}", (10, 80), cv.FONT_HERSHEY_PLAIN, 2, (255, 255, 255), 1) cv.putText(image, f"Reps: {reps}", (10, 110), cv.FONT_HERSHEY_PLAIN, 2, (0, 255, 0), 1) cv.putText(image, f"Reps incorrect: {reps_incorrect}", (10, 140), cv.FONT_HERSHEY_PLAIN, 2, (0, 0, 255), 1) for name, joint in frame: x = int(joint.x) y = int(joint.y) cv.circle(image, (x, y), 5, (0, 0, 255), -1) # cv.putText(image, name, (x, y-10), cv.FONT_HERSHEY_SIMPLEX, # 0.6, (36, 255, 12), 2) # Update # time.sleep(0.08) i = i+1 cv.imshow('Testing', image) cv.destroyAllWindows()
def visualize_vid(path): # Create a black image #img = np.zeros((600, 1200, 3), np.uint8) # Draw a diagonal blue line with thickness of 5 px # cv.line(img, (0, 0), (511, 511), (255, 0, 0), 5) # cv.circle(img, (447, 63), 63, (0, 0, 255), -1) video = parse_file(path, False) side = detect_perspective(video) index = 0 cap = cv.VideoCapture('videos/bicep_6.mp4') if(cap.isOpened()==False): print("Error") i = 0 # to count the frame initial_frame = i #start of each reps start_angle = 160 #intial position defined end_angle = 40 # final position of arm threshold = 10 down = False #to check whether the arm is in down region up = False #to check whether the arm is in upward region down_exited = False # to check whether arm exited down region reps = 0 # to count the number of reps in exercise reps_incorrect = 0 # to counf the incorrect reps start = False angles = [] frames_elapsed = 0 while(cap.isOpened()): ret, image = cap.read() frame = video[i] # User input k = cv.waitKey(1) & 0xFF if k == 27: break if ret==False: break if(k == 'p'): cv.waitKey(0) # Angle if (side == pose.Side.right): upperarm = pose.Part(frame.relbow, frame.rshoulder) forearm = pose.Part(frame.relbow, frame.rwrist) torso = pose.Part(frame.rhip, frame.neck) else: upperarm = pose.Part(frame.lelbow, frame.lshoulder) forearm = pose.Part(frame.lelbow, frame.lwrist) torso = pose.Part(frame.lhip, frame.neck) angle1 = upperarm.calculate_angle(forearm) angle2 = upperarm.calculate_angle(torso) angles.append(angle1) #Reps counter if (not down_exited and angle1 < start_angle-threshold): print(i) frames_elapsed = 0 down_exited = True if (down_exited): frames_elapsed += 1 if (start_angle-threshold <= angle1 <= start_angle+threshold): if (down_exited and frames_elapsed > 20): print(angle1) # cv.imwrite("frame%d.jpg" % i, image) correct, feedback = evaluate_side_bicepcurl(video[initial_frame:i]) if (correct): reps += 1 else: reps_incorrect += 1 # print(initial_frame,i) # print(feedback) initial_frame = i down_exited = False frames_elapsed = 0 # #Lower region # if (start_angle-threshold <= angle1 <= start_angle+threshold): # down = True # if (down and down_exited): # # reps += 1 # down = False # down_exited = False # start = True # correct, feedback = evaluate_side_bicepcurl(video[initial_frame:i]) # if (correct): # reps += 1 # else: # reps_incorrect += 1 # # print(initial_frame,i) # initial_frame = i # # print(reps,feedback) # # if (down and up): # # reps += 1 # # final_frame = i # # down = False # # up = False # # feedback = evaluate_bicepcurl (video[initial_frame:final_frame]) # # print(feedback) # # initial_frame = i # # #Upper region # # if (end_angle-threshold <= angle1 <= end_angle+threshold): # # up = True # #Downward region exit # if (down and angle1<start_angle-threshold): # down_exited = True # if (start and down and angle1<start_angle-threshold): # # print(i) # print(initial_frame, i) # start = False # index_min = np.argmin(angles[initial_frame:i])+initial_frame # print(initial_frame, index_min) # initial_frame = index_min # Drawing cv.putText(image, f"{path} {index}", (250, 20), cv.FONT_HERSHEY_PLAIN, 2, (255, 255, 255), 1) cv.putText(image, f"Angle upperarm forearm: {angle1}", (10, 50), cv.FONT_HERSHEY_PLAIN, 2, (255, 255, 255), 1) cv.putText(image, f"Angle upperarm torso: {angle2}", (10, 80), cv.FONT_HERSHEY_PLAIN, 2, (255, 255, 255), 1) cv.putText(image, f"Reps: {reps}", (10, 110), cv.FONT_HERSHEY_PLAIN, 2, (0, 255, 0), 1) cv.putText(image, f"Reps incorrect: {reps_incorrect}", (10, 140), cv.FONT_HERSHEY_PLAIN, 2, (0, 0, 255), 1) for name, joint in frame: x = int(joint.x) y = int(joint.y) cv.circle(image, (x, y), 5, (0, 0, 255), -1) # cv.putText(image, name, (x, y-10), cv.FONT_HERSHEY_SIMPLEX, # 0.6, (36, 255, 12), 2) # Update # time.sleep(0.04) i = i+1 cv.imshow('Testing', image) cv.destroyAllWindows()