Open Schaussi opened 7 years ago
I have created a systemd service file if you run raspbian (which uses systemd). So I would recommend you install catcierge on your system. To do that you first need to create a debian package:
cd build/
cmake ..
make
cpack # Builds the debian package.
ls *.deb # Or check output from above command what it is named.
sudo dpkg -i catcierge-0.6.3-armhf.deb # If you built the latest version it should be named this...
So that installs catcierge as a daemon on the system:
(Reading database ... 42601 files and directories currently installed.)
Preparing to unpack catcierge-0.6.3-armhf.deb ...
Unpacking catcierge (0.6.3) over (0.6.3) ...
Setting up catcierge (0.6.3) ...
#########################################
Creating user catcierge
#########################################
The system user `catcierge' already exists. Exiting.
Getting started
---------------
1. Create a system-wide catcierge config file to get started:
sudo cp /etc/catcierge/catcierge-example.cfg /etc/catcierge/catcierge.cfg
2. To see available options run:
catcierge_grabber --help
3. And to finally start the service:
sudo systemctl start catcierge
So yea, if you are not familiar with systemd read up some on how you stop start services using systemctl
.
To follow the log live you can run the following command:
sudo journalctl -f -u catcierge
Or if you want to check the entire log since yesterday:
sudo journalctl --since yesterday -u catcierge
Here is the contents of the systemd service file:
cat /lib/systemd/system/catcierge.service
[Unit]
Description=Catcierge automatic cat door awesomeness
After=catcierge_rpi_gpio.service
[Service]
ExecStart=/usr/local/bin/catcierge_grabber
RemainAfterExit=yes
StandardOutput=journal+console
StandardError=journal+console
User=catcierge
Group=users
[Install]
WantedBy=multi-user.target
As you see it also installs services that sets the proper GPIO settings.... Which pins are used and so on are defined at compile time using CMake (see cmake -LH ..
for CATCIERGE_LOCKOUT_GPIO
and CATCIERGE_BACKLIGHT_GPIO
to change which pins to use by default).
They can also be set at runtime via the command line/config file:
catcierge_grabber --help|grep gpio
This are the sources for the service files that are generated: https://github.com/JoakimSoderberg/catcierge/blob/master/cmake/catcierge_rpi_gpio.service.in
[Unit]
Description=Set cat door to open on boot
[Service]
Type=oneshot
ExecStart=@CMAKE_INSTALL_PREFIX@/share/catcierge_rpi_gpio.sh
[Install]
WantedBy=multi-user.target
The script referenced: https://github.com/JoakimSoderberg/catcierge/blob/master/cmake/catcierge_rpi_gpio.service.in
#!/bin/sh
# Cat door
echo "Catcierge lockout pin GPIO@CATCIERGE_LOCKOUT_GPIO@"
echo @CATCIERGE_LOCKOUT_GPIO@ > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio@CATCIERGE_LOCKOUT_GPIO@/direction
echo 0 > /sys/class/gpio/gpio@CATCIERGE_LOCKOUT_GPIO@/value
# Backlight pin
echo "Catcierge backlight pin GPIO@CATCIERGE_BACKLIGHT_GPIO@"
echo @CATCIERGE_BACKLIGHT_GPIO@ > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio@CATCIERGE_BACKLIGHT_GPIO@/direction
echo 0 > /sys/class/gpio/gpio@CATCIERGE_BACKLIGHT_GPIO@/value
echo "Catcierge GPIO ports setup"
And the catcierge service file: https://github.com/JoakimSoderberg/catcierge/blob/master/cmake/catcierge.service.in
[Unit]
Description=Catcierge automatic cat door awesomeness
@CATCIERGE_SERVICE_AFTER@
[Service]
ExecStart=@CMAKE_INSTALL_PREFIX@/bin/catcierge_grabber
RemainAfterExit=yes
StandardOutput=journal+console
StandardError=journal+console
User=catcierge
Group=users
[Install]
WantedBy=multi-user.target
Is there a logging option at the moment? I saw some information in your description, but cannot see a catcierge_grabber parameter regarding logging. "log=1" or "log_path=/var/log/catcierge.log" etc. do not work in cfg file.
Yes this is kind of deprecated, I have not even tested it for a long time... So I was planning to remove this eventually... This was some very basic logging I added early on. Now I'd rather rely on the console output which is logged by systemd... And then for special events one can use the "template output" stuff I mentioned in the other issue.
Note that the first thing you should be tweaking is the "background image" in front of your cat door. You haven't described your setup at all, but I'm assuming you've seen the pictures of my setup with a backlight and so on?
Use the catcierge_grabber --save_auto_roi
to get a debug image to tweak the region of interest for your background image.
$ sudo systemctl stop catcierge
$ catcierge_grabber --auto_roi_thr 180 --save_auto_roi
If you don't have this working good so it is a uniform and stable background, you will get a lot of false positive matches getting triggered.
I have added some code that makes all of this easy. However there is no easy "test program" for this. But rather you will need to use the catcierge_grabber
program to do this.
The detection for when to start matching works in the way that the camera is filming a white background. The image is made "binary" that is, a pixel is either BLACK or WHITE depending on a certain threshold for the grey value for a pixel. When something enters that white image, a certain percentage of black pixels end up in the camera picture, which triggers the logic to start the match sequence.
Here is the logic for this, sum all black pixels. If there are more than 200 then something is obstructing the frame. https://github.com/JoakimSoderberg/catcierge/blob/master/src/catcierge_matcher.c#L249
All settings related to the Region Of Interest (ROI):
$ catcierge_grabber --help|grep -C5 roi
...
--startup_delay STARTUP_DELAY Number of seconds to wait after starting before starting to
capture anything. This is so that if you have a back light
that is turned on at startup, it has time to turn on,
otherwise the program will think something is obstructing the
image and start trying to match.
--roi X Y WIDTH HEIGHT Crop all input image to this region of interest. Cannot be used
together with --auto_roi.
--auto_roi Automatically crop to the area covered by the backlight. This
will be done after --startup_delay has ended. Cannot be used
together with --roi.
--auto_roi_thr THRESHOLD Set the threshold values used to find the backlight, using a
binary threshold algorithm. Separate each pixel into either
black or white. White if the greyscale value of the pixel is
above the threshold, and black otherwise.
Default value 90
--min_backlight MIN_BACKLIGHT If --auto_roi is on, this sets the minimum allowed area the
backlight is allowed to be before it is considered broken. If
it is smaller than this, the program will exit. Default 10000.
--save_auto_roi Save the image roi found by --auto_roi. Can be useful for
debugging when tweaking the threshold. Result placed in
--output_path.
The ideal picture would be like this:
That is, the white background is perfectly framed. But that becomes quite a hazzle to achieve with the correct camera distance and whatever.
So to make that simpler I added the auto_roi
feature... ROI as in Region Of Interest. So we can feed it a background like this (from my current cat door):
From my config file I use these settings for the auto_roi
stuff:
auto_roi=1
auto_roi_thr=180
To verify you have a good background for your setup you can use the --save_auto_roi
command line option, which makes it save images of the background and region of interest at startup:
$ sudo systemctl stop catcierge # Make sure catcierge_grabber service is stopped
$ catcierge_grabber --auto_roi_thr 180 --save_auto_roi # This will save a debug image for the ROI, see path below.
...
[2016-08-13 14:59:40.649604] Automatically setting the frame obstruction Region Of Interest (ROI) to the back light area.
[2016-08-13 14:59:40.653278] Back light found with area 15528 (which is greater than the minimum allowed 10000)
[2016-08-13 14:59:40.664023] Saved auto roi image to: /home/pi/dev/catcierge/build/auto_roi.png
[2016-08-13 14:59:40.674148] Saved auto roi image to (highlighted): /home/pi/dev/catcierge/build/auto_roi_highlight.png
[2016-08-13 14:59:40.674536] Obstruction Region Of Interest (ROI): x: 89 y: 59 w: 128 h: 131
Or using another threshold (default is 90):
$ catcierge_grabber --auto_roi_thr 90 --save_auto_roi
...
[2016-08-13 15:08:45.635883] Startup delay of 0.00 seconds has ended!
[2016-08-13 15:08:45.636330] Automatically setting the frame obstruction Region Of Interest (ROI) to the back light area.
[2016-08-13 15:08:45.640741] Back light found with area 48090 (which is greater than the minimum allowed 10000)
[2016-08-13 15:08:45.652071] Saved auto roi image to: /home/pi/dev/catcierge/build/auto_roi.png
[2016-08-13 15:08:45.664543] Saved auto roi image to (highlighted): /home/pi/dev/catcierge/build/auto_roi_highlight.png
[2016-08-13 15:08:45.665326] Obstruction Region Of Interest (ROI): x: 1 y: 1 w: 318 h: 238
[2016-08-13 15:08:45.969035] Something in frame! Start matching...
[2016-08-13 15:08:45.988765]
[2016-08-13 15:08:45.989088] === Match group id: b3815f627de480a6195c6d44633467a88ca17244 ===
[2016-08-13 15:08:45.989356]
[2016-08-13 15:08:45.989972] [Waiting] -> [Matching]
[2016-08-13 15:08:46.034472] Match in - No cat head detected (5e005292298c4d2fbe288a73297777b5cdd441c3)
[2016-08-13 15:08:46.067820] Match in - No cat head detected (d5132f19d10faaa04cf19f35802a7fe1e6d428c3)
[2016-08-13 15:08:46.100927] Match in - No cat head detected (a93c45586f979a52b0e3e37a30fc1b3294fe17d)
[2016-08-13 15:08:46.135553] Match in - No cat head detected (b64cd4b1d1298cea24c1812a45075202ee4ac9b9)
[2016-08-13 15:08:46.136593] !!! Match group vetoed match success: No head found in any image !!!
[2016-08-13 15:08:46.139099] Lockout! 0 out of 4 matches failed (for 30 seconds).
[2016-08-13 15:08:46.139424] Waiting for lockout timer only (Lockout method 1)
[2016-08-13 15:08:46.139659] [Matching] -> [Lockout]
As you see in the text output above, this was not a good threshold, since it incorrectly thought the image was obstructed... Which is clear from the images below. The white outline is the thresholded area. If one encloses this in a rectangle you have the region of interest. But since the outline is so big it becaomse the entire picture (which includes a lot of black pixels):
Same for 120:
160 works, but is not good because it will throw off the algorithm because it is including the reflection at the bottom:
Currently I have no native code helper program to do this "offline" just giving it an image like with the other test programs. Instead of having to run it through the camera like this.
But I have a small prototype script written in python:
If you have docker installed you can run it (or if you have a python + opencv environment set up on your machine, but docker makes this simple). Note that I have my code checked out in ~/dev/catcierge/
in the below example (I am mounting the example images inside of the docker so the script can find them).
However, since this is not the exact same code as in the cat door code, with Python in between "translating" some OpenCV stuff. So if we run it on the same image as before where 180 was a good threshold, it now does not work:
180:
$ docker run -v $PWD:/app -v ~/dev/catcierge/examples:/examples ibotdotout/python-opencv python find_backlight.py --threshold 180 /examples/real/goodbg02.png
But raising it works...
220:
$ docker run -v $PWD:/app -v ~/dev/catcierge/examples:/examples ibotdotout/python-opencv python find_backlight.py --threshold 220 /examples/real/goodbg02.png
So this script is more good to play with to understand how it works, rather than use it to find the best setting.
Btw, here is the difference between how it looked when I had newly built my latest version of the cat door (I use plexiglas as a divider in front of the camera)
Before:
But after a while there will be dirt and scratches:
After:
So something good to think about. My setting with 180 as the threshold works fine for both those scenarios. But be aware things can shift as time goes on :)
Oh and an example of a bad background would be this:
Here my old backlight that was made out of normal led strips kind of stopped working because of the cold or just shitty quality... so the light because non-uniform... So it gives a ROI like this, which is bad:
With some tweaking one can get the area slightly bigger, but the goal is to get a square, not some blob like this:
It's cold and rainy today, hence my crazy spamming :)
I wrote a small helper program to tweak the above Auto ROI threshold: https://github.com/JoakimSoderberg/catcierge/blob/master/src/catcierge_bg_tester.c
Make sure you remember to update the submodules if you want to get the changes:
git checkout master
git pull --rebase upstream master # upstream or whatever your remote is named (git remote -v)
git submodule update # Must be in project root when running this.
git fetch --all # Get tags to get proper version.
This program can be run in both command line or GUI mode:
Background tester settings:
Use these settings to pass a set of images you want to test when tweaking the
settings relating to finding the backlight in the background using --auto_roi
and other command line options.
IMAGE Input image containig the
background image used to tweak
settings with.
--interactive GUI required, allows changing the
auto roi threshold interactively.
So to run it in GUI mode:
bin/catcierge_bg_tester --interactive --haar --cascade ../extra/catcierge.xml ../examples/real/goodbg04.png
Or to save images as I previously showed (but only with catcierge_grabber
running live) just using the command line:
bin/catcierge_bg_tester --haar --cascade ../extra/catcierge.xml ../examples/real/goodbg04.png --auto_roi_thr 130 --save_auto_roi
I've tested this on both Windows and OSX, should work fine on Linux as well. However on OSX the trackbar does not show its value, so one has to look in the console window.
Thank you for your answers.
I think the background should be "white enough", and the default ROI threshold also seems to work fine. During the day, I might get problems regarding sun shadow, but I will try to solve this later (also night recording; it is the Rpi cam without the IR filter).
I can now basically start the daemon via "systemctl start catcierge.service", but it does not start on boot, though the service is enabled. It seems to only work when the service is stopped and then started again (otherwise no catcierge_grabber appears in process list). Also there appears an error "Failed to open PID file /var/run/catcierge.pid".
Journal logging also works, but does not show all information you see when you manually start catcierge_grabber.
What I would like to achieve: The Rpi should run now for some days and collect cat picture data. Then I would like to see how the images were processed, what were the results and what I have to optimize. E.g. it would be great if I could easily see a detailed log text for every directory under /home/catcierge/images/[date]/. It would be even better if I could see the recognized regions (cat head, snout) painted into the processed images in the subfolders (but I think --highlight does not work). Would this be possible?
At the moment, I have not modified the default haar cascade file in any way. Which way do you recommend to "teach" the application some good and bad head/snout pictures? (I would not like to damage or confuse the default haar file)
Thank you
Hello again,
I think the background should be "white enough", and the default ROI threshold also seems to work fine. During the day, I might get problems regarding sun shadow, but I will try to solve this later (also night recording; it is the Rpi cam without the IR filter).
Hmm well it would be nice if you could maybe provide an image of how your background looks by using --save_auto_roi
?... You can include the image here by simply dropping it in the text field.
I am stressing this, because it is absolutely essential to get this working properly.
I am NOT using the IR camera either for this. But the point is that the background should be a light source. Or you are guaranteed to have issue with different lightning condition during the day/night. You will get spammed with invalid events.
I can now basically start the daemon via "systemctl start catcierge.service", but it does not start on boot, though the service is enabled.
Ah yes, to enable it starting on boot you use this command (or is that what you meant with "enabled"?):
sudo systemctl enable catcierge.service
Ah yes now that I come to think of it. I have it setup so that the GPIO "oneshot" service that will run at boot to enable the proper GPIO pins. Then the catcierge.service
will run After
that:
$ cat /lib/systemd/system/catcierge.service
[Unit]
Description=Catcierge automatic cat door awesomeness
After=catcierge_rpi_gpio.service
...
so you need to run:
sudo systemctl enable catgpio.service
To see which services that are run at boot:
ls -al /etc/systemd/system/*.service
Also there appears an error "Failed to open PID file /var/run/catcierge.pid".
This can be ignored, it is not used by systemd
Journal logging also works, but does not show all information you see when you manually start catcierge_grabber.
Yes I remember having this issue, but it should work with the latest version. Note that when you follow the log it will only show the "tail" of the log... You can extend so it shows more lines (200 in this example):
$ sudo journalctl -f -n 200 -u catcierge
Note however that journalctl
does not seem to properly show the order of stderr/stdout... so for example stderr
comes after the stdout
output which is why you might think it does not show the full log.
What I would like to achieve: The Rpi should run now for some days and collect cat picture data. Then I would like to see how the images were processed, what were the results and what I have to optimize. E.g. it would be great if I could easily see a detailed log text for every directory under /home/catcierge/images/[date]/. It would be even better if I could see the recognized regions (cat head, snout) painted into the processed images in the subfolders (but I think --highlight does not work). Would this be possible?
Again I stress the importance of the backlight... It must be a light!
But yes this is a good idea to do... Could you please provide me the contents of your config?
Here is mine for example:
matchtime=20
# Haar matcher
haar=1
cascade=/usr/local/share/catcierge/catcierge.xml
in_direction=right
min_size=80x80
# Save images
save=1
save_obstruct=1
save_steps=1
output_path=/home/catcierge/images/%match_group_start_time:&Y-&m-&d%
match_output_path=%output_path%/%match_group_id%
steps_output_path=%match_output_path%/%matchcur_idx%
auto_roi=1
auto_roi_thr=180
noanim=1
#lockout_dummy=1
zmq=1
# OLD
#input=/usr/local/share/catcierge/templates/match_group_done_full.json
input=/usr/local/share/catcierge/templates/event.json
You should not use highlight
I should probably remove that setting. As you see above I use the --save_steps
setting to get full debug output. (I showed example of the images you get for each match with this in https://github.com/JoakimSoderberg/catcierge/issues/11)
With this config, each match will generate a JSON with a unique ID. In the same directory as that JSON file there is a directory with the same ID containing all the images for that match.
At the moment, I have not modified the default haar cascade file in any way. Which way do you recommend to "teach" the application some good and bad head/snout pictures? (I would not like to damage or confuse the default haar file)
You should NOT edit this by hand, it will fail. This file was generated from thousands of training samples. The process for doing this (quite tedious) can be found in this repository: https://github.com/JoakimSoderberg/catcierge-samples
But you should not have to modify this at all most likely. Unless you have some very weird looking cat that is (long haired that makes its profile look completely different from my training data or something) :)
The most important thing as I keep repeating is to have a good consistent environment for the camera + background image. You describe the night/sun disturbing the picture. This is bound to be the problem, rather than the Haar cascade itself, you won't be able to tweak that to fix those issues even if you create your own training data. The important thing is the consistency of the input images.
It would be great if you could provide some images of your cat door setup, pictures of how you have placed your camera, the background taken by the Raspberry Pi camera, pictures of your cat etc... It would make it a lot easier for me to help you. If you don't want to post those here you can email them to me: joakim.soderberg@gmail.com
Btw I added "live camera" support to the catcierge_bg_tester
last night, so you should update your repo:
git checkout master
git pull --rebase origin master
git fetch --all # To get my tags
Also note that the directory structure created for the output images is just the format I prefer, based on these settings:
output_path=/home/catcierge/images/%match_group_start_time:&Y-&m-&d%
match_output_path=%output_path%/%match_group_id%
steps_output_path=%match_output_path%/%matchcur_idx%
If you just want all images as a flat structure you can simply do:
output_path=/home/catcierge/images/%match_group_start_time:&Y-&m-&d%
Or one directory for each event 2016-08-15/1726/
:
output_path=/home/catcierge/images/%match_group_start_time:&Y-&m-&d%
match_output_path=%output_path%/%match_group_start_time:&H&M&S%
steps_output_path=%match_output_path%/steps/
You get the point, it's configurable as you like...
The time formatting is based on http://man7.org/linux/man-pages/man3/strftime.3.html ... But instead of %
you use &
since catcierge uses %
for the variables as well...
Sorry for replying late. I did some further tests but had do realize the cat door is at the worst place for such a project: Built into a door panel, sun problems (shadows from time to time, too hot in summer for Rpi), WLAN issues, .... So the next step will probably to create a new cat door in a place with a more neutral environment, which will take a few weeks. I will send you pics then if you would like to. Thank you for your help yet.
No worries, I thought I simply scared you away with my somewhat obsessive manners :)
Feel free to ask for pointers on building the hardware, I have built two
I have now configured catcierge with haar matching and would like to collect some more real images of my cat, and test it with your cascade file - so I want to run catcierge in the background. Do you have any preferred way to to this, e.g. special parameters etc., or can I run it in background simply via "&"? Is there a logging option at the moment? I saw some information in your description, but cannot see a catcierge_grabber parameter regarding logging. "log=1" or "log_path=/var/log/catcierge.log" etc. do not work in cfg file. Thank you