Human detection with Ubiquiti’s UniFi Video and Python

Some months ago, I installed a couple of video cams from Ubiquiti’s UniFi series, and I think they are doing a pretty decent job compared to the price!

I played around with their motion detection settings, and soon realised that I got a shit load of notifications with leafs flying around.. The idea was to get a notification if people entered the camera area, not every other minut on a windy day.

Then I started to look around for alternatives, ofc. there’s an option to buy a camera with an integrated option to capture humans, but why not try to make the software my self? – The cameras are doing a great job, I just needed to write something able to find those humans! 🙂

I asked Google what to do, and found out that Python together with OpenCV could do the job. I have never really programmed anything from the bottom in Python, but hey, how hard could it be?

The goal of the program is the following:

  • Download a screenshot for each cam (looping around)
  • Scan videos for humans
    • If a human is detected
      • Send me an push notification with the image
      • Clean up the temp images
  • Integrate with Home Assistant, do disable notifications if I’m home (can be overwritten)

*NB* The Home Assistant part is not covered in this article *NB*

How does this OpenCV work, and how do we detect humans?

I found this guy Adrian at pyimagesearch, who had a tutorial with Python, OpenCV and something called YOLO (You Only Look Once, not to be compared with You Only Live Once) to detect objects on pictures and videos, and through I could use that.

Pyimagesearch’s YOLO tutorial can be found here
Pyimagesearch’s guide of how to install OpenCV with Python 3 on Ubuntu can be found here

So, I installed OpenCV and Python, and verified the setup with the tutorial-sample.

Access to the Ubiquiti NVR system

Next thing, how do I get the videos from the UniFi system?

The NVR does not save the files local in a structured way, when you access the website or the App, the system assembly the videos for you, so we have to download the videos from the system, to get the entire video.

The NVR have a REST-API, but it’s not very well documented, but after playing around I figured out how it worked.

First of all, create a new user, only to be used for API access, the user should only have “View”-access to the cams, but both “View” and “Edit” access to the recordings. And make sure that “Allow API Usage” is set to on. And copy the API Key – we are going to use that for all API requests.

With the API Key, it’s pretty straight forward, the API URLs are more or less the same, as the URL when browsing around the NVR.

I use Postman to test API calls, but you can use whatever you preferrer (for the Get requests the browser is just fine).

A couple of useful API Calls:

List all cameras:
https://<ubiquiti-nvr-ip>:<port>/api/2.0/camera?apiKey=<apikey>  (Get request)

List all users:
https://<ubiquiti-nvr-ip>:<port>/api/2.0/user?apiKey=<apikey>  (Get request)

List all recordings:
https://<ubiquiti-nvr-ip>:<port>/api/2.0/recording?apiKey=<apikey>  (Get request)

Download recording:
https://<ubiquiti-nvr-ip>:<port>/api/2.0/recording/<recordingid>/download?apiKey=<apikey>  (Get request)

Mark recording as locked:
https://<ubiquiti-nvr-ip>:<port>/api/2.0/recording/<recordingid>?apiKey=<apikey> | JSON encoded body: { “locked”: true } (Put request)

Python time

I’m going to create the following files:

  • getsnaps.py
    • Download screenshot from each camera
  • sendpush.py
    • Send a push message
  • checkha.py
    • Asks Home Assistant if home or not
    • Check if notification should be sent even if home is True
  • snap.py
    • Combine anything, and also do the detection 🙂

Lets start with getsnaps.py:

Then sendpush.py: (I use Pushover to accomplish this)

Next is getting info from HA.
checkha.py:

And now snap.py: (Reference)

And that’s more or less it!

You need to create the following folder:

  • snaps (image folder)

And then, just setup the script as a service, create a new file /etc/systemd/system/snaps.service:

Then reload the daemon, enable, start it and check the status:

You’re done!

Example of the push message:

 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.