Gradient filters

Open In Colab

In [1]:
# to run in google colab
import sys

if "google.colab" in sys.modules:

    def download_from_web(url):
        import requests

        response = requests.get(url)
        if response.status_code == 200:
            with open(url.split("/")[-1], "wb") as file:
                file.write(response.content)
        else:
            raise Exception(
                f"Failed to download the image. Status code: {response.status_code}"
            )

    download_from_web(
        "https://github.com/YoniChechik/AI_is_Math/raw/master/c_03_edge_detection/Bikesgray.jpg"
    )
In [2]:
import cv2
import numpy as np
from matplotlib import pyplot as plt

figsize = (10, 10)

Original image

In [3]:
img = cv2.imread("Bikesgray.jpg")
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
plt.figure(figsize=figsize)
plt.imshow(img, cmap="gray", vmin=0, vmax=255)
plt.title("Original image")
plt.show()
No description has been provided for this image

X absolute grad filter

In [4]:
img = img.astype(float)  # 'uint8' doesn't work with minus sign - for filtering

# 1. cv2.filter2D is working with corelation rether than convolution
#    no need to flip the kernel
# 2. Notice that kernel is 2D array - if 1d than we will get a column vector convolution
kernel = np.array([[-1, 0, +1]])
dst = cv2.filter2D(img, -1, kernel)

plt.figure(figsize=figsize)
plt.imshow(np.abs(dst), cmap="gray")
plt.colorbar()
plt.title("$f'_x$: image filtered with " + str(kernel))
plt.show()

print("kernel shape is " + str(kernel.shape))
No description has been provided for this image
kernel shape is (1, 3)

Y grad filter (no abs)

In [5]:
kernel = np.array([[-1, 0, +1]]).T
dst = cv2.filter2D(img, -1, kernel)

plt.figure(figsize=figsize)
plt.imshow(dst, cmap="gray")
plt.colorbar()
plt.title("$f'_y$: image filtered with\n " + str(kernel))
plt.show()
No description has been provided for this image

Filtering common errors

kernel dimension error

Note that you need to use a 2D array for a horizontal kernel!

In [6]:
kernel = np.array([-1, 0, +1])
dst = cv2.filter2D(img, -1, kernel)

plt.figure(figsize=figsize)
plt.imshow(np.abs(dst), cmap="gray")
plt.colorbar()
plt.title("wrong kernel dim: " + str(kernel))
plt.show()

print("kernel shape is " + str(kernel.shape))
No description has been provided for this image
kernel shape is (3,)

uint8 errors

Wrong filtering when keeping uint8 instead of float, because uint8 doesn't have negative numbers...

In [7]:
uint8_img = np.zeros((500, 500), dtype=np.uint8)
uint8_img[200:300, 200:300] = 1

kernel = np.array([[-1, 0, +1]])
dst = cv2.filter2D(uint8_img, -1, kernel)

fig, axs = plt.subplots(1, 2, figsize=(20, 20))
axs[0].imshow(uint8_img, cmap="gray")
axs[0].title.set_text("original image")
axs[1].imshow(dst, cmap="gray")
axs[1].title.set_text("uint8 WRONG filtering")

plt.show()
No description has been provided for this image