Skip navigation

Alakjellemzők számítása

Alakjellemzők számítása kontúr alapján

cv2.findContours() által visszaadott eredményt felhasználva további számításokat végezhetünk a reprezentált alakzaton.

Figyeljünk arra, hogy a cv2.findContours() függvény kontúrok egy listáját adja vissza, a feldolgozó függvények viszont egy-egy kontúrral dolgoznak. Vagyis célszerű például ciklussal bejárni a lista elemeit feldolgozáskor.

Néhány példa:

retval = cv2.contourArea(contour, oriented)

Kontúr által közrezárt terület.

Ha az oriented paraméter True, akkor előjeles eredményt kapunk a kontúr körüljárási irányától függően. False az alapértelmezett.

Megjegyzés: a függvény a kontúr által közrezárt teljes területet adja eredményül, nem a benne foglalt objektumpontok számát! Ez üreges objektumok esetén nem ugyanaz. Ha az objektumhoz tartozó objektumpontok darabszámát szeretnénk megkapni, akkor:

  • Érdemesebb lehet összefüggő komponenseket keresni a kontúrok helyett.
  • Egy másik megoldás, ha a kontúr által közrezárt területből kivonjuk a benne foglalt kontúrok által közrezárt területek összegét. Ekkor csak a közvetlen gyermek kontúrokat kell figyelembe venni, azok gyermekeit nem.
retval = cv2.arcLength(contour, closed)

Kontúr hossza.

A closed értéke legyen True. (A függvény pontlistákra is működik, nem csak kontúrokra, ott szükség lehet a False értékre is.)

hull = cv2.convexHull(points[, hull[, clockwise[, returnPoints]]]) Konvex burok meghatározása: minimális területű befoglaló poligon, amely konvex.
retval = cv2.isContourConvex(contour) Konvexitás vizsgálat, logikai eredménnyel.
x, y, w, h = cv2.boundingRect(contour) Álló helyzetű befoglaló téglalap meghatározása. A bal felső sarok és méret értékeket kapjuk vissza egész típusú számokként.
rect_center, rect_size, rect_angle = cv2.minAreaRect(contour)

Legkisebb területű (forgatott) befoglaló téglalap.

Eredményül megkapjuk a téglalap középpont koordinátáját, a méretét (szélesség és magasság), valamint az elforgtási szögét. Minden érték lebegőpontos típusú.

Ha a téglalapot a képmátrixba szeretnénk rajzolni, akkor meg kell határozni a 4 csúcspont egész típusú koordinátáit. Ebben segít a cv2.boxPoints() függvény és a Numpy:

box = cv2.boxPoints((rect_center, rect_size, rect_angle))
box = np.int0(box)
cv2.drawContours(im, [box], 0, (0, 0, 255), 2)

Angol nyelvű OpenCV dokumentáció

További alakjellemzők számítása

Számos további alakjellemzőt számíthatunk még, amikre az OpenCV nem ad közvetlen megoldást.

Rektangularitás (téglalap-szerűség)

A jellemző azt mutatja, hogy az alakzat mennyire hasonlít téglalapra. A legegyszerűbb számítási módja az alábbi:

rektangularitás = objektum_terület / legkisebb_területű_befoglaló_téglalap_terület

Értéke téglalap esetén 1, amely csökken az eltérés növekedésével. A számítási mód hátránya, hogy a kerület menti kis kiugrások nagy eltérést okoznak. További módszereket találunk az alábbi cikkben:

Kompaktság

Számítási módja:

kompaktság = (kerület)2 / terület

Cirkularitás (körszerűség)

cirkularitás = 1 / kompaktság = terület / (kerület)2

Értéke kör esetén maximális: r2π / (2rπ)2 = 1 / 4π ≈ 0,08

Feladat

Bővítsük ki a 11_03_findContours.py példaprogramot!

  • Az egyes kontúrokra számítsuk ki is írjuk is ki a konzolra az alakjellemző értékeket (kerület, terület, rektangularitás, körszerűség)!
  • A befoglaló téglalapot és a legkisebb területű elforgatott befoglaló téglalapokat rajzoljuk rá a képre!

Összefüggő komponensek statisztikai adatokkal

A komponensdetektálás egy másik változatával statisztikát is kapunk a komponensekhez.

retval, labels, stats, centroids = cv.connectedComponentsWithStats( image[, labels[, stats[, centroids[, connectivity[, ltype]]]]] )

