Catcierge is an image recognition and RFID detection system for a DIY cat door. It can be used to detect prey that the cat tries to bring in, or if a neighbour cat is trying to get in. The design is targeted for use with the Raspberry Pi including the camera board. However, it also runs on Windows, Linux and OSX with a normal webcam.
There is also preliminary support for reading animal RFID tags commonly used for cats (the kind that veterinarians insert into their necks).
Service | Status |
---|---|
Travis-CI (Linux/OSX) | |
CircleCI (Linux) | |
Appveyor (Windows) | |
Unit Test Coverage | |
Statical Analysis | [ |
The Catcierge project came about to solve the problem of our cat having the nasty habit of delivering "gifts" through our cat door in the form of dead, or partly dead / fully alive rodents or birds.
Instead of simply not allowing our cat to use the cat door like normal people I of course set out to find a high-tech solution to solve my perdicament.
I found the Flo Control project project and based the general idea on that setup (detecting prey based on the cats head profile).
The first implementation used a simple template matching technique, but after evaluating that for a while I realised a better solution was needed. Instead I trained a Haar Cascade recognizer to find the cats head, and then used various other techniques to detect if it has prey in it's mouth or not. This technique has turned out to be very reliable and successful with hardly any false positives. The training data and results for the Haar cascade training can be found in a separate repository https://github.com/JoakimSoderberg/catcierge-samples
To read more about how to build your own hardware that this code can run on, and the development story, see the webpage: http://joakimsoderberg.github.io/catcierge/
For the image recognition catcierge uses OpenCV via the raspicam_cv library written by Emil Valkov (which is included in the catcierge source).
See doc/ for a full getting started guide.
Catcierge uses the CMake build system. To compile:
First, to install OpenCV on raspbian:
$ sudo apt-get install cmake opencv-dev build-essential
Then to build:
$ git clone https://github.com/JoakimSoderberg/catcierge.git
$ cd catcierge
$ git submodule update --init # For the rpi userland sources.
$ ./build_userland.sh
$ mkdir build && cd build
$ cmake -DWITH_ZMQ=OFF .. # Raspbian has no CZMQ package.
$ make
If you want ZMQ support:
$ sudo apt-get install libzmq3-dev
$ git clone git@github.com:zeromq/czmq.git
$ cd czmq
$ mkdir build
$ cd build
$ cmake ..
$ make
$ make install # either this, or see below
# Or specify the locations manually where you built it.
$ cmake -DWITH_ZMQ=ON -DCZMQ_LIBRARIES=/path/to/czmq/src/libczmq.so -D CZMQ_INCLUDE_DIRS=/path/to/czmq/include ..
If you don't have any RFID cat chip reader you can exclude it from the compilation:
$ cmake -DWITH_RFID=OFF ..
If you already have a version of the raspberry pi userland libraries built, you can use that instead:
$ cmake -DRPI_USERLAND=/path/to/rpi/userland ..
However, note that the program only has been tested with the submodule version of the userland sources.
Use your favorite package system to install OpenCV.
You can also use your own build of OpenCV when compiling:
from git https://github.com/itseez/opencv
or download: http://opencv.org/downloads.html
$ git clone <url>
$ cd catcierge
$ mkdir build && cd build
$ cmake --build .
If OpenCV is not automatically found, build your own (See above for downloads) and point CMake to that build:
... # Same as above...
$ cmake -DOpenCV_DIR=/path/to/opencv/build .. # This should be the path containing OpenCVConfig.cmake
$ cmake --build .
Download OpenCV 2.x for Windows: http://opencv.org/downloads.html
Unpack it to a known path (you need this when compiling).
Assuming you're using git bash and Visual Studio Express (or more advanced version).
NOTE: If you are using Visual Studio 2015+ at the time of writing this, the precompiled version of OpenCV does not include a compatible version, so you will need to build it yourself:
$ cd /c/opencv-2.4.13
$ mkdir build_static && cd build_static # Another build directory already exists.
$ cmake -DBUILD_SHARED_LIBS=OFF ../sources # We want static so we don't have to copy DLLs around.
$ cmake --build . # This takes a long time :)
Then compile catcierge itself (note use the correct build directory below if you built OpenCV yourself).
$ git clone <url>
$ cd catcierge
$ mkdir build && cd build
$ cmake -DOpenCV_DIR=/c/PATH/TO/OPENCV/build_static .. # The OpenCV path must contain OpenCVConfig.cmake
$ cmake --build . # Either build from command line...
$ start catcierge.sln # Or launch Visual Studio and build from there...
$ ctest # Run all tests
# If all these fail with OTHER_FAULT you have probably not linked statically
# and it is not finding the DLLs in the build directory.
# Run command below to get proper error messages.
$ bin/catcierge_regress # Run the raw test executable without ctest involved.
The main program is named catcierge_grabber which performs all the logic of doing the image recognition, RFID detection and deciding if the door should be locked or not.
For more help on all the settings:
$ ./catcierge_grabber --help
While developing and testing I have created a few small helper programs.
See --help
for all of these.
This program tests the entire matching sequence as if it was fully running, except that you only feed it with 4 input images, instead of it using the camera image live like catcierge_grabber.
This is what you want to use most of the time. It can output full debug images of each step of the matching algorithms.
$ catcierge_fsm_tester --haar --cascade /path/to/catcierge.xml --images 01.png 02.png 03.png 04.png --save_steps
To test the image recognition there is a test program catcierge_tester that allows you to specify an image to match against. This ONLY tests the image recognition part.
Haar matcher:
$ catcierge_tester --haar --cascade /path/to/catcierge.xml --images *.png --show
Template matcher (this is inferior to the haar matcher):
$ catcierge_tester --templ --snout /path/to/image/of/catsnout.png --images *.png --show
Likewise for the RFID matching:
$ catcierge_rfid_tester
There is a program that helps you tweak background settings:
$ catcierge_bg_tester --interactive --haar --cascade /path/to/catcierge.xml bg_image.png
!Note! The below prototype is quite outdated. For the Haar cascade matcher the prototype can be found in the catcierge-samples repository.
These are prototypes written in Python. The Python and C versions of OpenCV behaves slightly differently in some cases.
To test different matching strategies there's a Python prototype as well in the aptly named "protoype/" directory. The prototype is named after my cat higgs.py. This was the first prototype used to create the Template matcher technique.
It has some more advanced options that allows you to create montage pictures of the match result of multiple images. This was used to compare the result of different matching strategies during development.
For this to work you will need to have ImageMagick installed.
Specifically the program montage
.
$ cd prototype/
$ python higgs.py --help
Test a load of test images and create a montage from them using two snout images to do the match: (Note that it is preferable if you clear the output directory before creating the montage, so outdated images won't be included).
$ rm -rf <path/to/output> # Clear any old images.
$ python higgs.py --snout snouts/snout{1,2}.png --output <path/to/output> --noshow --threshold 0.8 --avg --montage
If you don't have a Python + OpenCV setup ready on your computer I would recommend
you use docker. Here's an example where I mount the catcierge-examples/
images
so they could be passed to the script.
$ docker run
-v $PWD:/app
-v ~/dev/catcierge/examples:/examples
ibotdotout/python-opencv
python find_backlight.py --threshold 140 /examples/some/image.png
[coverity]: https://scan.coverity.com/projects/2506)