Inspiration

Many of us spend all day at the computer, and it is easy to develop bad posture and eye strain from staring at the screen. This is made worse because we unconsciously tend to move closer to the screen as we work.

What it does

Using the webcam it performs face detection. If the face is too large (set by the user), aka you are too close to the screen, a notification appears on the screen to remind you to sit up straight and bring your head further from the screen. It is designed to run in the background unseen, and give gentle non-intrusive reminders to sit up straight and not lean into the screen.

How I built it

Face and eye detection are performed by pre-built Haar cascades, which were created using AdaBoost. The size of these features determines whether the user is "too close" to the screen and whether a notification is sent. The system is resilient to either the face or eye features missing. I used opencv to perform the detection, rumps to create the GUI, and threads to link the two.

Challenges I ran into

When the process is running, you cannot easily display the images or annotations generated by the detection. This is because opencv's "imshow()" function can only be called by the main thread. Unfortunately, rumps hijacks the main thread for operating the GUI and I could not find a way to get it back to display images. You cannot start rumps in a thread because the thread "start()" call never returns. Rumps includes a timer function that is called periodically however it spawns a new thread meaning "imshow()" does not work there either. Matplotlib and Pillow's "imshow()" equivalents showed similar failures when being called from a non-main thread. I didn't know whether thread safety was an issue, but in any case I couldn't figure out how put a lock on the images either.

Displaying the images in real time while the process is running is not necessary for the process to be useful. It is an extra feature that would have been useful for debugging in case the system were not working as expected. For now, if you choose to display the images it will open each frame in a new window via Pillow. It is an annoying workaround but will show you live images if you want to see them that badly.

Accomplishments that I'm proud of

The detection is robust over long distances, eyeglasses, partial obstructions, (typical) head orientation changes, and other faces in the background. Personally I find it very effective and hope to keep using and improving upon it.

It is also resource efficient. It uses approximately 70% of one core and less than 100MB of RAM.

What I learned

Basic GUI implementation in Python, openCV, brushed up on my multithreading skills

What's next for Boost Your Posture

Windows and Linux machines. Experimenting with other GUI libraries to avoid the main-thread problem. Reducing CPU usage.

Built With

Share this project:

Updates