Az objektum leírására szolgálnak Mire jók? Sokszor maga a jellemző az érdekes: pl.: átlagosan mekkora egy szitakötő szárnyfesztávolsága? Tömörítés pl.: ha körszerű objektumokat tartalmaz a kép, elegendő lehet a középpontok és a sugár tárolása Objektumok csoportosítására Az objektum összes pontja gyakorta lényegtelen. Kiragadjuk azokat a tulajdonságokat, mely alapján a különböző csoportba tartozó objektumok megkülönböztethetők.
Cél: egy halmaz elemeinek K > 1 részhalmazra való felbontása. Halmazelemek: a kép összes képpontja Jellemzővektor: a pixelek CIE Lab színtérben vett színvektora Hasonlóság: a jellemzővektorok távolsága alapján Használt klaszterező: Kmeans, véletlenszerű középpontokkal
Olvassuk be a kutyás képet (színesben): https://arato.inf.unideb.hu/szeghalmy.szilvia/kepfeld/img/kutya.jpg Konvertáljuk (CIE) Lab színtérbe: Alakítsuk a képet CV_32F típusúvá, az értékeket [0, 1] tartományba skálázva rgb.convertto( rgbf, CV_32F, 1.0/255.0); Váltsuk át a színtért: cvtcolor(rgbf, lab, COLOR_BGR2Lab); Érjük el, hogy egy kép helyett, egy pontmátrixunk legyen, melynek minden eleme 3 értéket tartalmaz: reshape fv. segítségébel változtathatjuk a mátrix fejlécét (de a méret nem változhat) Mat reshape( uj_csatorna_szam/0, uj_sorok_szama ); A cél 3 jellemző (=3 csatorna) és az összes képpont külön sorba helyezése: cv::mat festures = lab.reshape( 3, img.rows * img.cols );
Hívjuk meg a Kmeans függvényt: void kmeans(jellemzo_mátrix, klaszterek_száma (K), pontok_klasztere, leállási_kritérium, próbálkozások, középpont_választás, középpontok); Mat labelvec; //eredmény címkék Mat centers; //klaszter középpontok TermCriteria crit(termcriteria::eps + TermCriteria::COUNT, 10, 1.0); int K = 3; //képtől és feladattól függő klaszterszám kmeans( features, K, labelvec, crit, KMEANS_RANDOM_CENTERS, centers); A címkék vektorát formázzuk át 2D-s képpé: Mat label = labelvec.reshape( 0, rgb.rows ); //A 0 jelenti, hogy a csatornák számát nem változtatjuk
Hozzunk létre egy függvényt a megjelenítéshez: A centroids mátrix float típusú. Sorainak száma a klaszterek száma. Oszlopainak száma a jellemzők száma, ami jelen esetben 3 (Lab színtérben lévő koordináták ). void drawkmeans(cv::mat& dest, const cv::mat labels, const cv::mat centroids){ hozd létre az eredményképet 3 csatornás valós(!) képként járd be a labels mátrixot int s = az aktuális címkével. (a labels mátrix int típusú elemeket tartalmaz) a centroid mátrix s. sorában lévő három érték legyen a dest aktuális pontjának színe } Hívd meg ezt a függvényt a korábbi kódrészt folytatva Az erdményképet konvertáld vissza rgb színtérbe (cvtcolor) Konvertáld vissza CV_8U bitmélységűvé (convertto) Alkalmazz rá egy mediánszűrést.
Töltsd le a sejtek.zip csomagot https://arato.inf.unideb.hu/szeghalmy.szilvia/kepfeld/img/sejtek.zip Az állomány 91 fájlt tartalmaz. Minden kép egyetlen sejttípus képét mutatja. Összesen három féle sejt van a mappába. Cél: a képek szétválogatása sejttípus szerint (mentés 1-es, 2-es, 3-as mappába). Találj olyan jellemzőket, mely segíthet elválasztani a háromféle sejttípust Néhány egyszerű példa: eredeti vagy transzformált kép átlagos intenzitás, szórása Vec4d m, stdv; //4 csatornás képre számolja, m[0] kell a szürkeskálás képnél meanstddev(img2, m, stdv); vagy Scalar m, stdv; meanstddev(img2, m, stdv); küszöbölés utáni objektumok száma, alakja, előtér területe
Hozz létre egy jellemzőmátrixot (CV_32F) sorok száma: a képek száma oszlopok száma: az általad számolni kívánt jellemzők száma Olvasd fel sorban a képeket, közben pedig: Számold ki az adott képre vonatkozó jellemzőket Tárold el a mátrix egy sorában a számolt értékeket Normalizáld a jellemzőmátrixot (minden egyes jellemzőnél [0, 1] tartományba skálázzuk az értékeket) Járd végig a mátrix oszlopait mat.col( oszlop_idx ) kifejezéssel lekérhetsz egy teljes oszlopot Hívd meg az oszlopra a normalize függvényt (az src és a dest is a lekért oszlop): normalize( src, dest, 0.0, 1.0, NORM_MINMAX, CV_32FC1);
Hívd meg a kmeans függvényt cv::mat label, centers; TermCriteria crit(termcriteria::eps + TermCriteria::COUNT, 10, 1.0); int K = 3; //3 féle sejttípus van cv::kmeans(features, K, label, crit, 3, KMEANS_RANDOM_CENTERS); Olvasd fel újra a képeket, és a label mátrix alapján mentsd el őket a sejttípusnak megfelelő könyvtárba.
Kiindulási pont: a leírni kívánt objektum Például: körvonal, maszk, maszk alatti képrész Terület: contourarea(kontúr, orientáció); Kerület: arclength(kontúr, zárt-e); Befoglaló téglalap: boundingrect(kontúr); Minimális területű befoglaló téglalap: RotatedRect minarearect(kontúr); Befoglaló ellipszis: RotatedRect fitellipse(kontúr) Befoglaló kör: minenclosingcircle(inputarray kontúr, Point2f& kp, float& sugar);
konvex burok kerülete konvexitás = objektum kerülete cv::convexhull(contour, convhull, false, true ); cirkularitás = terület vagy 4π terület kerület 2 kerület 2 (körre maximális) kompaktság = kerület2 terület vagy 4 terület π átmérő vagy 4π terület átmérő átmérő = max d(p, q) p,q C ekvivalensköratmerő = 2 terület π C: kontúr szálhossz = 0.25(kerület + kerület 2 16 terület) szálszelesség = 0.25(kerület kerület 2 16 terület) excentricitás = főtengely hossza melléktengely hosza Tengelyek meghatározása pl. a befoglaló ellipszis alapján vagy a leghosszabb obj-n belüli szakaszt véve főtengelynek, és arra merőleges leghosszabbat melléktengelynek.