Commit a0439dc7 authored by robin.danz's avatar robin.danz
Browse files

Canny detection work

parent 2e5080b0
Loading
Loading
Loading
Loading
+178 −45
Original line number Diff line number Diff line
import numpy as np

import matplotlib.pyplot as plt

import matplotlib.image as npimage


from scipy.ndimage import gaussian_filter
from scipy.ndimage.filters import convolve


def redFilter(img_orig):
    im = np.copy(img_orig)  # On fait une copie de l'original
    for i in range(im.shape[0]):
@@ -10,6 +17,7 @@ def redFilter(img_orig):
            im[i, j] = (r, 0, 0, a)
    return im


def blueFilter(img_orig):
    im = np.copy(img_orig)  # On fait une copie de l'original
    for i in range(im.shape[0]):
@@ -18,6 +26,7 @@ def blueFilter(img_orig):
            im[i, j] = (0, 0, b, a)
    return im


def greenFilter(img_orig):
    im = np.copy(img_orig)  # On fait une copie de l'original
    for i in range(im.shape[0]):
@@ -26,6 +35,7 @@ def greenFilter(img_orig):
            im[i, j] = (0, v, 0, a)
    return im


def cyanFilter(img_orig):
    im = np.copy(img_orig)  # On fait une copie de l'original
    for i in range(im.shape[0]):
@@ -34,6 +44,7 @@ def cyanFilter(img_orig):
            im[i, j] = (r, 1, 1, a)
    return im


def magentaFilter(img_orig):
    im = np.copy(img_orig)  # On fait une copie de l'original
    for i in range(im.shape[0]):
@@ -42,6 +53,7 @@ def magentaFilter(img_orig):
            im[i, j] = (1, v, 1, a)
    return im


def yellowFilter(img_orig):
    im = np.copy(img_orig)  # On fait une copie de l'original
    for i in range(im.shape[0]):
@@ -52,7 +64,7 @@ def yellowFilter(img_orig):


def blackFilter(img_orig):
    im = yellowFilter(img_orig) # On fait une copie de l'original
    im = np.copy(img_orig)  # On fait une copie de l'original
    for i in range(im.shape[0]):
        for j in range(im.shape[1]):
            r, v, b, a = im[i, j]
@@ -61,51 +73,172 @@ def blackFilter(img_orig):
    return im


def gaussian_kernel(size, sigma=1):
    size = int(size) // 2
    x, y = np.mgrid[-size:size+1, -size:size+1]
    normal = 1 / (2.0 * np.pi * sigma**2)
    g = np.exp(-((x**2 + y**2) / (2.0*sigma**2))) * normal

    return g


def sobel_filters(img):
    Kx = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]], np.float32)
    Ky = np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]], np.float32)

    Ix = convolve(img, Kx)
    Iy = convolve(img, Ky)

    G = np.hypot(Ix, Iy)
    G = G/G.max()*255
    theta = np.arctan2(Iy, Ix)

    return (G, theta)


def non_max_suppression(img, D):
    M, N = img.shape
    Z = np.zeros((M, N), dtype=np.int32)
    angle = D * 180. / np.pi
    angle[angle < 0] += 180

    for i in range(1, M-1):
        for j in range(1, N-1):
            try:
                q = 255
                r = 255

               # angle 0
                if (0 <= angle[i, j] < 22.5) or (157.5 <= angle[i, j] <= 180):
                    q = img[i, j+1]
                    r = img[i, j-1]
                # angle 45
                elif (22.5 <= angle[i, j] < 67.5):
                    q = img[i+1, j-1]
                    r = img[i-1, j+1]
                # angle 90
                elif (67.5 <= angle[i, j] < 112.5):
                    q = img[i+1, j]
                    r = img[i-1, j]
                # angle 135
                elif (112.5 <= angle[i, j] < 157.5):
                    q = img[i-1, j-1]
                    r = img[i+1, j+1]

                if (img[i, j] >= q) and (img[i, j] >= r):
                    Z[i, j] = img[i, j]
                else:
                    Z[i, j] = 0

            except IndexError as e:
                pass

    return Z

def threshold(img, lowThresholdRatio=0.05, highThresholdRatio=0.09):

    highThreshold = img.max() * highThresholdRatio
    lowThreshold = highThreshold * lowThresholdRatio

    M, N = img.shape
    res = np.zeros((M, N), dtype=np.int32)

    weak = np.int32(25)
    strong = np.int32(255)

    strong_i, strong_j = np.where(img >= highThreshold)
    zeros_i, zeros_j = np.where(img < lowThreshold)

    weak_i, weak_j = np.where((img <= highThreshold) & (img >= lowThreshold))

    res[strong_i, strong_j] = strong
    res[weak_i, weak_j] = weak

    return res

def hysteresis(img, weak=25, strong=255):
    """
    if img.dtype != np.uint8: # Si le résultat n'est pas un tableau d'entiers
        img = (img * 255).astype(np.uint8)
    """
    M, N = img.shape  
    for i in range(1, M-1):
        for j in range(1, N-1):
            if (img[i,j] == weak):
                try:
                    if ((img[i+1, j-1] == strong) or (img[i+1, j] == strong) or (img[i+1, j+1] == strong)
                        or (img[i, j-1] == strong) or (img[i, j+1] == strong)
                        or (img[i-1, j-1] == strong) or (img[i-1, j] == strong) or (img[i-1, j+1] == strong)):
                        img[i, j] = strong
                    else:
                        img[i, j] = 0
                except IndexError as e:
                    pass
    return img


if __name__ == "__main__":
    # Lecture de l'image
img = npimage.imread("res/lemon.png")
    img = npimage.imread("res/dog.png")
    img = np.array(img, copy=True)
    rgb_weights = [1, 1, 1]
    img_rescale = np.dot(img[..., :3], rgb_weights)
    
    #Plot RGB
    
    plt.subplot(221)
    plt.title("Base picture")

    imgplot = plt.imshow(img)

    plt.subplot(222)
    plt.title("Red filter")
    imgplot = plt.imshow(redFilter(img))

    plt.subplot(223)
    plt.title("Green filter")
    imgplot = plt.imshow(greenFilter(img))

    plt.subplot(224)
    plt.title("Blue filter")
    imgplot = plt.imshow(blueFilter(img))

    plt.show()    

    #Plot CNY
    plt.subplot(221)
    plt.title("Base picture")
    imgplot = plt.imshow(img)

    plt.subplot(222)
    plt.title("Cyan filter")
    imgplot = plt.imshow(cyanFilter(img))

    plt.subplot(223)
    plt.title("Magenta filter")
    imgplot = plt.imshow(magentaFilter(img))

    plt.subplot(224)
    plt.title("Yellow filter")
    imgplot = plt.imshow(yellowFilter(img))

    plt.show()

    #Plot black & white
    imgplot = plt.imshow(blackFilter(img))
plt.show()






    plt.title("B&W filter")
    plt.show(block = "false");
    
    #Plot canny
    
    imgSmooth = convolve(img_rescale, gaussian_kernel(5, 1))
    gradientMat, thetaMat = sobel_filters(imgSmooth)

    G, t = sobel_filters(imgSmooth)
    nonMaxImg = non_max_suppression(G, t)

    imgFinal = hysteresis(threshold(nonMaxImg))

    imgplot = plt.imshow(imgFinal, cmap="gray")
    plt.title("Canny edge detection")
    plt.show(block = "false")

res/dog.png

0 → 100644
+140 KiB
Loading image diff...

res/mario.png

0 → 100644
+594 KiB
Loading image diff...