Skip navigation

Harris-sarokdetektor

Harris sarokdetektor

A sarokdetektorok általában olyan pontokat keres a képen, ahol a gradiens minden irányban nagy. A Harris sarokdetektor egy "sarkossági" értéket jelez a képen, mivel nem minden pontról lehet eldönteni, hogy valóban sarokpont-e.

Legyen I képmátrix.Tekintsünk egy E(u,v) itenzitásváltozási függvényt [u,v] eltolással a következőképpen:

E(u,v)=x,yw(x,y)(I(x,y)I(x+u,y+v))2,

ahol w(x,y) egy ablakfüggvény I(x+u,y+v) az eltolt intenzitás, I(x,y) pedig a kép intenzitása az (x,y) pontban.

Egy f(x+u,y+v) függvényt közelíthetünk a Taylor sorfejtésével. Ebben az esetben az elsőrendű közelítést vesszük figyelembe.

I(x+u,y+v)I(x,y)uIx+vIy

Ebből következik, hogy

(I(x,y)I(x+u,y+v))2(I(x,y)I(x,y)+uIx+vIy)2=u2Ix2+2uvIxIy+v2Iy2=[uv][Ix2IxIyIxIyIy2][uv]=[uv]([Ix2IxIyIxIyIy2])[uv]

Az E(u,v) intezitásváltozási függvény tehát közelíthető az alábbi módon:

E(u,v)[uv]M[uv],

ahol M a kép deriváltjaiból számított 2×2-es mátrix:

M=x,yw(x,y)[Ix2IxIyIxIyIy2]

A w(x,y) egy súlyfüggvény (az egyszerűség kedvéért lehet konstans 1).

A sarkossági mérőszám

A fenti egyenletekből megkaphatjuk az R sarkossági mérőszámot:

R=det(M)k(trace(M))2

ahol

  • det(M) az M mátrix determinánsa, det(M)=λ1λ2
  • trace(M) az M mátrix nyoma, trace(M)=λ1+λ2
  • λ1 és λ2 pedig az M mátrix sajátértékei,
  • k egy empirikus úton meghatározott konstans érték, (k= 0.004-00.6)

Ha |R| értéke kicsi, akkor ott lapos régió van, ha R értéke nagy, akkor ott sarokpont található. Ha R értéke negatív, akkor ott él van.

A Harris sarokdetekor algoritmusa

  1. Számítsuk ki az I kép x és y irányú deriváltját. Jelölje ezeket rendre Ix és Iy.
  2. Számítsuk ki a deriváltak szorzatát minden (px,py) képpontra:
    Ixx(px,py)=Ix(px,py)Ix(px,py)Ixy(px,py)=Ix(px,py)Iy(px,py)Iyy(px,py)=Iy(px,py)Iy(px,py)
  3. Minden pixelre számoljuk ki a deriváltak összegét, Sxx-t, Sxy-t és Syy-t az adott eltolási környezeten belül.
  4. Számoljuk ki minden (x,y) pontra a H(x,y) értékét.
    H(x,y)=[Sxx(x,y)Sxy(x,y)Sxy(x,y)Sxx(x,y)]
  5. Számoljuk ki a sarkossági függvényt minden képpontra:
    R(x,y)=det(H)k(trace(H))2
  6. Küszöböljük a kapott képet valamilyen küszöbértékkel.

A Harris sarokdetektor használata

Az alábbi program az input képen keres jellemzőpontokat a Shi-Tomasi sarokdetektorral. A képet a notebook-fájl mellé érdemes elhelyezni, vagy át kell írni az elérési útvonalat.

A lépések a következők:

  1. Megnyitjuk a képet.
  2. Az RGB színes képet szürkeárnyalatosság konvertáljuk és a továbbiakban ezzel a változattal dolgozunk.
  3. Beállítjuk a detektor paramétereit (blokkméret, apertúra mérete, a k paraméter).
  4. Elvégezzük a sarokpont detektálást a cornerHarris() függvénynel. Az eredményt a cornerness képben kapjuk, amely a sarkossági válaszfüggvény értékeit tartalmazza.
  5. Meghatározzuk a minimum és maximum értékeket.
  6. Meghatározunk egy küszöbértéket.
  7. Kirajzoljuk és kimentjük a küszöbölt sarkossági képet.

import cv2
import numpy as np
from matplotlib import pyplot as plt


SOURCE_IMAGE='lisbon1.jpg'
OUTPUT_IMAGE='harris_lisbon1.jpg'

## kép beolvasása
img = cv2.imread(SOURCE_IMAGE);

## a képet szürkeárnyalatossá konvertáljuk
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

## sarokpontok keresése Harris sarokdetektorral
##  - meg kell adnunk az alábbi paramétereket:
blockSize = 2    # az ablakméret a sajátérték és sajátvektor számításhoz
apertureSize = 3 # a Sobel operátor ablakmérete
k = 0.004        # a Harris sarokdetektor paramétere (lásd a képletet a leírásban)
gray_img = np.float32(gray_img)
cornerness = cv2.cornerHarris(gray_img, blockSize, apertureSize, k)
#cornerness = cv2.normalize(cornerness,None)
cv2.imwrite('cornerness.jpg', cornerness)


## a kapott kép még csak a sarkossági válaszfüggvényt tartalmazza
## ahhoz, hogy ténylegesen sarokpontokat kapjunk küszöbölnünk kell
## kiszámoljuk a minimális és maximális sarkosságot a képen és
## határozzuk meg a küszöböt (ez képenként változhat).
minval, maxval, _, _ = cv2.minMaxLoc(cornerness)
threshold = 0.06 * maxval
print("min:" + str(minval))
print("max:" + str(maxval))
ret, corner_img = cv2.threshold(cornerness, threshold, 255, cv2.THRESH_BINARY);
cv2.imwrite(OUTPUT_IMAGE, corner_img)

plt.imshow(corner_img);
plt.title(OUTPUT_IMAGE)
plt.show()