Sushant007
Sushant007

Reputation: 15

why does cv2.Sobel function returns a black and white image instead of grayscale image

code -

    frame=cv2.imread('ball2.jpg',0)
    frame_blur=cv2.GaussianBlur(frame,(7,7),0)
    sobelx=cv2.Sobel(frame_blur,cv2.CV_64F,1,0,dst=None,ksize=5)
    sobely=cv2.Sobel(frame_blur,cv2.CV_64F,0,1,dst=None,ksize=5)
    lap=cv2.Laplacian(frame_blur,cv2.CV_64F)
    
   
    cv2.imshow('sobelx',sobelx)
    cv2.imshow('sobely',sobely)
    cv2.imshow('laplecian',lap)

why does cv2.solber returns a black and white image instead of grayscale and what is the threshold the cv2.solber function uses after finding the gradient in the image.

same thing happens with the cv2.laplecian function ^^^

one more question why do we normalise the image after applying solber kernel . i understand that sometimes we get a negative value after applying the solder kernel but doesn't opencv converts the negative no. to positive automatically for eg: -1 to 255 , -2 to 244

Upvotes: 1

Views: 2057

Answers (1)

fmw42
fmw42

Reputation: 53081

Here are two ways to create the sobel and normalize for saving in Python/OpenCV. Method 1: stretch min and max values to range -255 to 255, then clip negative values so range is 0 to 255. Method 2: stretch min and max values to range 0 to 255 (so zero in Sobel becomes mid gray).


Input:

enter image description here

import cv2
import numpy as np
import skimage.exposure as exposure

# read the image
img = cv2.imread('barn.jpg')

# convert to gray
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# blur
blur = cv2.GaussianBlur(gray,(3,3),0)

# apply sobel x derivative
sobelx = cv2.Sobel(blur,cv2.CV_64F,1,0,ksize=5)
      
# normalize to range -1 to 1
sobelx_norm1a = exposure.rescale_intensity(sobelx, in_range='image', out_range=(-1,1))

# normalize to range -255 to 255 and clip negatives 
sobelx_norm1b = exposure.rescale_intensity(sobelx, in_range='image', out_range=(-255,255)).clip(0,255).astype(np.uint8)

# normalize to range 0 to 255
sobelx_norm8 = exposure.rescale_intensity(sobelx, in_range='image', out_range=(0,255)).astype(np.uint8)

# save results
cv2.imwrite('barn_sobel_norm1b.jpg', sobelx_norm1b)
cv2.imwrite('barn_sobel_norm8.jpg', sobelx_norm8)

# show results
cv2.imshow('sobelx_norm1a', sobelx_norm1a)  
cv2.imshow('sobelx_norm1b', sobelx_norm1b)  
cv2.imshow('sobelx_norm8', sobelx_norm8)  
cv2.waitKey(0)
cv2.destroyAllWindows()

Result 1:

enter image description here

Result 2:

enter image description here

I suspect you want the second method. But are getting the first method when you use float values that get negative values clipped as in my displayed result 1a.

Upvotes: 1

Related Questions