A kép (I) intenzitástartományt folytonos tartományokra osztjuk. Az eredményképen minden egyes tartományhoz egyetlen (egyedi) értéket rendelünk. Egy (k) küszöb esetén [0, 1] intenzitástartományt feltételezve (v 2 v 2 ): I p = ቊ v 1, ha I p < k, különben v 2 Küszöbsorozat (0 < k 1 < k 2 < k n 1 < 1) esetén [0, 1] intenzitástartományt feltételezve (a v i sorozat a tartományokhoz rendelt, különböző értékeket jelöli): v 1, ha k 0 I p < k 1 I p = v 2, ha k 1 I p < k 2 v n, ha k n 1 I p 1
A küszöböléshez hasonlóan folytonos részekre osztjuk a kép (I) intenzitástartományát, azonban nem minden tartományhoz rendelünk új értéket. Pl.: egy sávon belül meghagyjuk az eredeti értékeket. Egy (k) küszöb esetén [0, 1] intenzitástartományt feltételezve: I p = ቊ 0, ha I p < k I(p), különben Sávkivágás 0 < k 1 < k 2 < 1 küszöbértékek esetén [0, 1] intenzitástartományt feltételezve: I p = ቊ I p, ha k 1 I p k 2 0, különben
threshold(inputarray src, OutputArray dest, double kuszob, double maxertek, int eljaras ); Küszöbölés: 1, ha src p kuszob THRESH_BINARY : dest p = ቊ 0, különben 0, ha src p kuszob THRESH_BINARY_INV : dest p = ቊ 1, különben THRESH_OTSU : a küszöbértéket automatikus módon határozza meg küszöb: az az érték, amelynél az előtérhez ill. a háttérhez sorolt pontok intenzitásértékeinek szórása (előtér_szórása + háttér_szórása) minimális. Vágás pl.: maxvalue, ha src p kuszob THRESH_TRUNC : dest p = ቊ src(p), különben THRESH_TOZERO : dest p = ቊ src(p), ha src p kuszob 0, különben
Tartomány kiválasztása (sávkijelölés): inrange(inputarray src, Scalar kuszob1, Scalar kuszob2, OutputArray dest); Küszöbölés mátrix operátorokkal dest = src > kuszob dest = src <= kuszob Kombinálható bitoperátorokkal: dest = (src < 100) (200 < src)
Készíts egy programot, mely különböző küszöbértékek (20, 40, 60,... ) mellett küszöböli a képet: https://arato.inf.unideb.hu/szeghalmy.szilvia/kepfeld/img/sejtek.png Az eredmények összevetésénél előnyös, ha külön-külön ablakokban jelenítjük meg az eredményt. Az ablakok elrendezéséről a következő módon gondoskodhatsz: Ciklus: Hozz létre egy ablakot az alábbi utasítással. Az ablaknévben szerepeljen a küszöbérték. namedwindow(ablaknev, WINDOW_NORMAL); Küszöböld a képet és jelenítsd meg az ablakban. Méretezd át az ablakot (ne a képet) egy előre rögzített méretre (pl: 300x300). resizewindow Mozgasd el úgy az ablakot, hogy ne kerüljön rá az előző ablakokra. movewindow Várakoztatás billentyűzet leütésre.
Bizonyos problémáknál jól meghatározható, hogy az előtér a kép hány százalékát teszi ki. (pl. tesztek, űrlapok feldolgozása) Emeljük folyamatosan a küszöböt és figyeljük az arányt? => több százszor is bejárhatjuk a képet Helyette: járjuk be egyszer és készítsünk egy hisztogramot A kumulált hisztogram i. eleme megadja, hogy hány pont volt a képen, ami az i értékű vagy annál sötétebb. Töltsd le a következő képet és olvasd be szürkeskálában: https://arato.inf.unideb.hu/szeghalmy.szilvia/kepfeld/img/scanned3.png Hozz létre egy hisztogramot a világosságértékek alapján Ha az előző leírás alapján nem megy, ugorja a következő diára. Kezd el a tömb elejétől összegezni a tömböt: for(int i = 0; i<histo.rows; ++i) Amint az összeg és az összes képpont hányadosa nagyobb, mint 0.1, küszöbölj i-vel és lépj ki a ciklusból.
calchisto( InputArrayOfArrays kepek, ); const vector<int> csatornak, InputArray maszk, const vector<int> hiszto_meretek, const vector<float> hiszto_tartomanyok,//alsóhatár,felső határ,... bool akkumlalt Magyar fordítás: kepek: vector<mat> struktúrába "csomagolt" képek (sokszor csak 1) csatornak: melyik kép, mely csatornája legyen használva (a számozás folytonos, tehát ha az 1. kép 3 csatornás, akkor a második kép 0. csatornája a 3-as, 1. csatornája a 4-es stb.) maszk: egy fekete/fehér (CV_8UC1) kép, ahol fehér, azt veszi figyelembe a többi képen a hisztoszámítás során. (ha ki akarod hagyni: noarray() ) hiszto_meretek: pl. szürkeskálánál 256 különböző érték van, de előfordulhat, hogy nem akarunk ennyi szürkeségi szintet. hiszto_tartomanyok: pl. 8UC3-s RGB kép R, G, és B csatornájánál is [0, 255], de pl. 8UC3-s HSV kép H csatornája csak [0, 179]. Ne feledd összehangolni a hiszto_merettel! akkumlalt: ha true-ra állítod, akkor a képek között nem nullázza le a hisztogram tömböt.
vector<mat> kepek; kepek.push_back(img); // egy képet használunk vector<int> csatornak; csatornak.push_back(0); //a képnek a 0. csatornáját használjuk vector<int> hiszto_meretek; hiszto_meretek.push_back(256); //szürkeárnyalatok száma vector<float> hiszto_tartomanyok; hiszto_tartomanyok.push_back(0.0f); //hol kezdődik a tartomány hiszto_tartomanyok.push_back(255.f); //meddig tart //accumlate: marad false (nullázza a hisztogrammot) calchist(kepek, csatornak, noarray(), histo, hiszto_meretek, hiszto_tartomanyok, false);
Lokális környezetre értelmezett adaptivethreshold( InputArray src, OutputArray dest, double maxval, int adaptivmethod, int thresholdmethod, int block_size, double C); thresholdmethod: THRESH_BINARY THRESH_BINARY_INV adaptivemethod : ADAPTIVE_THRESH_MEAN_C (küszöb = a blokk alatti pontok intenzitásának átlaga C) ADAPTIVE_THRESH_GAUSSIAN_C (küszöb = a blokk alatti pontok súlyozott átlaga - C)
A feladatod egy GI-s hallgató által fényképezett régi adatszerkezet zh küszöbölése. https://arato.inf.unideb.hu/szeghalmy.szilvia/kepfeld/img/zh.jpg Az eredményképen a szöveg fekete háttér előtt, fehérrel jelenjen meg. Az ablak méretét és az átlagértékből való levonást a felhasználó választhassa meg. Trackbar létrehozása (ha cikluson belül használod, akkor nem szükséges eseménykezelőt írni): int sugar = 20;... createtrackbar("kuszob:", "zh", &sugar, 255);
Eseménykezelő: void onchange_adthreshold(int pos, void* userdata){ } Mat src = *(cv::mat*)userdata; Mat dest; //kuszobold a képet //jelenítsd meg az eredményt (dest) Trackbar hozzáadása a "zh" ablakhoz, összerendelés az eseménykezelővel: Mat img = imread(<kép_elérési_út>, IMREAD_GRAYSCALE);... int sugar = 20; createtrackbar("sugar:", "zh", &sugar, 20, onchange_adthreshold, &img);... waitkey(0);