← All posts

Counting Reps With Angles, Not Guesswork

2024CV · Python

Counting your own reps sounds trivial until you are tired and lose track at nineteen. That was the problem. Not a big problem. Just the kind that makes a good first computer vision project because the feedback loop is immediate and mistakes are obvious.

This project was small on purpose. About eighty lines in one Python file. A webcam, MediaPipe landmarks, OpenCV, and one question. Can joint geometry be enough to detect a push-up reliably.

Turning Motion Into a Counter

The core idea was simple. Track shoulder, elbow, and wrist landmarks. Compute the elbow angle. Use that angle to infer whether I was at the top or bottom of a rep.

The interesting part was not pose detection. It was state. Counting on every frame would explode the rep total. The counter only worked once I treated a push-up as a transition between states instead of a single threshold crossing.

That cooldown logic was tiny, but it changed the project from a demo into something that mostly worked.

What I Learned From the Rough Edges

Hardcoded thresholds were the first limitation I ran into. Ninety and one hundred sixty worked for me. That does not mean they work for everyone. Different form, mobility, and camera placement all matter.

Tracking only one arm was another shortcut. It kept the logic simple, but it also made the system fragile if the arm was occluded or the pose detector drifted. If I rebuilt it, calibration and bilateral tracking would be first.

Lighting also mattered more than I expected. Computer vision feels abstract until a dim room breaks your assumptions.

Small Project, Useful Lesson

What made this project interesting to me was not that it counted push-ups. It was seeing vector math show up in something physical. An angle from three points became a decision. A decision became a rep counter.

It was also one of the first times I felt the difference between code that runs and code that handles messy input. Webcam data is messy. Bodies are inconsistent. That forces better thinking.

What I Would Change

I would not keep it as a monolithic script. I would separate pose detection, counting logic, and calibration. I would add form validation too, because right now unrelated arm motion can trigger false positives.

I would probably keep the simplicity though. Early projects should stay honest. This was not a fitness product. It was me learning how far basic pose estimation could go with very little code.

Sometimes eighty lines are enough to teach the right lesson.

View all projects →View on GitHub ↗