File size: 4,752 Bytes
a942a5f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
from flask import Flask, request, jsonify
import os
import tensorflow as tf
import tensorflow_hub as hub
import numpy as np
import cv2

app = Flask(__name__)

# Define constants or parameters
min_kick_angle = 30  # Minimum angle for the leg to be considered a kick
frame_window = 10  # Number of frames to consider for action recognition
kick_counter = 0
highest_kick_frame = -1  # Initialize the frame number of the highest kick
highest_kick_knee = None  # Initialize coordinates of the knee for the highest kick
highest_kick_hip = None  # Initialize coordinates of the hip for the highest kick

# Initialize variables for action recognition
frame_buffer = []

# Load the MoveNet model for pose estimation from TensorFlow Hub
model = hub.load("https://tfhub.dev/google/movenet/singlepose/thunder/4")
pose_net = model.signatures['serving_default']

# Define upload folder for video files
UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = {'mp4'}
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

# Function to detect front kick based on keypoints
def detect_front_kick_func(keypoints, frame_number):
    keypoints_array = keypoints[0]  # Get the NumPy array from the list

    right_hip = keypoints_array[0, 0, 8, :]  # Right hip is at index 8
    right_knee = keypoints_array[0, 0, 9, :]  # Right knee is at index 9

    # print(right_hip, ' ', right_knee)
    if right_knee[2] < 0.4 and right_hip[2] < 0.4:
        return False, -1, None, None

    angle = np.arctan2(right_knee[1] - right_hip[1], right_knee[0] - right_hip[0]) * 180 / np.pi

    if angle > min_kick_angle:
        return True, frame_number, right_knee, right_hip
    else:
        return False, -1, None, None

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS


@app.route('/detect_front_kick', methods=['POST'])
def detect_front_kick():
    try:
        # Check if the 'video' field is in the request
        if 'video' not in request.files:
            return jsonify({'error': 'No video file provided'})

        video_file = request.files['video']

        # Check if the file has the allowed extension
        if not allowed_file(video_file.filename):
            return jsonify({'error': 'Invalid file format. Only MP4 videos are allowed.'})

        # Save the video file to the upload folder with a secure name
        video_filename = (video_file.filename)
        video_filepath = os.path.join(app.config['UPLOAD_FOLDER'], video_filename)
        video_file.save(video_filepath)

        # Open the video file for processing
        cap = cv2.VideoCapture(video_filepath)

        # Check if the video file was opened successfully
        if not cap.isOpened():
            return jsonify({'error': 'Failed to open video file.'})

        frame_number = 0  # Initialize frame number

        while True:
            ret, frame = cap.read()

            if not ret:
                break

            # Preprocess the frame (resize, normalize, denoise, etc.)

            # Perform pose estimation using MoveNet
            resized_frame = cv2.resize(frame, (256, 256))
            image = tf.constant(resized_frame, dtype=tf.int32)
            image = tf.expand_dims(image, axis=0)

            # Run model inference
            outputs = pose_net(image)
            keypoints = outputs['output_0'].numpy()

            # Append the keypoints to the frame buffer
            frame_buffer.append(keypoints)

            # Maintain a sliding window of frames for action recognition
            if len(frame_buffer) > frame_window:
                frame_buffer.pop(0)

            # Perform action recognition using the frame buffer
            if len(frame_buffer) == frame_window:
                is_kick, frame_with_kick, knee, hip = detect_front_kick_func(frame_buffer, frame_number)

                if is_kick:
                    kick_counter += 1
                    if frame_with_kick > highest_kick_frame:
                        highest_kick_frame = frame_with_kick
                        highest_kick_knee = knee
                        highest_kick_hip = hip

            frame_number += 1

        cap.release()

        response_data = {
            'kick_counter': kick_counter,
            'highest_kick_frame': highest_kick_frame,
            'highest_kick_knee': highest_kick_knee.tolist() if highest_kick_knee is not None else None,
            'highest_kick_hip': highest_kick_hip.tolist() if highest_kick_hip is not None else None,
        }

        return jsonify(response_data)

    except Exception as e:
        return jsonify({'error': str(e)})

@app.route('/home', methods=['GET'])
def homie():
    return jsonify({"message":"none"})


if __name__ == '__main__':
    app.run(debug=True)