I was trying to implement the sobel filter in python, but the output was poor and full of noise. The Output image i got was:
The Input I gave was(after blurring):
The code for sobel filter is below:
def sobel_filters(img):
Kx = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])
Ky = np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]])
Ix = ndimage.filters.convolve(img, Kx)
Iy = ndimage.filters.convolve(img, Ky)
G = np.sqrt(np.square(Ix) + np.square(Iy))
G *= 255.0 / G.max()
return G
I blurred the results using sigma=1.3. The input image size is 512 by 512. I expected the output to be similar to what is shown in here:https://www.adeveloperdiary.com/data-science/computer-vision/how-to-implement-sobel-edge-detection-using-python-from-scratch/
Here is one way to do that in Python/OpenCV. Your issue is that your derivatives are not properly normalized and should be processed as floats. Your normalization also does not take into account negative values. In this answer, I make use of OpenCV built-in Sobel and other methods. So there is no need to introduce scipy.ndimage
Input:
import cv2
import numpy as np
import skimage.exposure as exposure
# read the image
img = cv2.imread('gray_lena.png')
# convert to gray
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# blur
blur = cv2.GaussianBlur(gray, (0,0), 1.3, 1.3)
# apply sobel derivatives
sobelx = cv2.Sobel(blur,cv2.CV_64F,1,0,ksize=3)
sobely = cv2.Sobel(blur,cv2.CV_64F,0,1,ksize=3)
# optionally normalize to range 0 to 255 for proper display
sobelx_norm= exposure.rescale_intensity(sobelx, in_range='image', out_range=(0,255)).clip(0,255).astype(np.uint8)
sobely_norm= exposure.rescale_intensity(sobelx, in_range='image', out_range=(0,255)).clip(0,255).astype(np.uint8)
# square
sobelx2 = cv2.multiply(sobelx,sobelx)
sobely2 = cv2.multiply(sobely,sobely)
# add together and take square root
sobel_magnitude = cv2.sqrt(sobelx2 + sobely2)
# normalize to range 0 to 255 and clip negatives
sobel_magnitude = exposure.rescale_intensity(sobel_magnitude, in_range='image', out_range=(0,255)).clip(0,255).astype(np.uint8)
# save results
cv2.imwrite('gray_lena_sobelx_norm.jpg', sobelx_norm)
cv2.imwrite('gray_lena_sobely_norm.jpg', sobely_norm)
cv2.imwrite('gray_lena_sobel_magnitude.jpg', sobel_magnitude)
# show results
cv2.imshow('sobelx_norm', sobelx_norm)
cv2.imshow('sobely_norm', sobely_norm)
cv2.imshow('sobel_magnitude', sobel_magnitude)
cv2.waitKey(0)
cv2.destroyAllWindows()
Sobel X (normalized):
Sobel Y (normalized):
Sobel Magnitude: