naučiť sa detekciu objektov selektívneho vyhľadávania otvoreného OpenCV (C ++ / Python)
Learn Opencv Selective Search Object Detection
Referencia:
1, https://github.com/spmallick/learnopencv
dva, https://github.com/opencv/
V tomto návode pochopíme dôležitý koncept, ktorý sa v detekcii objektov nazýva „selektívne vyhľadávanie“. Rovnako budeme zdieľať kód OpenCV v jazykoch C ++ a Python.
Detekcia objektov a rozpoznávanie objektov
Algoritmus rozpoznávania objektov rozpoznáva, ktoré objekty sa v obraze nachádzajú. Vezme celý obrázok ako vstup a výstup štítku triedy a pravdepodobnosti triedy objektov prítomných na obrázku. Napríklad štítok triedy môže byť „pes“ a pravdepodobnosť súvisiacej triedy môže byť 97%.
Na druhej strane, algoritmus detekcie objektov vám nielen povie, ktoré objekty sa nachádzajú na obrázku, ale tiež vygeneruje ohraničujúce pole (x, y, šírka, výška), ktoré označuje polohu objektu v obraze.
Jadrom všetkých algoritmov detekcie objektov je algoritmus rozpoznávania objektov. Predpokladajme, že sme natrénovali model rozpoznávania objektov, ktorý rozpoznáva psy v obrazových škvrnách. Tento model určí, či je v snímke pes. Nehovorí, kde je predmet.
Aby sme mohli lokalizovať objekty, musíme zvoliť podoblasti (záplaty) obrazu a potom na tieto obrazové záplaty použiť algoritmus rozpoznávania objektov. Poloha objektu je daná polohou obrazového bloku s vysokou pravdepodobnosťou triedy vrátenou algoritmom rozpoznávania objektov.
Najjednoduchším spôsobom generovania menších podoblastí (záplat) je metóda posuvného okna. Metóda posuvného okna má však niekoľko obmedzení. Tieto obmedzenia prekonáva trieda algoritmov nazývaná „návrhy oblasti“. Selektívne vyhľadávanie je jedným z najpopulárnejších algoritmov návrhu oblasti.
Algoritmus posuvného okna
Pri metóde posúvania okna posúvame na obraze políčko alebo okno, aby sme vybrali záplatu, a pomocou modelu rozpoznávania objektov klasifikujeme každú záplatu obrázka, na ktorú sa okno vzťahuje. Toto je dôkladné prehľadanie celého obrázka. Nielenže musíme prehľadať všetky možné polohy na obrázku, ale musíme vyhľadávať aj v rôznych mierkach. Je to tak preto, lebo modely rozpoznávania objektov sa zvyčajne trénujú v konkrétnej mierke (alebo v mierke). To vedie ku klasifikácii tisícov obrazových blokov.
Tu problém nekončí. Metóda posuvného okna je vhodná pre objekty s pevným pomerom strán, napríklad ľudské tváre alebo chodci. Obrázok je 2D projekciou 3D objektu. Vlastnosti objektu, ako napríklad pomer strán a tvar, sa výrazne líšia v závislosti od uhla nasnímaného obrázka. Metóda posuvného okna je výpočtovo veľmi nákladná, keď hľadáme viac pomerov strán.
Algoritmus návrhu oblasti
Problémy, o ktorých sme doteraz hovorili, je možné vyriešiť pomocou algoritmu návrhu regiónu. Tieto metódy používajú obrázok ako vstupné a výstupné ohraničovacie boxy zodpovedajúce všetkým opravám v obraze, ktoré sú s najväčšou pravdepodobnosťou objektmi. Návrhy v týchto oblastiach môžu byť hlučné, prekrývajú sa a nemusia úplne obsahovať objekt, ale v návrhoch v týchto oblastiach bude návrh, ktorý je veľmi blízky skutočnému objektu na obrázku. Tieto návrhy potom môžeme klasifikovať pomocou modelu rozpoznávania objektov. Návrh oblasti s vysokým skóre pravdepodobnosti je umiestnenie objektu.
Modré políčka: Falošné pozitíva Zelené políčka: Skutočné pozitívy
Algoritmy návrhu regiónov používajú segmentáciu na identifikáciu očakávaných objektov v obraze. V segmentácii zoskupujeme susedné oblasti podľa niektorých kritérií (napríklad farba, textúra atď.). Na rozdiel od metódy posuvného okna, kde nájdeme objekty na všetkých pozíciách pixelov a na všetkých mierkach, algoritmus návrhu regiónu zoskupuje pixely na menej fragmentov. Konečný počet vygenerovaných návrhov je teda mnohonásobne nižší ako v prípade metódy posuvného okna. To znižuje počet obrazových opráv, ktoré musíme klasifikovať. Tieto generované regionálne návrhy majú rôzne stupnice a pomery strán.
Dôležitou vlastnosťou metódy regionálneho návrhu je vysoká miera stiahnutia z trhu. Toto je iba zvláštne tvrdenie, že oblasť obsahujúca objekty, ktoré vidíme, musí byť v našom zozname návrhov oblastí. Na dosiahnutie tohto cieľa môže náš zoznam regionálnych návrhov nakoniec obsahovať mnoho regiónov, ktoré neobsahujú žiadne objekty. Inými slovami, algoritmus návrhu regiónu môže vygenerovať veľké množstvo falošných pozitívov, pokiaľ dokáže zachytiť všetky skutočné pozitívy. Väčšina z týchto falošných pozitívov bude odmietnutá algoritmom rozpoznávania objektov. Keď budeme mať viac falošných pozitívov a presnosť bude mať nejaký dopad, čas strávený detekciou sa zvýši. Ale vysoká rýchlosť vyvolania je stále dobrý nápad, pretože nedostatočný výber oblasti obsahujúcej skutočný objekt môže vážne ovplyvniť mieru detekcie.
Bolo navrhnutých niekoľko regionálnych odporúčaní, ako napr
1. Objektivita
2. Min-Cuts, parameter obmedzenia pre automatickú segmentáciu objektov
3. Návrhy na objekty nezávislé od kategórie
4. Náhodný prim
5. Selektívne vyhľadávanie
Spomedzi všetkých týchto metód navrhovania oblastí sa najčastejšie používa selektívne vyhľadávanie, pretože je rýchle a má vysokú rýchlosť vyvolania.
Selektívne vyhľadávanie na rozpoznávanie objektov
Čo je to selektívne vyhľadávanie?
Selektívne vyhľadávanie je algoritmus návrhu regiónu na detekciu objektu. Je navrhnutý tak, aby mal veľmi vysokú rýchlosť vyvolania. Je založený na výpočte hierarchického zoskupenia podobných oblastí na základe kompatibility farieb, textúr, veľkostí a tvarov.
Selektívne vyhľadávanie sa začína použitím metódy segmentácie na základe grafu Felzenszwalba a Huttenlochera na nadmernú segmentáciu obrazu na základe intenzity pixelov. Výstup algoritmu je uvedený nižšie. Obrázok vpravo obsahuje segmentované oblasti reprezentované plnými farbami.
Sú niektoré segmenty na tomto obrázku regionálne návrhy? Odpoveď je nie. Nemôžeme to urobiť z dvoch dôvodov:
1. Väčšina skutočných objektov na pôvodnom obrázku obsahuje 2 alebo viac segmentovaných častí
2. Pri použití tejto metódy nemožno generovať návrhy na oblasti uzavretých predmetov, ako sú taniere pokryté šálkami alebo šálky naplnené kávou
Ak sa pokúsime vyriešiť prvý problém ďalším zlúčením susedných oblastí, dostaneme sa k segmentovanej oblasti pokrývajúcej dva objekty.
Naším cieľom nie je dokonalá segmentácia. Chceme len predpovedať odporúčania v mnohých regiónoch, z ktorých niektoré by sa mali veľmi prekrývať so skutočnými cieľmi.
Selektívne vyhľadávanie používa ako počiatočné semeno metódy Felzenszwalba a Huttenlochera. Extrovertný obrázok vyzerá takto.
Algoritmus selektívneho vyhľadávania berie tieto exogénne ako počiatočný vstup a vykoná nasledujúce kroky
1. Pridajte všetky ohraničovacie rámčeky zodpovedajúce rozdeleným častiam do zoznamu regionálnych ponúk
2. Zoskupte susedné segmenty na základe podobnosti
3. Prejdite na krok 1
V každej iterácii sa tvoria väčšie fragmenty, ktoré sa pridajú do zoznamu regionálnych návrhov. Preto pri vytváraní regionálnych návrhov z menšej časti do väčšej používame prístup zdola nahor. Toto je to, čo nazývame použitie Felzenszwalbových a Huttenlocherových pravidiel na výpočet delenia úrovne.
Obrázok zobrazuje počiatočné, stredné a posledné kroky procesu hierarchickej segmentácie.
podobný
Dozvieme sa viac o tom, ako vypočítať podobnosť medzi dvoma regiónmi.
Selektívne vyhľadávanie využíva 4 miery podobnosti založené na kompatibilite farieb, textúr, veľkostí a tvarov.
Farebná podobnosť
Vypočítajte farebné histogramy 25 oblastí pre každý kanál obrázka a spojte histogramy všetkých kanálov, aby ste získali deskriptory farieb a získali 25 × 3 = 75-rozmerné deskriptory farieb.
Farebná podobnosť týchto dvoch oblastí je založená na priesečníku histogramov a dá sa vypočítať ako:
cki Je v deskriptore farieb kth hodnota histogramu koša
Podobnosť textúry
Vlastnosti textúry sa počítajú extrakciou gaussovských derivátov v 8 smeroch pre každý kanál. Pre každý smer a každý farebný kanál sa počíta 10 histogramov, aby sa získali deskriptory znakov 10 × 8 × 3 = 240-rozmerných.
Podobnosť textúry týchto dvoch oblastí sa tiež počíta pomocou priesečníka histogramov.
tki Je hodnota histogramu kth {bin} v deskriptore textúry
Podobná veľkosť
Podobnosť veľkosti podporuje skorú konsolidáciu menších regiónov. Zaisťuje, aby sa všetky regionálne odporúčania vytvorili vo všetkých častiach obrázka. Ak sa toto opatrenie podobnosti nezohľadní, jediný región pohltí všetky menšie susedné regióny jeden po druhom, takže regionálne návrhy viacerých mierok možno vygenerovať iba na tomto mieste. Podobnosť veľkosti je definovaná ako:
sisje(im) Je veľkosť obrázka (v pixeloch)
Kompatibilita tvaru
Kompatibilita tvaru meria dve oblasti ( ri s rj ) Stupeň vzájomného prispôsobenia. v prípade ri vhodné pre rj „Chceme ich zlúčiť, aby preklenuli priepasť, a ak sa navzájom ani len nedotýkajú, nemali by byť zlúčené.
Kompatibilita tvarov je definovaná ako:
sisje(BBij) Je okolo ri s rj Ohraničujúca skrinka
Konečná podobnosť
Konečná podobnosť medzi týmito dvoma oblasťami je definovaná ako lineárna kombinácia vyššie uvedených 4 podobností.
medzi nimi ri s rj Sú na obrázku dve oblasti alebo segmenty, doi∈0,1 Označuje, či sa má použiť opatrenie podobnosti.
výsledok
Implementácia selektívneho vyhľadávania v OpenCV umožňuje usporiadať tisíce regionálnych návrhov v poradí podľa objektov. Kvôli prehľadnosti zdieľame výsledky a na obrázok nakreslíme 200 - 250 políčok. Všeobecne povedané, na získanie všetkých správnych regionálnych návrhov stačí 1 000 - 1 200 návrhov.
Selektívny vyhľadávací kód
Poďme sa pozrieť na to, ako používať selektívnu segmentáciu podľa vyhľadávania implementovanú v OpenCV.
Selektívne vyhľadávanie: C ++
Nasledujúci kód je výukový program C ++ pre selektívne vyhľadávanie pomocou OpenCV. Prečítajte si komentáre, aby ste pochopili kód.
#include 'opencv2/ximgproc/segmentation.hpp' #include 'opencv2/highgui.hpp' #include 'opencv2/core.hpp' #include 'opencv2/imgproc.hpp' #include #include using namespace cv using namespace cv::ximgproc::segmentation //Program execution command: ./ssearch input_image (f|q) static void help() q)' << std::endl << 'f=fast, q=quality' << std::endl << 'Use l to display less rects, m to display more rects, q to quit' << std::endl int main(int argc, char** argv) { // If image path and f/q is not passed as command // line arguments, quit and display help message //I did not enter the command as required if (argc <3) { help() return -1 } // speed-up using multithreads // Speed up the use of multithreading setUseOptimized(true) setNumThreads(4) // read image read image Mat im = imread(argv[1]) // resize image adjust size int newHeight = 200 int newWidth = im.cols*newHeight/im.rows resize(im, im, Size(newWidth, newHeight)) // create Selective Search Segmentation Object using default parameters // Create selective search segmentation object with default parameters Ptr ss = createSelectiveSearchSegmentation() // set input image on which we will run segmentation // Set the input image we will run the segmentation ss->setBaseImage(im) // Switch to fast but low recall Selective Search method // Switch to fast but low call rate selective search method if (argv[2][0] == 'f') { ss->switchToSelectiveSearchFast() } // Switch to high recall but slow Selective Search method //Switch to high call rate, but slow selective search method else if (argv[2][0] == 'q') { ss->switchToSelectiveSearchQuality() } // if argument is neither f nor q print help message // If the last parameter is neither f nor q print help information else { help() return -2 } // run selective search segmentation on input image // Run selective search segmentation on the input image std::vector rects ss->process(rects) std::cout << 'Total Number of Region Proposals: ' << rects.size() << std::endl // number of region proposals to show // Show the suggested number of areas int numShowRects = 100 // increment to increase/decrease total number // of reason proposals to be shown // Increase/decrease the total number of reason suggestions to be displayed int increment = 50 while(1) { // create a copy of original image // Create a copy of the original image Mat imOut = im.clone() // itereate over all the region proposals // Iterate through all the suggestions of regions for(int i = 0 i if (i 0, 255, 0)) } else { break } } // show output // display output imshow('Output', imOut) // record key press // record key press int k = waitKey() // m is pressed // m is pressed if (k == 109) { // increase total number of rectangles to show by increment // Increase the total number of rectangles to display in increments numShowRects += increment } // l is pressed // l is pressed else if (k == 108 && numShowRects > increment) { // decrease total number of rectangles to show by increment // Reduce the total number of rectangle display increments numShowRects -= increment } // q is pressed // press q to exit else if (k == 113) { break } } return 0 }
Poznámka:
Chýbajúci modul ximgproc môže ísť
https://github.com/opencv/opencv_contrib Stiahnite a nainštalujte
Odkaz na kompiláciu: http://blog.csdn.net/wc781708249/article/details/78273241
Selektívne vyhľadávanie: Python
Nasledujúci kód predstavuje výukový program jazyka Python pre selektívne vyhľadávanie pomocou OpenCV 3.3. Všimnite si chybové hlásenie OpenCV 3.2 uvedené za blokom kódu. Prečítajte si komentáre, aby ste pochopili kód.
#!/usr/bin/env python # -*- coding: UTF-8 -*- ''' Usage: ./ssearch.py input_image (f|q) f=fast, q=quality Use 'l' to display less rects, 'm' to display more rects, 'q' to quit. ''' import sys import cv2 if __name__ == '__main__': # If image path and f/q is not passed as command # line arguments, quit and display help message if len(sys.argv) <3: print(__doc__) sys.exit(1) # speed-up using multithreads # Use multi-threaded acceleration cv2.setUseOptimized(True) cv2.setNumThreads(4) # read image im = cv2.imread(sys.argv[1]) # resize image newHeight = 200 newWidth = int(im.shape[1]*200/im.shape[0]) im = cv2.resize(im, (newWidth, newHeight)) # create Selective Search Segmentation Object using default parameters # Use default parameters to create selective search segment objects ss = cv2.ximgproc.segmentation.createSelectiveSearchSegmentation() # set input image on which we will run segmentation # Set the input image we will run segmentation ss.setBaseImage(im) # Switch to fast but low recall Selective Search method # Switch to fast but low callback selective search method if (sys.argv[2] == 'f'): ss.switchToSelectiveSearchFast() # Switch to high recall but slow Selective Search method # Switch to high callback, but slow selective search method elif (sys.argv[2] == 'q'): ss.switchToSelectiveSearchQuality() # if argument is neither f nor q print help message # If the parameter is neither f nor q print help information else: print(__doc__) sys.exit(1) # run selective search segmentation on input image # Run selective search segmentation on the input image rects = ss.process() print('Total Number of Region Proposals: {}'.format(len(rects))) # number of region proposals to show # Show the number of regional recommendations numShowRects = 100 # increment to increase/decrease total number # of reason proposals to be shown # Increase/decrease the total number of reason suggestions to be displayed increment = 50 while True: # create a copy of original image # Create a copy of the original image imOut = im.copy() # itereate over all the region proposals # Iterate over suggestions for all regions for i, rect in enumerate(rects): # draw rectangle for region proposal till numShowRects # Propose drawing a rectangle for the area until numShowRects if (i 0, 255, 0), 1, cv2.LINE_AA) else: break # show output cv2.imshow('Output', imOut) # record key press k = cv2.waitKey(0) & 0xFF # m is pressed if k == 109: # increase total number of rectangles to show by increment # Increase the total number of rectangles to display in increments numShowRects += increment # l is pressed elif k == 108 and numShowRects > increment: # decrease total number of rectangles to show by increment # Reduce the total number of rectangle display increments numShowRects -= increment # q is pressed elif k == 113: break # close image show window cv2.destroyAllWindows()
Varovanie pred chybou: V tomto príspevku je opravená chyba vo väzbách Pythonu pre selektívne vyhľadávanie. Takže kód Pythonu je možné použiť pre OpenCV 3.3.0, ale nie pre OpenCV 3.2.0.
Ak nechcete kompilovať OpenCV 3.3.0 a nechať si predtým zostaviť priečinok na zostavenie OpenCV 3.2.0, môžete túto chybu tiež opraviť.
Ak sa pozriete na príspevok na Github, je to len malá zmena. V súbore musíte zmeniť riadok 239
opencv_contrib-3.2.0 / modules / ximgproc / include / opencv2 / ximgproc / segmentation.hpp
// from CV_WRAP virtual void process(std::vector& rects) = 0 // to CV_WRAP virtual void process(CV_OUT std::vector& rects) = 0
Teraz znova skompilujte svoj OpenCV 3.2.0. Ak máte priečinok na zostavenie, ktorý kompiloval OpenCV už skôr, kompiláciou modulu sa spustí príkaz make.