Úvod do OpenCV s Java

1. Úvod

V tomto výučbe to urobíme Naučte sa, ako nainštalovať a používať knižnicu počítačového videnia OpenCV a aplikovať ju na detekciu tváre v reálnom čase.

2. Inštalácia

Ak chcete v našom projekte používať knižnicu OpenCV, musíme pridať opencv Zlá závislosť na našej pom.xml:

 org.openpnp opencv 3.4.2-0 

Pre používateľov Gradle budeme musieť pridať závislosť build.gradle spis:

skupina kompilácií: „org.openpnp“, názov: „opencv“, verzia: „3.4.2-0“

Po pridaní knižnice do našich závislostí môžeme využívať funkcie poskytované OpenCV.

3. Používanie knižnice

Ak chcete začať používať OpenCV, musíme inicializovať knižnicu, ktoré môžeme urobiť v našom hlavný metóda:

OpenCV.loadShared ();

OpenCV je trieda, ktorá obsahuje metódy spojené s načítaním natívnych balíkov požadované knižnicou OpenCV pre rôzne platformy a architektúry.

Stojí za zmienku, že dokumentácia robí veci trochu inak:

System.loadLibrary (Core.NATIVE_LIBRARY_NAME)

Obe tieto volania metód skutočne načítajú požadované natívne knižnice.

Rozdiel je v tom druhá vyžaduje inštaláciu natívnych knižníc. Prvý z nich však môže nainštalovať knižnice do dočasného priečinka, ak nie sú na danom počítači k dispozícii. Kvôli tomuto rozdielu the zdieľané metóda je zvyčajne najlepší spôsob, ako ísť.

Keď sme teraz inicializovali knižnicu, pozrime sa, čo s ňou môžeme urobiť.

4. Načítavanie obrázkov

Začať, načítajme ukážkový obrázok z disku pomocou OpenCV:

public static Mat loadImage (String imagePath) {Imgcodecs imageCodecs = new Imgcodecs (); vrátiť imageCodecs.imread (imagePath); }

Táto metóda bude načítať daný obrázok ako a Mat objekt, ktorý je maticovým znázornením.

Na uloženie predtým načítaného obrázka môžeme použiť napísať () metóda Imgodeksy trieda:

public static void saveImage (Mat imageMatrix, String targetPath) {Imgcodecs imgcodecs = nový Imgcodecs (); imgcodecs.imwrite (targetPath, imageMatrix); }

5. Haarov kaskádový klasifikátor

Predtým, ako sa ponoríme do rozpoznávania tváre, pochopme základné pojmy, ktoré to umožňujú.

Jednoducho povedané, klasifikátor je program, ktorý sa snaží umiestniť nové pozorovanie do skupiny závislej od minulých skúseností. Kaskádové klasifikátory sa to snažia dosiahnuť pomocou zreťazenia niekoľkých klasifikátorov. Každý nasledujúci klasifikátor používa výstup z predchádzajúceho ako ďalšie informácie, čím výrazne zlepšuje klasifikáciu.

5.1. Funkcie Haar

Detekciu tváre v OpenCV vykonávajú kaskádové klasifikátory založené na funkciách Haar.

Funkcie Haar sú filtre, ktoré sa používajú na detekciu hrán a línií na obrázku. Filtre sa zobrazujú ako štvorce s čiernou a bielou farbou:

Tieto filtre sa na obrázok použijú viackrát po pixeloch a výsledok sa zhromaždí ako jedna hodnota. Táto hodnota predstavuje rozdiel medzi súčtom pixelov pod čiernym štvorcom a súčtom pixelov pod bielym štvorcom.

6. Detekcia tváre

Spravidla kaskádový klasifikátor musí byť vopred vyškolený, aby dokázal vôbec niečo zistiť.

Pretože školiaci proces môže byť dlhý a vyžadoval by si veľký súbor údajov, použijeme jeden z vopred vyškolených modelov ponúkaných OpenCV. Tento súbor XML umiestnime do nášho zdrojov priečinok pre ľahký prístup.

Prejdime si proces detekcie tváre:

Pokúsime sa detekovať tvár tak, že ju ohraničíme červeným obdĺžnikom.

Na začiatok je potrebné načítať obrázok Mat formát z našej zdrojovej cesty:

Mat loadedImage = loadImage (sourceImagePath);

Potom vyhlásime a MatOfRect objekt na uloženie tvárí, ktoré nájdeme:

MatOfRect FacesDetected = nový MatOfRect ();

Ďalej musíme inicializovať CascadeClassifier urobiť uznanie:

CascadeClassifier cascadeClassifier = nový CascadeClassifier (); int minFaceSize = Math.round (loadedImage.rows () * 0,1f); cascadeClassifier.load ("./ src / main / resources / haarcascades / haarcascade_frontalface_alt.xml"); cascadeClassifier.detectMultiScale (loadedImage, faceDetected, 1.1, 3, Objdetect.CASCADE_SCALE_IMAGE, new Size (minFaceSize, minFaceSize), new Size ());

