index

Problem 2.1

1. Define edge and provide examples to illustrate the concept.

Edges are characterized by a rapid variation in the intensity of the pixels. Fig.1 represents the brightness profile along a horizontal blue line in image, which clearly shows a sudden decrease in the brightness of the pixels.

pics/edge_intensity.png

with following implementation

import skimage.io as io
import skimage.color as color
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt

def convert_to_rgb_format(img):
    if img.shape[2] == 4:
        img = color.rgba2rgb(img)
    return img


def convert_to_gray_scale(img):
    return color.rgb2gray(img)

img = io.imread("./sky.png")

img = convert_to_rgb_format(img)

g = convert_to_gray_scale(img)

cut = 600
profil = g[cut, :]

plt.figure(figsize=(10, 5)) 

plt.subplot(1, 2, 1)  
plt.plot(profil, "b")  
plt.title("Brightness profile")  

plt.subplot(1, 2, 2) 
plt.imshow(g, cmap="gray")  
plt.plot((0, g.shape[1]), (cut, cut), "b")  
plt.title("City")  

plt.show()


2. Explain how derivatives are utilized for edge detection

with visual examples

an edge can be detected by analyzing the first derivative of the intensity profile, taken perpendicular to the edge. Similarly, an edge can be detected by determining the zero crossing of the second derivative.

since image depends on two dimensions, we use partial derivatives

and gradient with finite differences

and second order derivative, Laplacian

this is the illustration of application of first and second order derivatives with forward difference

pics/bright_der.png

with implementation

import numpy as np
import skimage.io as io
import skimage.color as color
import matplotlib

matplotlib.use("TkAgg")
import matplotlib.pyplot as plt


def convert_to_rgb_format(img):
    if img.shape[2] == 4:
        img = color.rgba2rgb(img)
    return img


def convert_to_gray_scale(img):
    return color.rgb2gray(img)


def grad_f(y):
    grd = [0 for _ in range(y.shape[0])]
    for i in range(y.shape[0] - 1):
        grd[i] = y[i + 1] - y[i]
    return np.array(grd)


img = io.imread("./sky.png")

img = convert_to_rgb_format(img)

g = convert_to_gray_scale(img)

cut = 600
profil = g[cut, :]

y = np.array(profil)

grd = grad_f(y)

grd_2 = grad_f(grd)

fig, axs = plt.subplots(1, 3, figsize=(15, 5))


axs[0].plot(y, color="blue")
axs[0].set_title("initial brigtness intensity")


axs[1].plot(grd, color="blue")
axs[1].set_title("first order derivative")


axs[2].plot(grd_2, color="blue")
axs[2].set_title("second order derivative")

plt.tight_layout()
plt.show()

and this is the comparison between original image and gray scaled image after computing derivative

applied_derivative.png

with following implementation

import numpy as np
import skimage.io as io
import skimage.color as color
import matplotlib

matplotlib.use("TkAgg")
import matplotlib.pyplot as plt


def convert_to_rgb_format(img):
    if img.shape[2] == 4:
        img = color.rgba2rgb(img)
    return img


def convert_to_gray_scale(img):
    return color.rgb2gray(img)


def grad_f(y):
    grd = [0 for _ in range(y.shape[0])]
    for i in range(y.shape[0] - 1):
        grd[i] = y[i + 1] - y[i]
    return np.array(grd)


def compute_grad(g):
    n = g.shape[0]
    for i in range(n):
        clac = grad_f(g[i])
        g[i] = clac
    return g


img = io.imread("./sky.png")

img = convert_to_rgb_format(img)

g = convert_to_gray_scale(img)


M = compute_grad(g)

print(M)

fig, axs = plt.subplots(1, 2, figsize=(10, 5))


axs[0].imshow(img)
axs[0].set_title("original image")


axs[1].imshow(M, cmap="gray")
axs[1].set_title("applied derivative after gray scaling")

plt.tight_layout()
plt.show()

investigate impact of truncation error in finite differences formula

to investigate impact of truncation errors we can calculate gradient and Laplacian for multiple finite differences formulas compare results by visualizing and calculate relative errors

forward difference

backward difference

central difference

from the image below we can see that central difference yields more accurate result, rate of intensity change matches the picture more accurately with central difference.

pics/diff_types.png

with relative errors

Relative error between forward and backward 6.167518521609531
Relative error between forward and central 3.0837592608047655
Relative error between backward and central 3.0837592608047655

and implementation

import numpy as np
import skimage.io as io
import skimage.color as color
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt

def convert_to_rgb_format(img):
    if img.shape[2] == 4:
        img = color.rgba2rgb(img)
    return img


def convert_to_gray_scale(img):
    return color.rgb2gray(img)


def forward_f(y):
    grd = [0 for _ in range(y.shape[0])]
    for i in range(y.shape[0] - 1):
        grd[i] = y[i + 1] - y[i]
    return np.array(grd)


def backward_f(y):
    grd = [0 for _ in range(y.shape[0])]
    for i in range(1, y.shape[0]):
        grd[i] = y[i] - y[i - 1]
    return np.array(grd)


def central_f(y):
    grd = [0 for _ in range(y.shape[0])]
    for i in range(1, y.shape[0] - 1):
        grd[i] = (y[i + 1] - y[i - 1]) / 2
    return np.array(grd)


def relative_error(x, y):
    return np.linalg.norm(x - y)

img = io.imread("./sky.png")

img = convert_to_rgb_format(img)

g = convert_to_gray_scale(img)

cut = 600
profil = g[cut, :]

y = np.array(profil)

f_y = forward_f(y)
b_y = backward_f(y)
c_y = central_f(y)

print(f"Relative error between forward and backward {relative_error(f_y,b_y)}")
print(f"Relative error between forward and central {relative_error(f_y,c_y)}")
print(f"Relative error between backward and central {relative_error(b_y,c_y)}")

fig, axs = plt.subplots(1, 3, figsize=(15, 5))

axs[0].plot(f_y, color="blue")
axs[0].set_title("forward difference")


axs[1].plot(b_y, color="blue")
axs[1].set_title("backward difference")


axs[2].plot(c_y, color="blue")
axs[2].set_title("central difference")

plt.tight_layout()
plt.show()