Despeckle Patch for Motion
This page documents the despeckle patch for motion which adds the
option to motion.conf.
Download the despeckle.patch for motion-3.1.12. (Updated with dilate fixes 14 Apr 2004)
What does it do?
This is the default for motion. There are lots of things moving - the trees, grass and sea - and motion finds them all! As the wind blows, however, I get more and more detections so I have to raise the detection threshold to stop being swamped by false alarms. Unfortunately, if I raise the detection threshold too high then things will sneak past without being detected.
If you look at the motion image on the right, you will notice that although I am getting lots of detections they are all very small ones. So if I can remove these small detections, I can lower the detection threshold and then only snap the real motion.
For this image, I have applied the despeckle option, which has removed the small detections and only left the pigeon to be snapped.
Why not use a mask file?
A mask file can be used to block off parts of the image where motion is unwanted, but the mask needs to be aligned with the image. If I move the camera I need to generate a new mask file. With the despeckle patch, the algorithm ignores small movements wherever the camera is pointed. Also, if I tried to use a mask for this particular scene, there wouldn't be much of the image left, which is a pity as I get nice sunsets.
How does it work?
To remove the small detections, I use the technique of mathematical morphology (Also see the tutorials at CVonline or Raindeer Graphics.) Mathematical morphology is actually a branch of set theory, but you don't need to know that to use it.
First you need to define a structural element:
The structural element can be anything you want, but you should choose a shape that corresponds to the sort of feature you're interested in. If you want long thin objects, then choose a long thin structural element. I'm interested in small blobs, so I've chosen the above small blob.
Using the green structural element on the right, you scan the cross shape over the image. If you find 5 detection pixels in the same cross shape, then you mark it as a single detection. The following images show what happens:
Since each cross of 5 pixels only gets replaced by a single pixel, the effect is to make the detections smaller. None of the 4 pixels in the 2x2 box in the top right hand corner fit in the cross structural element and so the box is deleted.
This is a very non-mathematical description of erosion. We can reverse the process using dilation:
Here we scan the structural element over the image on the left and any detection pixel that lies in the cross is marked. The effect of dilation is to make the detections bigger.
How do I use it?
The size and shape of the noise you don't want detected will vary from webcam to webcam and from application to application, so I tried to set up a general method for despeckle.
There are two basic structural elements:
These can be used as many times and in any order to achieve the despeckling you need. So, for instance, the square (red) structural element followed by the cross (green) structural element is specified by the option despeckle Ee and will produce this effect:
Repeatedly applying the cross will produce diamond shapes while the box will produce squares. You can use combinations of these to produce circles. Each time you use a structural element, you add or remove a layer of pixels from the outside of the detection.
In general, each erode (e/E) will remove a layer of pixels from around each detection and each dilate (d/D) will add a layer of pixels to each detection.
In this image I have used the option despeckle EedD to erode with the box structural element and then the cross structural element. This removes the small (noisy) detections, but also shrinks the real detection of me on a bike. I then use dilation to expand the detection back up to full size so the threshold is correct.
In the left hand image motion has correctly found the person walking in the rain, however there is some noise at the top of the image I would like to remove. Applying despeckle e removes nearly all of these noisy detections (click on the middle image to see the full size version). There are just one or two left so for completeness, I try despeckle eE to remove them all (right hand image).
In the left hand image, the sun has come out after rain and so motion thinks that there is a big change, however the image is very noisy, so lets see what despeckle can do. Applying despeckle ee to the middle image removes many of the detections, but since I have used the cross structural element twice I get diamond shaped holes (click on the middle image to see this).
If I use despeckle eE instead, which applies the cross and then the box structural element, I get much more circular holes appearing. (click on the right hand image to see this).
This is a very windy day and a lot of things are being blown around. Without despeckle, motion is detecting over 200 events an hour, so I've sifted through the images and eventually found one of a car. Applying the cross structural element with despeckle e removes many detections, but also starts to open up a hole in the middles of the car. If I apply more erosions then the car will disappear along with everything else. So I fill in hole in the car with a dilate and then experiment with more erosions.
This is not a practical use of motion and despeckle, but it demonstrates how the erode and dilate options can be tuned to find just what you're looking for.
Want to play with despeckle?
Still not sure of all the e, E, d and D combinations to despeckle? Download despeckle.c and try it your own motion images.
Set output_motion yes in motion.conf and the motion images will be saved with a *m.jpg suffix.)
./despeckle EEEEee 11-00m.jpg desp1.jpg
./despeckle dDee 11-00m.jpg desp2.jpg
./despeckle EedD 11-00m.jpg desp3.jpg
You may need the jpeg-dev or jpeg62-dev package to compile up despeckle.c.