Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Backend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
42 changes: 42 additions & 0 deletions Backend/arPoseLandmarks/downward_dog/downward_dog_landmarks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
[
{
"name": "left_shoulder",
"x": 0.43475762009620667,
"y": 0.5846027731895447
},
{
"name": "right_shoulder",
"x": 0.4466809630393982,
"y": 0.5982203483581543
},
{
"name": "left_elbow",
"x": 0.3332710564136505,
"y": 0.7483700513839722
},
{
"name": "right_elbow",
"x": 0.34916260838508606,
"y": 0.7354578375816345
},
{
"name": "left_hip",
"x": 0.6648672223091125,
"y": 0.2121756225824356
},
{
"name": "right_hip",
"x": 0.6585555076599121,
"y": 0.2347366362810135
},
{
"name": "left_knee",
"x": 0.8213318586349487,
"y": 0.516678512096405
},
{
"name": "right_knee",
"x": 0.7963972687721252,
"y": 0.5197720527648926
}
]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
89 changes: 89 additions & 0 deletions Backend/arPoseLandmarks/extract_pose.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import cv2
import mediapipe as mp
import json
import os

print("[INFO] Initializing MediaPipe Pose...")
mp_pose = mp.solutions.pose
pose = mp_pose.Pose(
static_image_mode=True,
model_complexity=1,
min_detection_confidence=0.5,
min_tracking_confidence=0.5
)
mp_drawing = mp.solutions.drawing_utils

# Update video path for Warrior II pose
video_path = "../../CeylonCare/CeylonCare/assets/videos/warrior_ii.mp4" # Relative path
output_image_path = "warrior_ii/warrior_ii.jpg"
output_json_path = "warrior_ii/warrior_ii_landmarks.json"

# Create output directories if they don't exist
os.makedirs(os.path.dirname(output_image_path), exist_ok=True)
os.makedirs(os.path.dirname(output_json_path), exist_ok=True)

if not os.path.exists(video_path):
print(f"[ERROR] Video file not found at: {video_path}")
print("[INFO] Ensure the video is in ../../CeylonCare/CeylonCare/assets/videos/")
exit()

print("[INFO] Loading video...")
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
print("[ERROR] Could not open video.")
exit()

fps = cap.get(cv2.CAP_PROP_FPS)
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
print(f"[DEBUG] Video FPS: {fps}, Total Frames: {total_frames}")

# Adjust target time based on when the Warrior II pose is held in the video
target_time = 5 # Adjust this based on your video
target_frame = int(fps * target_time) if int(fps * target_time) < total_frames else total_frames - 1
print(f"[DEBUG] Targeting frame {target_frame} at {target_time} seconds")
cap.set(cv2.CAP_PROP_POS_FRAMES, target_frame)

success, frame = cap.read()
if not success:
print("[ERROR] Failed to read frame.")
cap.release()
exit()

print("[INFO] Processing frame for pose detection...")
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = pose.process(rgb_frame)

if not results.pose_landmarks:
print("[ERROR] No pose detected.")
cv2.imwrite(output_image_path, frame)
print(f"[DEBUG] Frame saved as {output_image_path}")
cap.release()
exit()

mp_drawing.draw_landmarks(frame, results.pose_landmarks, mp_pose.POSE_CONNECTIONS)
cv2.imwrite(output_image_path, frame)
print(f"[INFO] Frame saved as {output_image_path}")

# Extract landmarks
landmarks = results.pose_landmarks.landmark
correct_pose = [
{"name": "left_shoulder", "x": landmarks[11].x, "y": landmarks[11].y},
{"name": "right_shoulder", "x": landmarks[12].x, "y": landmarks[12].y},
{"name": "left_elbow", "x": landmarks[13].x, "y": landmarks[13].y},
{"name": "right_elbow", "x": landmarks[14].x, "y": landmarks[14].y},
{"name": "left_hip", "x": landmarks[23].x, "y": landmarks[23].y},
{"name": "right_hip", "x": landmarks[24].x, "y": landmarks[24].y},
{"name": "left_knee", "x": landmarks[25].x, "y": landmarks[25].y},
{"name": "right_knee", "x": landmarks[26].x, "y": landmarks[26].y}
]
print("[DEBUG] Extracted landmarks:")
for landmark in correct_pose:
print(f"[DEBUG] {landmark['name']}: x={landmark['x']:.3f}, y={landmark['y']:.3f}")

with open(output_json_path, 'w') as f:
json.dump(correct_pose, f, indent=2)
print(f"[INFO] Landmarks saved to {output_json_path}")