Vyššie uvedený parameter 1.1 označuje faktor mierky, ktorý chceme použiť, a určuje, o koľko sa zmenší veľkosť obrázka pri každej mierke obrázka. Ďalším parametrom, 3, je minSusedia. Toto je počet susedov, ktoré by mal mať obdĺžnik, aby si ho udržali.

Nakoniec urobíme slučku cez tváre a uložíme výsledok:

Rect [] FacesArray = FacesDetected.toArray (); for (Rect face: FacesArray) {Imgproc.rectangle (loadedImage, face.tl (), face.br (), new Scalar (0, 0, 255), 3); } saveImage (loadedImage, targetImagePath);

Keď zadáme náš zdrojový obrázok, mali by sme teraz dostať výstupný obrázok so všetkými tvárami označenými červeným obdĺžnikom:

7. Prístup k fotoaparátu pomocou OpenCV

Doteraz sme videli, ako vykonať detekciu tváre na načítaných obrázkoch. Ale väčšinou to chceme robiť v reálnom čase. Aby sme to dokázali, musíme mať prístup ku kamere.

Aby sme však mohli ukázať obraz z fotoaparátu, potrebujeme okrem zrejmého ešte niekoľko ďalších vecí - fotoaparát. Na zobrazenie obrázkov použijeme JavaFX.

Pretože budeme používať ImageView aby sme mohli zobraziť obrázky, ktoré nasnímal náš fotoaparát, potrebujeme spôsob, ako preložiť OpenCV Mat do JavaFX Obrázok:

public Image mat2Img (Mat mat) {MatOfByte bajty = nový MatOfByte (); Imgcodecs.imencode ("img", mat, bytes); InputStream inputStream = nový ByteArrayInputStream (bytes.toArray ()); vrátiť nový obrázok (inputStream); }

Tu prevádzame naše Mat na bajty a potom prevedenie bajtov na Obrázok objekt.

Začneme streamovaním pohľadu z kamery do JavaFX Etapa.

Poďme teraz inicializovať knižnicu pomocou zdieľané metóda:

OpenCV.loadShared ();

Ďalej budeme vytvorte javisko s Zachytávanie videa a an ImageView na zobrazenie Obrázok:

VideoCapture capture = nový VideoCapture (0); ImageView imageView = nový ImageView (); HBox hbox = nový HBox (imageView); Scéna scéna = nová scéna (hbox); stage.setScene (scéna); stage.show ();

Tu, 0 je ID kamery, ktorú chceme použiť. Tiež musíme vytvoriť Časovač animáciena nastavenie obrázka:

new AnimationTimer () {@Override public void handle (long l) {imageView.setImage (getCapture ()); }} .start ();

Nakoniec náš getCapture metóda rukoväte prevádzanie Mat do an Obrázok:

public Image getCapture () {Mat mat = nový Mat (); capture.read (mat); návrat mat2Img (mat); }

Aplikácia by teraz mala vytvoriť okno a potom živé vysielanie pohľadu z kamery do imageView okno.

8. Detekcia tváre v reálnom čase

Nakoniec môžeme všetky bodky spojiť a vytvoriť aplikáciu, ktorá detekuje tvár v reálnom čase.

Kód z predchádzajúcej časti je zodpovedný za získanie obrazu z fotoaparátu a jeho zobrazenie používateľovi. Všetko, čo musíme urobiť, je spracovať zachytené obrázky pred zobrazením na obrazovke pomocou nášho CascadeClassifier trieda.

Poďme si jednoducho upraviť naše getCapture metóda tiež vykonávať detekciu tváre:

public Image getCaptureWithFaceDetection () {Mat mat = nový Mat (); capture.read (mat); Mat haarClassifiedImg = detectFace (mat); návrat mat2Img (haarClassifiedImg); }

Teraz, ak spustíme našu aplikáciu, tvár by mala byť označená červeným obdĺžnikom.

Vidíme tiež nevýhodu kaskádových klasifikátorov. Ak príliš otočíme tvár akýmkoľvek smerom, červený obdĺžnik zmizne. To je preto, že použili sme špecifický klasifikátor, ktorý bol trénovaný iba na detekciu prednej časti tváre.

9. Zhrnutie

V tomto tutoriáli sme sa naučili, ako používať OpenCV v Jave.

Na detekciu tvárí na obrázkoch sme použili vopred trénovaný kaskádový klasifikátor. Pomocou JavaFX sa nám podarilo dosiahnuť, aby klasifikátory detegovali tváre v reálnom čase pomocou obrázkov z fotoaparátu.

Ako vždy všetky vzorky kódu nájdete na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found