August 17, 2018

Hikvision ANPR, Part 2

If you're folllowing on from [my previous post] ( you'll have your ANPR camera mounted and recording numberplates, however you've no way to integrate it into anything.

What do to?

There are a couple of ways of getting the number plate info:

The fastest way is to go with option 3, it also means that thanks to a handy utility called incron you don't have to poll the filesystem every x seconds - the filesystem will actually alert your script of a new plate file.


  1. Linux server (I used a low specced local esx ubuntu 18.04 vm)
  2. Incron installed (apt install incron)
  3. FTP server setup (vsftpd

Initially I wanted to use my Synology NAS as the ftp target as that seem to make the most sense, however, the NAS runs on busybox installing addional programs (aka incron) is a little tricky.. seeing that I store a lot of important data on there I didn't want to risk bricking the os. So I created a vm in my virtualisation enviroment and installed the Requirements above (a Raspberry Pi would work equally well.. but everyone loves servers right!).

Setting up incron is very easy, simply run:

incrontab -e

and then enter:

/home/anpr_user/plates IN_CREATE python /home/anpr_user/

Make sure to replace the file paths for the correct values. The IN_CREATE operator simply tells incron to watch the specified directory for newly created files and then to run the proceeding command.

My python script is as follows:

from slackclient import SlackClient
import re
import os
import shutil
from time import gmtime, strftime
import mysql.connector

# slack setup
slack_token = "token-here"
sc = SlackClient(slack_token)

# sql setup
db = mysql.connector.connect(
    host = "host",
    user = "user",
    passwd = "password",
    database = "db"
cursor = db.cursor()

######## Alert methods
def storeSQL(plate, time):
    sql = "INSERT INTO seen_plates (plate, datetime) VALUES (%s, %s)"
    val = (plate, time)
    cursor.execute(sql, val)

def sendSlack(msg):

######## Parse Plates 
files = []
path = "/home/infra/Plates/"
files = os.listdir(path)

for f in files:
    plate = re.match("(.*?)_",f).group() # gets plate from filename
    plate = plate.replace("_","")
    current_time = strftime("%H:%M:%S %Y-%m-%d", gmtime())
    storeSQL(plate, current_time)
    sendSlack("Plate detected: " + plate + " at: " + current_time)
    shutil.copy(path + f, "/home/infra/Plate_repo/" + f)
    os.remove(path + f) # Delete plate record

It simply uses regex to parse the plate from the file name and then grabs the current system time (could use the filename time, but figured system time was close enough). Currently it then feeds the info into a sql db and posts to a slack channel.

In the future I'm going to build the backend, I may stick with SQL or move to something like Splunk.. we shall see.

  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket