Gradients and Laplacian of an image using skimage vs. open-cv

112 views Asked by At

I compare the vertical and horizontal gradients and Laplacian of an image using skimage and cv2 with the following code:

import sys
import matplotlib.pyplot as plt
from matplotlib.image import imread
import skimage
import cv2

def plot(ax, img, title):
    ax.imshow(img) # cmap = 'gray'
    ax.set_title(title)
    ax.set_xticks([])
    ax.set_yticks([])

img = imread("./strawberry.jpg")
laplacian = cv2.Laplacian(img,cv2.CV_32F)
sobelx = cv2.Sobel(img,cv2.CV_32F,1,0,ksize=3)
sobely = cv2.Sobel(img,cv2.CV_32F,0,1,ksize=3)

fig1 = plt.figure(figsize=(10, 10))
fig1.suptitle('cv2', fontsize=14, fontweight='bold')
ax = fig1.add_subplot(221)
plot(ax, img, 'Original')
ax = fig1.add_subplot(222)
plot(ax, laplacian, 'Laplacian')
ax = fig1.add_subplot(223)
plot(ax, sobelx, 'Sobel X')
ax = fig1.add_subplot(224)
plot(ax, sobely, 'Sobel Y')
fig1.set_tight_layout(True)

laplacian = skimage.filters.laplace(img,ksize=5)
sobelx = skimage.filters.sobel(img, axis=0)
sobely = skimage.filters.sobel(img, axis=1)

fig2 = plt.figure(figsize=(10, 10))
fig2.suptitle('skimage', fontsize=14, fontweight='bold')
ax = fig2.add_subplot(221)
plot(ax, img, 'Original')
ax = fig2.add_subplot(222)
plot(ax, laplacian, 'Laplacian')
ax = fig2.add_subplot(223)
plot(ax, sobelx, 'Sobel X')
ax = fig2.add_subplot(224)
plot(ax, sobely, 'Sobel Y')
fig2.set_tight_layout(True)

plt.show()

Here are the results:

enter image description here

enter image description here

So, they are vastly different. Even if the kernels would differ, I would not expect such differences. Did I miss something in my script ?

1

There are 1 answers

0
user11634 On

There are two issues with the code I posted.

First, the Laplace filter from skimage works only with gray-scale images but not with color images. For the adaptation, I followed Adapting gray-scale filters to RGB images, so we should have

from skimage.color.adapt_rgb import adapt_rgb, each_channel

@adapt_rgb(each_channel)
def skimage_filters_laplace(img, ksize):
    return skimage.filters.laplace(img, ksize)

and then

laplacian = skimage_filters_laplace(img,ksize=3)

Second, there is a scaling problem; if I properly rescale the output of cv2 into [0,1], then it is fine. The examples with cv2.Sobel() I found use cv2.imshow(), it seems that the use of matplotlib to render images analyzed with cv2 makes trouble.