Ask Your Question

Most accurate visual representation of Gradient Magnitude

asked 2018-09-12 02:48:32 -0600

sazr gravatar image

I know of a couple of ways to visually show the gradient magnitude of an image. However which is the most accurate visual representation? I know that when I calculate the magnitude its in 32bit floats and outside the grayscale visible range (0-255) thus I need to scale it and in doing so I loose accuracy. But which of the below techniques scales it most accurately? Also if there are better ways I haven't done below please let me know.

# Calculate the Gradient magnitude and direction
dX = cv2.Sobel(gray, cv2.CV_32F, 1, 0, (3,3))
dY = cv2.Sobel(gray, cv2.CV_32F, 0, 1, (3,3))
mag, direction = cv2.cartToPolar(dX, dY, angleInDegrees=True)

# Technique 1
abs_dx = cv2.convertScaleAbs(dX)
abs_dy = cv2.convertScaleAbs(dY)
alt_abs_mag = cv2.addWeighted(abs_dx, 0.5, abs_dy, 0.5, 0)

# Technique 2
abs_dx = cv2.convertScaleAbs(dX)
abs_dy = cv2.convertScaleAbs(dY)
alt_abs_mag = abs_dx + abs_dy

# Technique 3
abs_mag = cv2.convertScaleAbs(mag)

# Technique 4
abs_mag = cv2.normalize(mag, 0, 255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1)
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted

answered 2018-09-12 04:16:52 -0600

kbarni gravatar image

The magnitude formula is:


It does the same thing than the cartToPolar function, without calculating the gradient angles. Technique1 and Technique2 don't calculate the magnitude accurately (however they can be used for a faster approximation).

Technique3 is unnecessary, as mag is always positive.

Technique4 will produce a normalized result between 0-255, so it's the best for display from the methods above. However the intensity will change for each image, based on the strongest gradient.

To get the best representation, so the same intensity for every image, you have to divide everything by the highest theoretical value of the Sobel operator intensity (1024*sqrt(2)=1448):

# Technique 5
mag_disp = mag / 1448 # for double values to have a result between 0-1
mag_disp_byte = mag / 5.6 # for uchar values between 0-255
edit flag offensive delete link more

Question Tools

1 follower


Asked: 2018-09-12 02:48:32 -0600

Seen: 3,198 times

Last updated: Sep 12 '18