Walid Bousseta
Walid Bousseta

Reputation: 1469

harris corner detector python

Harris corner detector

I want to implement the method of harris corner detector with python but I am stuck please give some advice. The method that I have implemented can be found HERE

import numpy as np
import matplotlib.pyplot as plt
from PIL.Image import *
import scipy
from scipy import ndimage, signal


def conv2(x, y, mode='same'):
    return np.rot90(signal.convolve2d(np.rot90(x, 2), np.rot90(y, 2), mode=mode), 2)

def harris(im):
    l, c = im.size
    k = 0.04
    imarr = np.asarray(im, dtype=np.float64)
    dx = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]], dtype=np.float64)
    dy = dx.transpose()
    mat3x3 = np.array([[-1, -1, -1], [-1, -1, -1], [-1, -1, -1]], dtype=np.float64)
    for i in range(0, (c-3), 2):
        for j in range(0, (l-3), 2):
            mat3x3[0, 0] = imarr[i, j]
            mat3x3[0, 1] = imarr[i, j+1]
            mat3x3[1, 0] = imarr[i, j+2]
            mat3x3[1, 1] = imarr[i+1, j]
            mat3x3[1, 1] = imarr[i+1, j+1]
            mat3x3[0, 0] = imarr[i+1, j+2]
            mat3x3[0, 0] = imarr[i+2, j]
            mat3x3[0, 0] = imarr[i+2, j+1]
            mat3x3[0, 0] = imarr[i+2, j+2]
            Ix = conv2(mat3x3, dx, mode='same')
            Iy = conv2(mat3x3, dy, mode='same')
            Ix2 = Ix * Ix
            Iy2 = Iy * Iy
            Ixy = Ix * Iy
            Sx2 = conv2(mat3x3, Ix2, mode='same')
            Sy2 = conv2(mat3x3, Iy2, mode='same')
            Sxy = conv2(mat3x3, Ixy, mode='same')
            Hxy = [[Sx2, Sxy], [Sy2, Sxy]]
            R = np.linalg.det(Hxy) - k*(np.power((np.linalg.eig(Hxy)), 2))
            # print(R[0, 0])
            if(R[0, 0] > 0):
                imarr[i, j] = 127
                imarr[i, j+1] = 127
                imarr[i, j+2] = 127
                imarr[i, j+3] = 127
                imarr[i+1, j] = 127
                imarr[i+1, j+1] = 127
                imarr[i+1, j+2] = 127
                imarr[i+1, j+3] = 127
                imarr[i+2, j] = 127
                imarr[i+2, j+1] = 127
                imarr[i+2, j+2] = 127
                imarr[i+2, j+3] = 127
                imarr[i+3, j] = 127
                imarr[i+3, j+1] = 127
                imarr[i+3, j+2] = 127
                imarr[i+3, j+3] = 127
    return imarr

im = open('chess.png')
em = harris(im)
plt.imshow(em, 'gray')
plt.show()

that is an exemple of what I want to do : harris exempe

Upvotes: 2

Views: 7838

Answers (2)

Walid Bousseta
Walid Bousseta

Reputation: 1469

def Harris():
    if im == None:
        msg.showerror('error', 'Ouvrire une image')
        return 0
    msg.showinfo('wait', 'Le programme traite l\'image, veuillez patienter')
    global em
    neim = imap1()
    imarr = np.asarray(neim, dtype=np.float64)
    ix = ndimage.sobel(imarr, 0)
    iy = ndimage.sobel(imarr, 1)
    ix2 = ix * ix
    iy2 = iy * iy
    ixy = ix * iy
    ix2 = ndimage.gaussian_filter(ix2, sigma=2)
    iy2 = ndimage.gaussian_filter(iy2, sigma=2)
    ixy = ndimage.gaussian_filter(ixy, sigma=2)
    c, l = imarr.shape
    result = np.zeros((c, l))
    r = np.zeros((c, l))
    rmax = 0
    for i in range(c):
        print('loking for corner . . .')
        for j in range(l):
            print('test ', j)
            m = np.array([[ix2[i, j], ixy[i, j]], [ixy[i, j], iy2[i, j]]], dtype=np.float64)
            r[i, j] = np.linalg.det(m) - 0.04 * (np.power(np.trace(m), 2))
            if r[i, j] > rmax:
                rmax = r[i, j]
    for i in range(c - 1):
        print(". .")
        for j in range(l - 1):
            print('loking')
            if r[i, j] > 0.01 * rmax and r[i, j] > r[i - 1, j - 1] and r[i, j] > r[i - 1, j + 1] \
                    and r[i, j] > r[i + 1, j - 1] and r[i, j] > r[i + 1, j + 1]:
                result[i, j] = 1
    result = np.transpose(result)
    pc, pr = np.where(result == 1)
    base = plt.gca().transData
    rot = transforms.Affine2D().rotate_deg(270)
    plt.plot(pr, pc, 'r', transform=rot + base, linestyle="None", marker="o", markersize=1)
    plt.savefig('harris_test.png')
    root_analy.geometry("1108x553+85+50")
    frame_active.configure(width=1108, height=40)
    # ---------- frame de present l'image filter------------------
    frame_image_fil = Frame(root_analy)
    frame_image_fil.configure(width=500, height=470)
    frame_image_fil.place(x=605, y=42)
    frame_image_fil.configure(borderwidth=2, relief=GROOVE)
    # --------- frame de title de image resultat ---------------
    frame_imgreslt = Frame(root_analy)
    frame_imgreslt.configure(width=500, height=40, bg='#1B3F5D')
    frame_imgreslt.place(x=760, y=512)
    frame_imgreslt.configure(borderwidth=2, relief=GROOVE)
    label_title1 = Label(frame_imgreslt, text='les point d\'intérêt', font=("Courier", 18), bg='#0F2130', foreground="#4F5459")
    label_title1.pack()
    img = open('harris_test.png')
    em = img
    img = img.resize((491, 458), ANTIALIAS)
    img = ImageTk.PhotoImage(img)
    pano = Label(frame_image_fil)
    pano.configure(image=img)
    pano.image = img
    pano.place(x=0, y=0)
    os.remove('harris_test.png')
    return 0

Upvotes: 2

Jeru Luke
Jeru Luke

Reputation: 21203

Apparently, there is no direct function available in PIL to detect corners in an image. I, however found, THIS LINK. See if it suits you.

Your best bet would be to use OpenCV's in-built functions, which give quite a good result.

THIS PAGE provides another way to find corners using scikit image python module

Upvotes: 0

Related Questions