OpenCV Q&A Forum - RSS feedhttp://answers.opencv.org/questions/OpenCV answersenCopyright <a href="http://www.opencv.org">OpenCV foundation</a>, 2012-2018.Wed, 12 Sep 2018 04:16:52 -0500Most accurate visual representation of Gradient Magnitudehttp://answers.opencv.org/question/199237/most-accurate-visual-representation-of-gradient-magnitude/ 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)Wed, 12 Sep 2018 02:48:32 -0500http://answers.opencv.org/question/199237/most-accurate-visual-representation-of-gradient-magnitude/Answer by kbarni for <p>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.</p>
<pre><code># 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)
</code></pre>
http://answers.opencv.org/question/199237/most-accurate-visual-representation-of-gradient-magnitude/?answer=199245#post-id-199245The [magnitude formula](https://docs.opencv.org/2.4/doc/tutorials/imgproc/imgtrans/sobel_derivatives/sobel_derivatives.html) is:
mag=sqrt(dX*dX+dY*dY)
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-255Wed, 12 Sep 2018 04:16:52 -0500http://answers.opencv.org/question/199237/most-accurate-visual-representation-of-gradient-magnitude/?answer=199245#post-id-199245