A retval és a labels megegyezik az eredeti cv2.connectedComponents() függvényhíváséval.

A stats tömb tartalma:

  • Az adott indexű komponens befoglaló téglalapjának bal felső sarokpontja, szélessége és magassága.
  • A komponenst alkotó képpontok száma.
  • Ezekre az indexekre konstans számok helyett a cv2.CC_STAT_LEFTcv2.CC_STAT_TOPcv2.CC_STAT_WIDTHcv2.CC_STAT_HEIGHT, és cv2.CC_STAT_AREA konstansokkal is hivatkozhatunk. Pl. az 1 indexű komponens területe esetén area = stats[1][cv2.CC_STAT_AREA].
  • Megjegyzés: A függvény a háttérpontok statisztikai adatait is visszaadja, ezt kapjuk a stats[0] és centroids[0] elemekben! Fontos, hogy itt az összes háttérpont adata szerepel, amelyek nem is feltétlenül összefüggőek (például üreges objektumok esetén az izolált üregekben található háttérpontok is számítanak).

centroids tömb tartalma:

  • Az adott indexű komponens súlypontjának koordinátái. Ezek lebegőpontos számértékek, és nem biztos, hogy az adott képmátrix pozíción komponenshez tartozó képpont van (üreges objektum esetén például)!

A FrenchCardsShapes.png képre eredményül a következő stats és centroids tömböket kapjuk:

Kompenensek száma: 5

stats:
[[ 0 0 500 500 162660]
[ 13 12 171 223 19646]
[ 282 13 191 218 23782]
[ 18 269 161 219 16637]
[ 269 270 218 217 27275]]


centroids:
[[243.09058158 251.19901635]
[ 98.06337168 135.87569989]
[377.72327811 91.96034816]
[ 98.03414077 377.77363707]
[377.3904308 380.3311824 ]]

Feladat

Hajtsuk végre az alábbi lépéseket:

  • car_numberplate_rs.jpg képen hajtsunk végre adaptív küszöbölést, amely önálló komponensekként megtartja a rendszámtábla betűit és számait. (cv2.THRESH_BINARY_INV konstanst kell használni, mert a betűk és számok sötét színűek!)
  • Hajtsunk végre kontúrkeresést a küszöbölt képen.
  • Menjünk végig a kontúrokon, és azokat adjuk hozzá egy új kontúr listához, amelyek közrezárt területe 200 és 800 képpont között van! (Kiindulhatunk a 11_03_findContours.py példaprogram kontúrbejárásából.)
  • A megfelelő méretű kontúrok kitöltött területeit rajzoljuk bele az eredeti színes képbe sárga színnel!
  • Próbáljunk további, kontúrjellemzőkön alapuló szűréseket végezni, hogy kevesebb hamis detekció maradjon! (Pl. befoglaló téglalap szélesség / magasság aránya, stb.)

További feladatok

Oldjuk meg úgy is az előző feladatot, hogy kontúrok helyett összefüggő komponenseket detektálunk, és azok statisztikai információi alapján végezzük el a szűrést! Miben különbözik a két eredmény?

Módosítsuk úgy a szegmentálást, hogy a kék színű objektumokat kapjuk eredményül (lásd a küszöbölés és vágás színes képeken részben, vagy végezhetünk színhasonlóságon alapuló szegmentálást is). Ha szükséges, morfológiai műveletekkel javítsunk a komponensek összefüggőségén (statisztikai szűrők részben az "egy lehetséges megoldás" kép). Az eredmény képen szűrjük a komponenseket méret és körszerűség alapján, hogy csak a matrica maradjon!

Keressünk más képeket, amelyen sokszögek és körök szegmentálhatók! Rektangularitás és körszerűségi értékek alapján rendezzük csoportokba az alakzatokat (például egyforma színnel színezzük az egyezőket)!

Kontúr hierarchia és méret feladat

Készítsünk programot, amely a contour_test_3.png bemeneti képen detektált kontúrokat szűri az alábbiak szerint:

  • A kontúr által közrezárt terület nagyobb mint 1000 képpont.
  • Összefüggő komponensek esetén csak a külső kontúrt tartjuk meg, az esetlegesen benne található üreghez tartozó belső kontúrt nem, hiába lenne elegendően nagy a közrezárt területe.

A kritériumokat teljesítő kontúrokat ábrázoljuk vörös színnel a képbe rajzolva.

Ötletcv2.RETR_CCOMP és szülő hierarchia index érték vizsgálat.