Uvod u OpenCV s Javom

1. Uvod

U ovom uputstvu ćemo naučite kako instalirati i koristiti OpenCV knjižnicu računalnog vida i primijeniti je na otkrivanje lica u stvarnom vremenu.

2. Instalacija

Da bismo koristili OpenCV biblioteku u našem projektu, moramo dodati opencv Mavenova ovisnost o našoj pom.xml:

 org.openpnp opencv 3.4.2-0 

Za korisnike Gradlea morat ćemo dodati ovisnost na našu graditi.gradle datoteka:

kompajliraj grupu: 'org.openpnp', naziv: 'opencv', verzija: '3.4.2-0'

Nakon dodavanja knjižnice u naše ovisnosti, možemo koristiti značajke koje pruža OpenCV.

3. Korištenje knjižnice

Da biste počeli koristiti OpenCV, moramo inicijalizirati knjižnicu, što možemo učiniti u našem glavni metoda:

OpenCV.loadShared ();

OpenCV je klasa koja sadrži metode povezane s učitavanjem izvornih paketa potrebna za OpenCV knjižnicu za razne platforme i arhitekture.

Vrijedno je napomenuti da dokumentacija stvari radi malo drugačije:

System.loadLibrary (Core.NATIVE_LIBRARY_NAME)

Oba poziva metode će zapravo učitati potrebne matične knjižnice.

Ovdje je razlika u tome potonji zahtijeva instaliranje matičnih knjižnica. Međutim, prvi mogu knjižnice instalirati u privremenu mapu ako nisu dostupne na određenom računalu. Zbog ove razlike, the loadShared metoda je obično najbolji put.

Sad kad smo inicijalizirali knjižnicu, da vidimo što možemo s njom učiniti.

4. Učitavanje slika

Početi, učitajmo uzorak slike s diska pomoću OpenCV-a:

javni statički mat loadImage (String imagePath) {Imgcodecs imageCodecs = novi Imgcodecs (); vratiti imageCodecs.imread (imagePath); }

Ova metoda će učitaj zadanu sliku kao Mat objekt, koji je matrični prikaz.

Za spremanje prethodno učitane slike možemo koristiti upisati () metoda Imgcodeci razred:

javna statička praznina saveImage (Mat imageMatrix, String targetPath) {Imgcodecs imgcodecs = novi Imgcodecs (); imgcodecs.imwrite (targetPath, imageMatrix); }

5. Haar-ov kaskadni klasifikator

Prije ulaska u prepoznavanje lica, shvatimo ključne pojmove koji to omogućuju.

Jednostavno rečeno, klasifikator je program koji želi postaviti novo opažanje u skupinu koja ovisi o prošlom iskustvu. Kaskadni klasifikatori to žele učiniti pomoću spajanja nekoliko klasifikatora. Svaki sljedeći klasifikator koristi izlaz iz prethodnog kao dodatne informacije, uvelike poboljšavajući klasifikaciju.

5.1. Haar značajke

Otkrivanje lica u OpenCV-u vrši se kaskadnim klasifikatorima koji se temelje na Haar-u.

Haar značajke su filtri koji se koriste za otkrivanje rubova i crta na slici. Filteri se vide kao kvadratići s crno-bijelim bojama:

Ti se filtri primjenjuju više puta na sliku, piksel po piksel, a rezultat se prikuplja kao jedna vrijednost. Ova je vrijednost razlika između zbroja piksela ispod crnog kvadrata i zbroja piksela ispod bijelog kvadrata.

6. Otkrivanje lica

Općenito, kaskadni klasifikator mora biti unaprijed obučen da bi uopće mogao bilo što otkriti.

Budući da proces obuke može biti dug i zahtijevat će velik skup podataka, koristit ćemo jedan od unaprijed obučenih modela koje nudi OpenCV. Smjestit ćemo ovu XML datoteku u naš resursi mapa za jednostavan pristup.

Krenimo kroz postupak otkrivanja lica:

Pokušat ćemo otkriti lice ocrtavanjem crvenim pravokutnikom.

Za početak moramo učitati sliku Mat format s našeg izvornog puta:

Prostirka loadedImage = loadImage (sourceImagePath);

Zatim ćemo proglasiti a MatOfRect objekt za pohranu lica koja smo pronašli:

MatOfRect facesDetected = novi MatOfRect ();

Dalje, moramo inicijalizirati CascadeClassifier učiniti prepoznavanje:

CascadeClassifier cascadeClassifier = novi CascadeClassifier (); int minFaceSize = Math.round (loadedImage.rows () * 0.1f); cascadeClassifier.load ("./ src / main / resources / haarcascades / haarcascade_frontalface_alt.xml"); cascadeClassifier.detectMultiScale (loadedImage, facesDetected, 1.1, 3, Objdetect.CASCADE_SCALE_IMAGE, nova veličina (minFaceSize, minFaceSize), nova veličina ());

