Okay, so I was playing around with some real-time people counting stuff for local businesses, and let me tell you, it was a bit of a journey. Here’s how it all went down.
The Initial Idea
It all started when a buddy of mine who owns a small coffee shop was complaining about not knowing when his peak hours were. He was like, “Dude, I’m guessing when to staff up! There’s gotta be a better way.” That got me thinking – real-time people counting. Simple enough, right?
Picking the Hardware
First thing’s first, I needed a camera. I had an old Raspberry Pi lying around, so I figured I could hook up a USB camera to it. I grabbed a cheap one off Amazon, nothing fancy. Then, I needed a place to mount it. Ended up 3D printing a little enclosure to keep it protected and pointed downwards at the entrance.
Setting Up the Software
This is where things got interesting. I decided to use OpenCV for the image processing. I’ve messed with it before, but never for anything real-time. So, I installed OpenCV on the Raspberry Pi. Then, the fun began: coding.
- Background Subtraction: I started with background subtraction. Basically, the script learns the background of the image (the empty store) and then detects anything that moves differently.
- Motion Detection: I used Gaussian Mixture-based Background/Foreground Segmentation Algorithm, `*2()`. Tweaked the history and varThreshold parameters until it was somewhat reliable.
- Blob Detection: After getting the foreground mask, I used some morphological operations (erosion and dilation) to clean up the noise. Then, I found contours to identify blobs representing people.
- Counting Logic: This was tricky. I set up a virtual line in the frame. When a blob crossed that line, it incremented a counter. I had to be careful to only count each person once, so I tracked their direction of movement and made sure they weren’t counted again if they moved back across the line.
Dealing with Challenges
Oh boy, there were challenges. Shadows were a huge problem. Sunlight changing would trigger the motion detection like crazy. I tried different threshold values and tweaked the background subtraction parameters to minimize this, but it was never perfect.
Another issue was people stopping in the doorway. The script would sometimes count them multiple times or not at all. I added some logic to ignore blobs that stayed in the doorway area for too long.
Sending the Data
Once I had a semi-reliable count, I needed to send the data somewhere useful. I decided to use MQTT to send the counts to a central server. I set up a Mosquitto MQTT broker on a separate machine. The Raspberry Pi would publish the people count every minute.
Visualizing the Data
On the server side, I used Node-RED to subscribe to the MQTT topic and store the counts in a simple SQLite database. Then, I built a basic dashboard using Node-RED’s dashboard nodes to display the hourly and daily counts. Nothing fancy, but it got the job done.
Testing and Tweaking
I set it up in my buddy’s coffee shop for a week and watched the data. Turns out, my script was overcounting by about 10-15%. I spent a few more evenings tweaking the parameters and adjusting the counting logic. Things like minimum blob size and line position made a big difference.
The Result
After a couple of weeks of tinkering, I had a system that was reasonably accurate. My buddy could finally see his peak hours and adjust his staffing accordingly. He even used the data to optimize his menu board placement. It was pretty cool to see something I built actually making a difference for his business.
Lessons Learned
This project taught me a ton about OpenCV, real-time processing, and the challenges of computer vision in the real world. Shadows are evil, and getting accurate counts is harder than it looks. But hey, it was a fun project, and I learned a lot along the way. Plus, I helped out a friend. Can’t beat that.