bowling-analysis-system
Version:
A comprehensive system for analyzing bowling techniques using video processing and metrics calculation
114 lines (92 loc) • 4.05 kB
JavaScript
/**
* @module core/metrics/EventPositions
* @description Calculate event positions from valid frames
*/
const { findFrameIndexByEvent } = require('../utils/FrameUtils');
/**
* Calculate positions at key events
* @param {Array} validFrames - Array of valid frames
* @param {Object} events - Detected events
* @returns {Object} Position metrics
*/
function calculateEventPositions(validFrames, events) {
const positions = {};
console.log('Starting event positions calculation');
console.log(`Valid frames: ${validFrames.length}`);
console.log('Events:', Object.keys(events).join(', '));
// Calculate positions at release point
if (events.releasePoint && validFrames.length > 0) {
console.log('Found release point event');
const releaseIndex = events.releasePoint.frameIndex;
console.log(`Release index: ${releaseIndex}`);
// Find the release frame or the closest frame to it using the centralized utility
const releaseFrameIndex = findFrameIndexByEvent(validFrames, events.releasePoint, 'index');
if (releaseFrameIndex >= 0) {
console.log(`Release frame index in validFrames: ${releaseFrameIndex}`);
// Get the frame data
const frame = validFrames[releaseFrameIndex];
// Calculate release position
if (frame.pose_landmarks && frame.pose_landmarks[0]) {
const landmarks = frame.pose_landmarks[0];
// Check if we have all required landmarks
if (landmarks[0] && landmarks[11] && landmarks[12] && landmarks[15] && landmarks[16]) {
console.log('All required landmarks are present');
// Get the wrist position (average of left and right wrists)
const leftWrist = landmarks[15];
const rightWrist = landmarks[16];
positions.releasePosition = {
x: (leftWrist[0] + rightWrist[0]) / 2,
y: (leftWrist[1] + rightWrist[1]) / 2,
z: (leftWrist[2] + rightWrist[2]) / 2
};
// Get the head position
const head = landmarks[0];
positions.headPosition = {
x: head[0],
y: head[1],
z: head[2]
};
// Get the shoulder position (average of left and right shoulders)
const leftShoulder = landmarks[11];
const rightShoulder = landmarks[12];
positions.shoulderPosition = {
x: (leftShoulder[0] + rightShoulder[0]) / 2,
y: (leftShoulder[1] + rightShoulder[1]) / 2,
z: (leftShoulder[2] + rightShoulder[2]) / 2
};
}
}
} else {
console.log('No valid release frame found');
}
}
// Calculate positions at foot landing
if (events.frontFootLanding && validFrames.length > 0) {
// Similar approach using findFrameIndexByEvent for front foot landing
const landingFrameIndex = findFrameIndexByEvent(validFrames, events.frontFootLanding, 'index');
if (landingFrameIndex >= 0) {
const frame = validFrames[landingFrameIndex];
// Calculate foot position
if (frame.pose_landmarks && frame.pose_landmarks[0]) {
const landmarks = frame.pose_landmarks[0];
// Check if we have foot landmarks
if (landmarks[27] && landmarks[28]) {
// Get the foot position (average of left and right ankles)
const leftAnkle = landmarks[27];
const rightAnkle = landmarks[28];
positions.footPosition = {
x: (leftAnkle[0] + rightAnkle[0]) / 2,
y: (leftAnkle[1] + rightAnkle[1]) / 2,
z: (leftAnkle[2] + rightAnkle[2]) / 2
};
}
}
}
}
console.log('Finished event positions calculation');
console.log('Position metrics:', Object.keys(positions).join(', '));
return positions;
}
module.exports = {
calculateEventPositions
};