I built a CCTV network that is comprised of 15 4k cameras, all recording 24x7. Over 20,000 still images per day are analyzed for humans or vehicles via artificial intelligence. When detected, I get a push notification with a snapshot of the object of interest and the camera starts recording at full-resolution for a while. If you're on my property, you're now being recorded by between two and five cameras at a time. All in, this project cost me about $2,600 with no monthly fees.
I've spent the past month putting this system together. I want to document it somewhere and /homedefense
seems like a good fit.
I live in a semi-rural area on about three acres of land surrounded by woods. My house is fairly large, plus I have an outbuilding that functions as my home office and workshop. Being so isolated and unable to keep an eye on the entire property, I've longed been concerned about being a target.
Last year we got symmetrical gigabit fiber to the home in my area. In preparation for it, I built out a robust home network. I have a 48-port PoE Ubiquiti switch in a full rack in my basement. In my outbuilding, I also have a 16-port PoE Ubiquiti switch in a small wall rack. They're interconnected via two runs of direct-burial, multimode fiber I buried 4' deep in 3/4" PVC conduit. Between the house and outbuilding, I have eight Unfi wifi access points installed. In my main rack I also have a Synology NAS, Intel NUC that's a Docker host, and a Ubiquiti Security Gateway Pro.
On my Intel NUC, I run about a dozen Docker containers. Most notably is: Home Assistant, Mosquito MQTT broker, Grafana, InfluxDB, and Plex.
has an excellent video
that was my jumping off point. I recommend that you watch his video first before reading the rest of this post, since it will help with context.
I am using fifteen of these Annke 4k turrent IP cameras
. The top-rated review is super helpful. These are rebranded Hikvision DS-2CD2383G0-I cameras for half the cost. The initial config is a bit tedious though:
- Connect my notebook to my security camera VLAN.
- Plug the camera into the switch and it powers on via PoE.
- "Activate" the camera with SADPTool.exe (a Annke tool that uses some sort of layer-3 protocol to discover the camera and set it's initial password, which is why my PC and the camera has to be on same layer-2 network (VLAN) for the initial setup.).
- Note the IP address listed in SADPTool and login with "admin" and the password via the web interface.
- Upload the new Hikvision firmware
- When it reboots, the camera has a static IP of 192.168.1.64. So I have to manually set my PC to 192.168.1.63 (or whatever) and log back in to the camera and change it to DHCP. It reboots again.
- Tweak the video feed settings.
The picture quality is absolutely amazing. They'll push 4k video at 15 fps on the main stream. Excellent resolution and (more importantly) dynamic range. The night-vision IR emitter is also really good.
Using the full resolution, quality and framerate on the main stream and similar settings on the 640x480 substream, results in a sustained rate of about 19 mb/s. This is why wired cameras are way
better than wi-fi based ones. I mean, the camera needs a wire for power anyway, right? Why not just use one wire for both data and power?
- The drill template is helpful but don't peel off the adhesive backing, just hold it up to the wall.
- DO NOT USE A CORDLESS SCREW GUN (DRILL). The screws are both cheaply made and go in slightly askew into the camera base. You will strip the heads super fast. I had to use left-handed drill bits to extract broken screws more than once before I stopped trying. Make sure you drill an appropriately-sized pilot hole first and then use a plain 'ole screwdriver.
- Loosen the tiny set screw a bit on the turret to make it a lot easier to rotate into the correct position.
- Read the directions on how to assemble the waterproof cable sleeve. I also wrapped each connector with self-adhesive silicone tape for extra protection.
- I used UV-resistant Cat6 on runs where the cable would be exposed outdoors and standard Cat6 when I was mounting the camera directly over the hole in the exterior wall.
- I have quite a bit of experience doing low-voltage cabling, but if you've never fished cable, watch some YouTube videos on how to do it. 80% of it is having the right tools. Fiberglass poles (Wire Noodler) are a god send.
- Crimp an RJ45 connector on the camera end and punch down the other end into a patch panel. Use pass-through RJ45 connectors and crimp tool--they're about 100x easier to use than traditional plugs. And use a real punchdown tool/cutter on the patch panel. Again, YouTube is a great place to get some basics down.
- When putting cable through an exterior wall, make sure you use drip loops on the outside and service loops on the inside.
- If you have to fish cable through walls, also pull a length of pull line through the path. Leave the pull line in the wall so you don't have to refish the path in the future if you want to run another cable. You'll thank your past self. Next time you pull a cable, you just tie the cable + a new pull line and pull them both through the pathway with the old pull line. You then leave the new pull line in the wall again. There's probably a Youtube video out there if I succeeded in confusing my description.
- A trick that I haven't seen elsewhere: I use 3M packing tape to attach cables to pull lines, fish tapes, and fish poles. It's strong, slippery, thin, and cheap.
- Cameras should be installed between 8' and 10' off the ground in most cases to better capture faces. Most of mine are 9'-ish, mainly dictated by where I needed the cable to enter the building (into the attic most of the time).
- Exceptions: My front door camera is located about a foot above the doorbell and I have another camera pointed at that door camera (180 degrees from the other direction) that is about 14' high in my porch gable.
- Some of my cameras are intentionally very conspicuous (like the front door) as a deterrent. I often overlap coverage with another camera that is more hidden in case someone tampers with the visible camera. This is especially true for cameras covering exterior entrances and first floor windows. This double coverage also allows me to capture faces both coming and going.
- I have a couple of standalone IR emitters that are equipped with a photocell to automatically turn on in low light. They're $15-30 on Amazon and work really well for extending the camera ranges at night.
I really wanted to stick with open source software on this project. Not because of cost but because of flexibility. I tried both Shinobi and ZoneMinder and, unfortunately, neither of them hold a candle to BlueIris. BlueIris just works and works well.
Another issue: I couldn't easily containerize BlueIris and run it under Docker on my Intel NUC. So I ended up buying another NUC (#NUC8v7PNK) with the fastest processor I could find. I then put 32 GB of RAM in it and Windows Server 2019 on a 1TB SSD and installed BlueIris. With 15 cameras and direct-to-disk recording, my CPU utilization is typically 20-30%. Not bad considering it's constantly downloading 260 mb/s worth of video feeds. DarkBunnySC
goes into a lot of detail on how to configure Blue Iris in the above-mentioned video so I won't be redundant. I'm using the same config: record all substreams 24x7 and have them trigger motion alerts, record full-resolution video on manual triggers from the artificial intelligence application.
Artificial Intelligence (AI) Object Classification
The problem is that getting notified every time there's movement on a camera would be rage-inducing. So I need a way to filter out leaves blowing, rain, etc. and only alert me when an actual person or vehicle is detected. DarkBunnySC
got this working using two pieces of software:
- DeepStack -- This the system that does the actual analysis of the images. It's completely self-contained (no cloud component), open source, free, and super simple to use. Using a RESTful API, it takes an input of a JPEG and outputs a list of objects it sees in the image. I run this in a Docker container on my original NUC. It takes about 350 ms to analyze a 4k resolution image in "HIGH" mode.
- AI bridge -- A tiny Windows-based application that functions as "glue" between BlueIris and DeepStack. BlueIris is configured to create a bunch of still images from video when motion is detected, this application grabs these stills and feeds them into DeepStack, and processes the results. Simple in theory, but was pretty terrible for me.
Where things start to diverge...
The problem with DarkBunnySC
's solution in my situation became apparent on very windy days we've had recently. This caused a lot
of motion events to occur constantly. This absolutely smoked my BlueIris server because it couldn't keep up with extracting multiple JPEGs per second from 15 4k video feeds.
So I configured BlueIris to stop creating JPEGs on motion events and set it to publish to a MQTT topic instead. And then I wrote a Python application to listen for MQTT events and grab still images directly from each camera. Problem solved. I've also expanded my Python app to include additional functionality not available in the AI bridge tool:
- Save image data offsite in Amazon S3 for archival purposes and/or someone destroys my home gear.
- On each motion event grab five still images, a half a second apart, analyze each for a person or vehicle. Send a push notification to my phone (via Pushover) containing the best matching image.
- I'm performing the object recognition on the full 4k resolution images, rather than the 640x480 snapshots BlueIris was creating from the low resolution camera substream. I should be able to correctly identify objects much further away from the camera.
- Grab events off the MQTT wire and log them in InfluxDB. Use Grafana to browse real-time and historical charts of what objects are detected on what cameras and when, the confidence levels of various detected objects, etc.
- I'm beginning to experiment with the facial recognition part of Deep Stack. The goal would be to ignore alerts when recognized faces are found, automatically unlock my smart door locks, etc.