Tag Archives: camera

Getting OpenALPR Working on RPi

As yet another side project I wanted to make use of my RPi camera + ANPR software to try and track down whoever is fly-tipping in my local estate. Since they dump their rubbish basically in full view of my living room, I’m looking to catch them in the act.

Attempt 1 – using the Raspbian packages (spoiler alert, it didn’t work)

Boring package install

sudo apt install openalpr openalpr-daemon openalpr-utils libopenalpr-dev
pip3 install openalpr picamera numpy
sudo apt-get install libatlas-base-dev

Get a test image wget http://plates.openalpr.com/ea7the.jpg

alpr -c us ea7the.jpg
Error opening data file /usr/share/openalpr/runtime_data/ocr/lus.traineddata
Please make sure the TESSDATA_PREFIX environment variable is set to your "tessdata" directory.
Failed loading language 'lus'
Tesseract couldn't load any languages!
Segmentation fault

Not good – so this is based on tesseract in the background. Looking around I see that the training data lives in tessdata, which is a subdirectory of ocr

/usr/share/openalpr/runtime_data/ocr/tessdata $ ls
lau.traineddata leu.traineddata lgb.traineddata lkr2.traineddata lkr.traineddata lsg.traineddata lus.traineddata
pi@raspberrypi:/usr/share/openalpr/runtime_data/ocr/tessdata $ mv ./* ../
pi@raspberrypi:/usr/share/openalpr/runtime_data $ tesseract --tessdata-dir /usr/share/openalpr/runtime_data/ocr/ --list-langs
Please make sure the TESSDATA_PREFIX environment variable is set to your "tessdata" directory.
List of available languages (7):
lau
leu
lgb
lkr
lkr2
lsg
lus

Ok, still not really making sense. Lets assume that OpenALPR is putting wrappers around the language so “us” becomes “lus” when fed to tesseract

pi@raspberrypi:/usr/share/openalpr/runtime_data/ocr $ tesseract -l lus ~/ea7the.jpg ./openalpr/runtime_data/config/us.conf
Error, could not create TXT output file: No such file or directory

Now that is more promising

alpr -c us ea7the.jpg
plate0: 10 results
- EA7THE confidence: 91.0578
- EA7TBE confidence: 84.133
- EA7T8E confidence: 83.0083
- EA7TRE confidence: 82.7869
- EA7TE confidence: 82.5961
- EA7TME confidence: 80.2908
- EA7TH6 confidence: 77.0045
- EA7THB confidence: 75.5779
- EA7TH confidence: 74.6576
- EA7TB6 confidence: 70.0797

Now lets take our python bindings for a spin

Python 3.7.3 (default, Dec 20 2019, 18:57:59)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
import json
from openalpr import Alpr
alpr = Alpr("us", "/etc/openalpr/openalpr.conf", "/usr/share/openalpr/runtimedata")
Traceback (most recent call last):
File "", line 1, in
File "/home/pi/.local/lib/python3.7/site-packages/openalpr/openalpr.py", line 91, in init
self._initialize_func = self._openalprpy_lib.openalpr_init
File "/usr/lib/python3.7/ctypes/init.py", line 369, in getattr
func = self.getitem(name)
File "/usr/lib/python3.7/ctypes/init.py", line 374, in getitem
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: /usr/lib/libopenalpr.so.2: undefined symbol: openalpr_init

Much Google time later and it seems that this is down to the pre-build python bindings not matching the version of the package that I’ve installed. Fsck it anyway

pi@raspberrypi:~/.local/lib/python3.7/site-packages $ pip3 show openalpr
Name: openalpr
Version: 1.1.0
Summary: OpenALPR Python Bindings
Home-page: http://www.openalpr.com/
Author: Matt Hill
Author-email: [email protected]
License: UNKNOWN
Location: /home/pi/.local/lib/python3.7/site-packages
Requires:
Required-by:

Attempt 2 – Build from master

Use git to clone from the master

Install the required packages

sudo apt-get install build-essential
sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install libopencv-dev libtesseract-dev git cmake build-essential libleptonica-dev
sudo apt-get install libcurl4-openssl-dev
sudo apt-get install liblog4cplus-dev

Build and install OpenAPNR and the python bindings

cd openalpr/src
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_INSTALL_SYSCONFDIR:PATH=/etc ..
make
sudo make install
cd ../bindings/python
sudo python3 setup.py install

Now we can make progress

pi@raspberrypi:~ $ python3
Python 3.7.3 (default, Dec 20 2019, 18:57:59)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import locale
>>> locale.setlocale(locale.LC_ALL, 'C')
'C'
>>> from openalpr import Alpr
>>> alpr = Alpr("us", "/etc/openalpr/openalpr.conf", "/usr/share/openalpr/runtime_data")
>>> import json
>>>
>>> results = alpr.recognize_file("/home/pi/ea7the.jpg")
>>>
>>> print(json.dumps(results, indent=4))
{
    "version": 2,
    "data_type": "alpr_results",
    "epoch_time": 1589218326623,
    "img_width": 636,
    "img_height": 358,
    "processing_time_ms": 234.429916,
    "regions_of_interest": [
        {
            "x": 0,
            "y": 0,
            "width": 636,
            "height": 358
        }
    ],
    "results": [
        {
            "plate": "EA7THE",
            "confidence": 91.05777,
            "matches_template": 0,
            "plate_index": 0,
            "region": "",
            "region_confidence": 0,
            "processing_time_ms": 59.747936,
            "requested_topn": 25,
            "coordinates": [
                {
                    "x": 208,
                    "y": 157
                },
                {
                    "x": 393,
                    "y": 157
                },
                {
                    "x": 393,
                    "y": 245
                },
                {
                    "x": 208,
                    "y": 245
                }
            ],
            "candidates": [
                {
                    "plate": "EA7THE",
                    "confidence": 91.05777,
                    "matches_template": 0
                },
                {
                    "plate": "EA7TBE",
                    "confidence": 84.132973,
                    "matches_template": 0
                },

Enabling telnet access on DCS-7110

Very nice outdoor bullet camera that the D-Link DCS-7110 is, managing it is a pain as the main web interface still uses Active-X, and seems to be coded to IE6. Fortunately, it is actually running linux under the hood, so if you know what you are doing, you can edit the configuration directly.

Step 1 is to enable the telnet server, by using this link:

http://<camera-ip>/cgi-bin/admin/mod_inetd.cgi?telnet=on

Now we can telnet onto the device using the same credentials as the web

[user.network][~]=> telnet A.B.C.D
Trying A.B.C.D...
Connected to A.B.C.D.
Escape character is '^]'.

Network-Camera login: <username>
Password:
~ #
~ # ls
back.tar.gz imgbufmgr s0 s1 s2 s3 s4
~ # cd s0
~/s0 # ls

All the interesting config that I could see lives under /etc

~/s0 # cd /
/ # ls
bin drivers home linuxrc proc sbin tmp usr www
dev etc lib mnt root sys tmpfs var

When you are done, be sure to disable the telnet server again, and reboot the camera for the changes to take effect.

http://<camera-ip>/cgi-bin/admin/mod_inetd.cgi?telnet=off


> telnet A.B.C.D
Trying A.B.C.D...
telnet: connect to address A.B.C.D: Connection refused
telnet: Unable to connect to remote host

Raspberry Pi as a Cheap Security Camera

One thing I wanted to look into was the use of the Raspberry Pi as a low-cost, linux based security camera. Key goals were:

  • Recording of HD Video
  • Live stream via web browser

This sets out the steps I did to get it up and running – consider some of the previous posts on the Raspberry to lock it down before opening it to the big bad interweb.

Raspberry Pi Configuration

Disable the camera led – lets not make it too obvious if we are, or aren’t recording. Add the following line to /boot/config.txt

disable_camera_led=1

There is a free, open-source motion detection/surveillance software package that we can use, called motion. Unfortunately it doesn’t yet support the Raspberry Pi Camera Module natively yet, so a special build is required.

sudo apt-get install motion
sudo apt-get remove motion

This is a little odd, but the main goal is that the APT package manager will install all the dependencies, add the service account, etc.

Then we get the customised motion package and install it:

wget https://www.dropbox.com/s/xdfcxm5hu71s97d/motion-mmal.tar.gz
tar zxvf motion-mmal.tar.gz
sudo mv motion /usr/bin/motion
sudo mv motion-mmalcam.conf /etc/motion.conf

We then need to enable motion to run as a daemon by editing /etc/default/motion to include

start_motion_daemon=yes

The main motion configuration file is /etc/motion.conf, but lets make sure that the permissions are sufficient for the motion user to modify them

sudo chmod 664 /etc/motion.conf
sudo chmod 755 /usr/bin/motion
sudo touch /tmp/motion.log
sudo chmod 775 /tmp/motion.log

At this point I tried to run it from the CLI, but was missing a library:

pi@watcher ~ $ motion
motion: error while loading shared libraries: libjpeg.so.62: cannot open shared object file: No such file or directory

Easily solved:

sudo apt-get install libjpeg62

motion.conf – some key changes

daemon on
process_id_file /tmp/motion.pid

logfile /home/pi/motion.log

width 1280
height 720

framerate 2

pre_capture 2
post_capture 2

max_movie_time 600

ffmpeg_video_codec msmpeg4

stream_localhost off

stream_auth_method 2
stream_authentication USERNAME:PASSWORD

There are many configuration options, all of which are detailed in the motion config documentation

If we are running it as a daemon on boot we also need to update /etc/init.d/motion with the log and PID variables e.g.

PIDFILE=/tmp/$NAME.pid

So far the streaming works fine is Firefox and Safari, but not Chrome.