cap.release()
pose.close()
print("[INFO] Script completed!")
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions Backend/arPoseLandmarks/triangle_pose/triangle_pose_landmarks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
[
{
"name": "left_shoulder",
"x": 0.393909215927124,
"y": 0.5337827205657959
},
{
"name": "right_shoulder",
"x": 0.41303548216819763,
"y": 0.4024796485900879
},
{
"name": "left_elbow",
"x": 0.39781999588012695,
"y": 0.6615622043609619
},
{
"name": "right_elbow",
"x": 0.3966938853263855,
"y": 0.2836398184299469
},
{
"name": "left_hip",
"x": 0.50235915184021,
"y": 0.576718270778656
},
{
"name": "right_hip",
"x": 0.5291388630867004,
"y": 0.5406009554862976
},
{
"name": "left_knee",
"x": 0.4347962439060211,
"y": 0.7202959656715393
},
{
"name": "right_knee",
"x": 0.5943127870559692,
"y": 0.698548436164856
}
]
Binary file added Backend/arPoseLandmarks/warrior_ii/warrior_ii.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions Backend/arPoseLandmarks/warrior_ii/warrior_ii_landmarks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
[
{
"name": "left_shoulder",
"x": 0.5757824182510376,
"y": 0.30987370014190674
},
{
"name": "right_shoulder",
"x": 0.48430055379867554,
"y": 0.3139100670814514
},
{
"name": "left_elbow",
"x": 0.650972843170166,
"y": 0.32717323303222656
},
{
"name": "right_elbow",
"x": 0.40994828939437866,
"y": 0.3287721872329712
},
{
"name": "left_hip",
"x": 0.5621575117111206,
"y": 0.5378085374832153
},
{
"name": "right_hip",
"x": 0.5064576864242554,
"y": 0.5383180379867554
},
{
"name": "left_knee",
"x": 0.6146337985992432,
"y": 0.6881082057952881
},
{
"name": "right_knee",
"x": 0.44796282052993774,
"y": 0.6910121440887451
}
]
69 changes: 69 additions & 0 deletions Backend/ar_model/pose_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from flask import Flask, request, jsonify
import cv2
import mediapipe as mp
import base64
import numpy as np
import logging
import traceback

# Set up logging for debugging and error tracking
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

app = Flask(__name__)
mp_pose = mp.solutions.pose

# Initialize MediaPipe Pose model with higher confidence thresholds
pose = mp_pose.Pose(min_detection_confidence=0.7, min_tracking_confidence=0.7)

@app.route('/process_frame', methods=['POST'])
def process_frame():
try:
# Log incoming request
logger.info('[DEBUG] Received request to process frame')

# Get JSON data from request
data = request.json
if not data or 'frame' not in data:
logger.error('[ERROR] Invalid request: Missing frame data')
return jsonify({'error': 'Missing frame data'}), 400

# Extract and log frame data
frame_base64 = data['frame']
logger.debug('[DEBUG] Frame base64 length: %d', len(frame_base64))

# Decode base64 string to image
frame = base64.b64decode(frame_base64)
image = cv2.imdecode(np.frombuffer(frame, np.uint8), cv2.IMREAD_COLOR)
if image is None:
logger.error('[ERROR] Failed to decode image')
return jsonify({'error': 'Failed to decode image'}), 400

# Log image details
logger.debug('[DEBUG] Image decoded, shape: %s', image.shape)

# Convert image to RGB for MediaPipe processing
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
results = pose.process(image_rgb)

# Process pose detection results
if results.pose_landmarks:
landmarks = [
{'name': f'landmark_{i}', 'x': lm.x, 'y': lm.y, 'z': lm.z}
for i, lm in enumerate(results.pose_landmarks.landmark)
]
logger.info('[DEBUG] Pose landmarks detected: %d', len(landmarks))
return jsonify({'landmarks': landmarks})
else:
logger.warning('[WARN] No pose landmarks detected')
return jsonify({'landmarks': []})

except Exception as e:
# Log detailed error information
logger.error('[ERROR] Error processing frame: %s', str(e))
logger.error('[ERROR] Traceback: %s', traceback.format_exc())
return jsonify({'error': str(e)}), 500

if __name__ == '__main__':
logger.info('[INFO] Starting pose detection service on http://0.0.0.0:5002')
app.run(host='0.0.0.0', port=5002, debug=True)
4 changes: 2 additions & 2 deletions Backend/controllers/arController.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const getARRecommendations = async (req, res) => {
console.log(`[DEBUG] Received request to fetch therapy for user: ${userId}`);

try {
const response = await axios.get(`http://localhost:5000/healthData/${userId}`);
const response = await axios.get(`http://192.168.60.22:5000/healthData/${userId}`);
console.log(`[DEBUG] Fetching health data for user: ${userId}, Response status: ${response.status}`);

if (response.status !== 200) {
Expand All @@ -24,7 +24,7 @@ const getARRecommendations = async (req, res) => {
const userHealthData = response.data;
console.log("[DEBUG] Fetched user health data:", JSON.stringify(userHealthData, null, 2));

const flaskResponse = await axios.post("http://localhost:5001/predict", userHealthData);
const flaskResponse = await axios.post("http://192.168.60.22:5001/predict", userHealthData);

console.log("[DEBUG] Flask API Full Response:", JSON.stringify(flaskResponse.data, null, 2));

Expand Down
2 changes: 1 addition & 1 deletion Backend/controllers/chatController.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const getChatRecommendation = async (req, res) => {
console.log(`[DEBUG] User health condition: ${userHealthData.healthCondition || 'general'}`);

// Send chat message and health condition to Flask app
const flaskResponse = await axios.post("http://localhost:5001/chat", {
const flaskResponse = await axios.post("http://192.168.60.22:5001/chat", {
message: userInput,
userId: userId,
healthCondition: userHealthData.healthCondition || "general",
Expand Down
Loading