OpenCV+Python:Part3–Image Gradients

In this post I will explain the application of Gradient or High pass Filters namely Sobel, Scharr and Laplacian

Sobel and Scharr

These perform Gaussian smoothing and differentiation operation and hence provides resistance against noise. The direction of the differentiation can be specified within the function along with the kernel size.


This calculates the laplacian of the image where the derivative at each position is found using the sobel derivatives

The following code snippet describes the use of the above given derivatives and gives an output of np.uint8 type with a kernel size of 5×5 —

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image.jpg',0)
laplacian = cv2.Laplacian(img,cv2.CV_64F)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5)
plt.subplot(2,2,1),plt.imshow(img,cmap = 'gray')
plt.title('Original'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,2),plt.imshow(laplacian,cmap = 'gray')
plt.title('Laplacian'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,3),plt.imshow(sobelx,cmap = 'gray')
plt.title('Sobel X'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,4),plt.imshow(sobely,cmap = 'gray')
plt.title('Sobel Y'), plt.xticks([]), plt.yticks([])

The result–

One important thing to note in the above example is that the data type of the result image is taken as np.uint8 in which all Black to White transitions are considered Positive slopes but all the White to Black transitions are taken as Negative slope and hence are taken as zero in the final result and important edge information is lost. However if you want to keep the edge info intact you can use a higher data type like cv2.CV_16S, cv2.CV_64F etc, take its absolute value and convert it back to cv2.CV_8U.

The following code snippet demonstrates this procedure by applying a horizontal Sobel filter :

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image.jpg',0)
# Output dtype = cv2.CV_8U
sobelx8u = cv2.Sobel(img,cv2.CV_8U,1,0,ksize=5)
# Output dtype = cv2.CV_64F. Then take its absolute and convert to cv2.CV_8U
sobelx64f = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)
abs_sobel64f = np.absolute(sobelx64f)
sobel_8u = np.uint8(abs_sobel64f)
plt.subplot(1,3,1),plt.imshow(img,cmap = 'gray')
plt.title('Original'), plt.xticks([]), plt.yticks([])
plt.subplot(1,3,2),plt.imshow(sobelx8u,cmap = 'gray')
plt.title('Sobel CV_8U'), plt.xticks([]), plt.yticks([])
plt.subplot(1,3,3),plt.imshow(sobel_8u,cmap = 'gray')
plt.title('Sobel abs(CV_64F)'), plt.xticks([]), plt.yticks([])

The result:

That’s all in this post…Sayonara!!