Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
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
Пример #4
0
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)
Пример #5
0
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)
Пример #6
0
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
Пример #8
0
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()
Пример #9
0
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()