Deriche filter

Principle

The Deriche filter is a smoothing filter (low-pass) which was designed to optimally detect, along with a derivation operator, the contours in an image (Canny criteria optimization). Besides, as this filter is very similar to a gaussian filter, but much simpler to implement (based on simple first order IIR filters), it is also much used for general image filtering.

Indeed, contrary to a gaussian filter that is often implemented using a FIR (finite response) filter, and which complexity is directly dependant on the desired filtering level (standard deviation sigma), for a first order IIR, which equation is: y[n] = a*x[n] + (1-a)*y[n-1], the complexity is constant and very limited (2 multiplications per pixel), and the filtering level can be arbitrary modified through the "forget factor" a.

Yet, this filter is not symetrical, which can be a problem while processing images. Fortunately, to make it symetrical, one needs only to apply it a second time in the inverse direction (anti-causal filter). At last, to be even closer to a gaussian filter, this sequence causal + anti-causal filtering is applied twice. Here is what we obtain in terms of 1D impulse responses:

In the end, we need four filtering in the horizontal direction, then four filtering in the vertical direction (the filter is separable), hence a fixed complexity of about 16 multiplications / pixel, and this independantly of the desired filtering level. For comparison, with a gaussian filter, the complexity becomes higher whenever the kernel width is 9 pixels or higher.

Gaussian and Deriche filters 2D impulse responses

C++ API

int DericheBlur(const cv::Mat &I, cv::Mat &O, float gamma)

Where:

  • I and O are respectively the input and output images. The type of the pixels can be: CV_32F, CV_8U, CV_16S, with an arbitrary number of channels (colors).
  • And gamma is the "forget factor" between 0 (no filtering) et 1 (maximal filtering).

Application to gradient computing

When we compute an image gradient (that is, the partial derivatives of the image along the x and y directions), the high-frequency noise is naturally amplified ; that's why it is very important to prefilter the image before applying the derivation operator. For this, a gaussian filter is often used (for instance in the Canny algorithm), but its approximation by the Deriche filter can also be used.

The following function make successively the two operations of prefiltering (Deriche) et the gradient computing (Sobel mask):

int DericheGradient(const cv::Mat &I, 
                    cv::Mat &gx, cv::Mat &gy, 
                    float gamma)

To be convinced of the need to prefilter the image before computing the gradient, look below at the gradients computed on a image only moderatly noised (in practive, the noise can be even more important, especially in low lighting conditions):

Test image (top left), Sobel gradient without prefiltering (top right), with Deriche prefiltering (bottom).

As one can expect, the Deriche prefiltering gives similar results as the gaussian prefiltering (but with lower complexity), and better than with a simple moving average filter, as the figures below show:

Sobel gradient (without prefiltering). The color (hue) indicates the gradient direction.

Canny's gradient (gaussian prefiltering, 15x15 kernel)

Deriche's gradient (exponential prefiltering, a = 0.6)

Gradient (moving average prefiltering, 11x11 kernel). Note: a wider kernel makes the noise lower, but makes also the gradient too much blurry.