Is the Sobel Filter meant to be normalized?
Asked Answered
R

5

23

The x-derivative Sobel looks that way:

-1 0 +1
-2 0 +2
-1 0 +1

Lets say there are two samples of my image which look like that (0=black, 1=white):

0 0 1            1 0 0
0 0 1      &     1 0 0
0 0 1            1 0 0

If I perform convolution I'll end up with 4 and -4 respectively.

So my natural response would be to normalize the result by 8 and translate it by 0.5 - is that correct? (I am wondering as can't find Wikipedia etc. mentioning any normalization)

EDIT: I use the Sobel Filter to create a 2D Structure Tensor (with the derivatives dX and dY):

                   A B 
Structure Tensor = C D

with  A = dx^2 
      B = dx*dy
      C = dx*dy 
      D = dy^2

Ultimately I want to store the result in [0,1], but right now I'm just wondering if I have to normalize the Sobel result (by default, not just in order to store it) or not, i.e.:

A = dx*dx 
//OR
A = (dx/8.0)*(dx/8.0)
//OR
A = (dx/8.0+0.5)*(dx/8.0+0.5)
Raleighraley answered 9/4, 2013 at 2:6 Comment(10)
it only depends on your application. If the goal is to store it and visualize the result as a bitmap, then you should translate and scale so that it falls within 0..255. What is your goal ?Laurin
"So my natural response would be to normalize the result by 8 and translate it by 0.5 - is that correct?" Your response to what?Loaiasis
@WhitAngl: storing and visualizing is the ultimate goal (so I'll do the appropriate normalization/translation in the end), but I have to do a bit more calculation in between. And I am wondering if the Sobel Filter ALWAYS has to be normalized (see updated question).Raleighraley
@Lajos Arpad: Natural response to getting results which are no longer in the range of the input, i.e. [0=black to 1=white]Raleighraley
if the question is: does it ALWAYS have to be normalized, the answer is no. For example, I have an application that does not do that. Hence "always" does not hold.Laurin
I just saw your edit: if you want to compute the structure tensor: you should NOT normalize it at all.Laurin
Ok, no normalization until the very end. Thank you!Raleighraley
Perhaps you're already thinking this, but I would assume that it is ALWAYS going to be normalized and for every image know the max/min of the resulting values and scale it accordingly. Have that be part of the process for every image, and it it so happens that the max and min are 1 and 0, so be it, no scaling needed.Drusilladrusus
The only reason you would ever normalize any convolution is either because I want to see the results, or the algorithm calls for normalization. If you're just using the coefficients produced for some further computation than there's no reason to normalize.Burbage
I’d like to stick to the mathematically precise gradient magnitudes. I’m going to divide them by 8, because that is the denominator, the delta in the very formula.Grumous
S
7

The Sobel filter is the composition of a finite difference filter in one dimension:

[ 1  0  -1 ] / 2

and a smoothing filter in the other dimension:

[ 1  2  1 ] / 4

Therefore, the proper normalization to the kernel as typically defined is 1/8.

This normalization is required when a correct estimate of the derivative is needed. When computing the gradient magnitude for detecting edges, the scaling is irrelevant. This is why often the Sobel filter is implemented without the 1/8 normalization.

The 1/4 in the smoothing filter is to normalize it to 1. The 1/2 in the finite difference filter comes from the distance between the two pixels compared. The derivative is defined as the limit of h to zero of [f(x+h)-f(x)]/h. For the finite difference approximation, we can choose h=1, leading to a filter [1,-1], or h=2, leading to the filter above. The advantage with h=2 is that the filter is symmetric, with h=1 you end up computing the derivative in the middle between the two pixels, thus the result is shifted by half a pixel.

Sororate answered 19/4, 2019 at 1:20 Comment(0)
S
1

A mathematically correct normalization for the Sobel filter is 1/8, because it brings the result to the natural units of one gray-level per pixel. But in practical programming, this isn't necessarily the right thing to do.

Sebastian answered 19/3, 2014 at 12:9 Comment(0)
H
1

The structure tensor is made of sums of products, so the normalization to [0, 1] is not really helpful.

You mainly use the Eigenvalues, possibly comparing them to a threshold. Rather than normalizing all values, it is more efficient to adjust the threshold.

The ratios of the coefficients or of the Eigenvalues are normalization-independent.


Now if you want to store the Sobel components and your pixel data type is unsigned bytes [0, 255], the range of the components will be [-1020, 1020], which you rescale to [0, 255] by adding 1024 and dividing by 8.

If you only need to store the gradient modulus (L∞ norm), the range is [0, 1020] and a division by 4 is enough.


Final remark: the Sobel components are usually small, except along strong edges. So it can make sense, to preserve accuracy, to use a smaller denominator (1, 2 or 4) and clamp the values that are out of range.

Hacking answered 20/9, 2022 at 14:49 Comment(0)
C
0

Regarding the finite difference filter in the highest answer by @CrisLuengo, it is normalizing the range to be stored in an unsigned char from [0, 255]. When visualizing the Sobel X or Y filter output on an image, it is common practice to normalize the values to [0, 255] for display purposes since standard imaging tools and formats, like PNG or JPEG, do not handle negative pixel values.

However, the output of a Sobel should be in the range of [-255,255]. Allowing negative values is critical if you want to obtain the orientation of a derivative.

So, for Gradient Magnitude, just

[ 1  0  -1 ]
Columbary answered 1/10, 2023 at 0:21 Comment(1)
No, I did not suggest any form of normalization for the result to fit in an 8-bit range. The division by 2 in the derivative is for the actual computation of the derivative. If you use [1,0,-1], then the result is double the actual derivative. The derivative is given by (f(x+h)-f(x))/h, in the limit for h to 0. Because we can't make h so small, we can pick h=1, leading to the [1,-1] filter, or h=2, leading to [1,0,-1]/2.Sororate
T
-1

Sobel filter is sort of heuristic approach to do differential along horizontally or vertically. Therefore, normalization could be arbitrary. I found following normalization makes more sense than others, which take half of the sum of absolute values.

http://www.imagemagick.org/discourse-server/viewtopic.php?t=14434&start=30

In fact, scikit-image uses this approach. e.g.,

>>>from skimage import filters
>>>import numpy as np
>>>one[:,0] = 2
>>>one
array([[ 2.,  1.,  1.],
       [ 2.,  1.,  1.],
       [ 2.,  1.,  1.]])
>>>filters.sobel_v(one)
array([[ 0.,  0.,  0.],
       [ 0., -1.,  0.],
       [ 0.,  0.,  0.]])
Turpin answered 25/8, 2015 at 4:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.