Before fixing the roadway to my house I have laid 1 UTP cable to the fence. 2 wires was used by the door lock, 4 by videophone, 2 are used to send impulses to gate motor. That's all. There is no wires left to connects sensors checking if the gate is left open. I has happened a few times that in the evening, after letting the guests out, the gate was left opened. Nothing happened, that's true, but it is leaves a space for improvement.
The camera is a potential source of information. It is looking at the gate and is always on. It must be possible to use it to recognized if the gate is open... ...but after checking all the libraries and software doing image recognition, I got stuck. Recognizing edges, registering changes... all too complicated. It was just not worth it. Finally I managed to build a much simplified solution based on GD PHP library and some simple calculations. Here is how it's done:
1. Every minute a script on RPi downloads a 640x480 image from the camera.
2. 4 samples 15x15px each are cut out from the fence and the gate as shown on the image below:
3. The cut-out sub-samples are resampled to the size of 1x1px
4. The colors are red from the small 1x1 samples.
5. I calculate the 3d distance between the sample from the fence before the gate ant the gate's beginning as well as the fence after the gate and the gate ending.
6. If the differences are above a set treshold it means that the gate is opened.
7. The result ('open' / 'closed') is stored in a txt file for other applications' use.
The idea seems to be quite simple, right? How effective is it?
Well - it is very good. It is not a system which reacts immediately, that's for sure. It is prone to disruptions if, for example, the house drops the shadow on the gate as shown on the image below. Nevertheless after a few minutes of fine-tuning and setting right cut-offs, it all functions to my satisfaction.
One difficulty, which I managed to handle, was the flattening of color pallet in the evenings, which in turn lowered the differences between the colors even if the gate was opened. I managed it by re-sapmling the whole image to a single pixel and checking its brightness. If it is too dark I lower the difference threshold used to decide if the gate is opened:
The problem, with which I still strugle, is caused by intensive sunlight, which drops shadows of trees or my house. The reading of sub-samples returns false values. I could for example on the basis of the overall brightness recognize that the sun is high and act accordingly. Well, it does not hurt me too much, so I leave it for later. Here is the image of the described problem:
For those who would like to try how it could work I place my php code below. Here are some comments:
1. I start from downloading the image with $image = imagecreatefromjpeg("http://XXX.XXX.XXX.XXX/cgi-bin/snapshot.cgi")
2. I copy 4 samples with imagecopy($sample, $image, 0, 0, x, y, $cropSize, $cropSize)
3. I down-sample those samples to 1 pixel with imagecopyresampled($pixel, $sample, 0, 0, 0, 0, 1, 1, $cropSize, $cropSize)
4. I read the colors of those pixels with $color = imagecolorat($pixel, 0,0)
5. I read the rgb coordinates of that color with imagecolorsforindex($pixel, $color)
6. I calculate the 3d distance between the colors (although a linear distance is not perfect for colors, it does the job)
I the file attached below you will also find functions responsible for saving the result to a csv file or sending an email when the gate status changes. They might be useful for code testing. The largest commented-out part generates the image with visible rectangles showing the sub-samples and their color-differences.