Iznad, parametar 1.1 označava faktor skale koji želimo koristiti, određujući za koliko je veličina slike smanjena na svakoj skali slike. Sljedeći parametar, 3, je minSusjedi. To je broj susjeda koji bi pravokutnik kandidat trebao imati da bi ga zadržao.

Na kraju ćemo provući kroz lica i spremiti rezultat:

Ispravljanje [] facesArray = facesDetected.toArray (); za (Ispravi lice: faceArray) {Imgproc.rectangle (loadedImage, face.tl (), face.br (), novi Scalar (0, 0, 255), 3); } saveImage (loadedImage, targetImagePath);

Kada unesemo izvornu sliku, sada bismo trebali dobiti izlaznu sliku sa svim licima označenim crvenim pravokutnikom:

7. Pristup kameri pomoću OpenCV-a

Do sada smo vidjeli kako izvršiti otkrivanje lica na učitanim slikama. Ali većinu vremena to želimo raditi u stvarnom vremenu. Da bismo to mogli, moramo pristupiti kameri.

Međutim, da bismo mogli prikazati sliku s fotoaparata, potrebno nam je nekoliko dodatnih stvari, osim očitog - kamera. Za prikaz slika koristit ćemo JavaFX.

Budući da ćemo koristiti ImageView za prikaz slika koje je napravio naš fotoaparat potreban nam je način prevesti OpenCV Mat na JavaFX Slika:

javna slika mat2Img (Mat mat) {MatOfByte bytes = new MatOfByte (); Imgcodecs.imencode ("img", mat, bajtovi); InputStream inputStream = novi ByteArrayInputStream (bytes.toArray ()); vrati novu sliku (inputStream); }

Evo, pretvaramo naše Mat u bajtove, a zatim pretvaranje bajtova u Slika objekt.

Započet ćemo s preusmjeravanjem prikaza kamere na JavaFX Scena.

Ajmo sada inicijalizirati knjižnicu pomoću loadShared metoda:

OpenCV.loadShared ();

Dalje, mi ćemo stvoriti pozornicu s Video snimanje i an ImageView za prikaz Slika:

VideoCapture capture = novi VideoCapture (0); ImageView imageView = novi ImageView (); HBox hbox = novi HBox (imageView); Scena scene = nova scena (hbox); stage.setScene (scena); stage.show ();

Ovdje, 0 je ID kamere koju želimo koristiti. Mi također trebamo stvoriti AnimationTimerza rukovanje postavljanjem slike:

novi AnimationTimer () {@Preuzmi javnu ručku za prazninu (dugo l) {imageView.setImage (getCapture ()); } }.početak();

Napokon, naša getCapture metoda ručke pretvaranje Mat do an Slika:

javna slika getCapture () {Mat mat = novi Mat (); capture.read (mat); povrat mat2Img (mat); }

Aplikacija bi sada trebala stvoriti prozor, a zatim uživo prenijeti pogled s kamere na imageView prozor.

8. Otkrivanje lica u stvarnom vremenu

Napokon, možemo povezati sve točkice kako bismo stvorili aplikaciju koja otkriva lice u stvarnom vremenu.

Kôd iz prethodnog odjeljka odgovoran je za hvatanje slike s fotoaparata i prikazivanje korisniku. Sada sve što moramo učiniti je obraditi ugrabljene slike prije nego što ih prikažemo na zaslonu pomoću našeg CascadeClassifier razred.

Jednostavno izmijenimo naš getCapture metoda za izvođenje detekcije lica:

javna slika getCaptureWithFaceDetection () {Mat mat = novi Mat (); capture.read (mat); Prostirka haarClassifiedImg = identifyFace (mat); povrat mat2Img (haarClassifiedImg); }

Sada, ako pokrenemo našu aplikaciju, lice bi trebalo biti označeno crvenim pravokutnikom.

Također možemo uočiti nedostatak kaskadnih klasifikatora. Ako lice okrenemo previše u bilo kojem smjeru, tada crveni pravokutnik nestaje. Ovo je zbog koristili smo određeni klasifikator koji je osposobljen samo za otkrivanje prednjeg dijela lica.

9. Sažetak

U ovom uputstvu naučili smo kako koristiti OpenCV u Javi.

Koristili smo unaprijed obučeni kaskadni klasifikator za otkrivanje lica na slikama. Uz pomoć JavaFX-a uspjeli smo učiniti da klasifikatori otkrivaju lica u stvarnom vremenu pomoću slika s fotoaparata.

Kao i uvijek, svi uzorci koda mogu se naći na GitHubu.