BenchMetric is a small computer-vision app that analyzes bench press technique from an uploaded video. It uses MediaPipe Pose for landmark detection and OpenCV for frame processing, then produces per-rep metrics and charts in a Streamlit UI.
- Upload
.mp4bench press videos in the browser (Streamlit) - Frame-by-frame analysis (OpenCV + MediaPipe)
- Phase detection:
START / ECCENTRIC / BOTTOM / CONCENTRIC - Per-rep/per-phase metrics:
Duration_s,Velocity_avg,Distance_pxBottom_pause,Asymmetry
- Visual output:
- live preview while analyzing
- metrics table
- velocity / duration charts
- Saves results to
results.csv
- Python 3.10+ (Python 3.11 recommended)
- Dependencies from
requirements.txt
Note: this repo uses
opencv-python-headless(great for Docker and servers without a GUI). If you want to run the non-Streamlit mode withcv2.imshow, you’ll typically wantopencv-pythoninstead.
Install dependencies:
pip install -r requirements.txtRun the Streamlit app:
streamlit run app.pyThen open http://localhost:8501, upload a video, and click Analyze video.
Build the image:
docker build --no-cache -t bench-metric .Run the container:
docker run --rm -p 8501:8501 bench-metricOpen http://localhost:8501.
- Open the app.
- Upload an
.mp4file. - Adjust settings:
- Delay — artificial slowdown (useful for watching the analysis).
- Right mode — analyze the right side (default is left).
- Click Analyze video.
- After it finishes, you’ll see:
- a DataFrame with metrics
- charts
results.csvwritten in the project directory
The CSV is generated automatically after analysis. Columns include:
Repetition— repetition indexPhase— movement phaseDuration_s— phase durationVelocity_avg— average velocity in the phase (px/s)Distance_px— bar path distance in the phase (px)Bottom_pause— bottom pause detected (0/1)Asymmetry— wrist asymmetry detected (0/1)
app.py— Streamlit UI (upload, progress, charts)main.py— video processing loop (OpenCV) + progress reportingpose_module.py— pose logic, phase detection, metrics, CSV exportassets/— sample images and videos
- Video analysis is CPU-bound and runs in a tight loop. Updating the progress bar too frequently can slow things down.
- The code updates progress every few frames. You can tweak
progress_every_n_framesinmain.py. - Some video backends report an unknown frame count (
CAP_PROP_FRAME_COUNTreturns 0). In that case the app can only display a status message (no accurate percentage).
- Ensure the file is a valid
.mp4(H.264 is usually the safest choice).
- In Streamlit/Docker mode the preview is rendered via
st.image. - For desktop window mode, consider switching from
opencv-python-headlesstoopencv-python.

