Bevezetés az OpenCV Java-ba

1. Bemutatkozás

Ebben az oktatóanyagban megtesszük megtanulják, hogyan kell telepíteni és használni az OpenCV számítógépes látástárat, és hogyan kell alkalmazni a valós idejű arcfelismeréshez.

2. Telepítés

Az OpenCV könyvtár használatához projektünkben hozzá kell adnunk a opencv Maven függőség a mi pom.xml:

 org.openpnp opencv 3.4.2-0 

A Gradle felhasználóknak hozzá kell adnunk a függőséget a sajátunkhoz épít.gradle fájl:

fordítási csoport: 'org.openpnp', név: 'opencv', verzió: '3.4.2-0'

Miután hozzáadta a könyvtárat a függőségeinkhez, használhatjuk az OpenCV által biztosított szolgáltatásokat.

3. A Könyvtár használata

Az OpenCV használatának megkezdéséhez inicializálnunk kell a könyvtárat, amit megtehetünk a mi fő- módszer:

OpenCV.loadShared ();

OpenCV olyan osztály, amely a natív csomagok betöltésével kapcsolatos módszereket tárolja amelyet az OpenCV könyvtár különféle platformokhoz és architektúrákhoz igényel.

Érdemes megjegyezni, hogy a dokumentáció kissé másképp csinálja a dolgokat:

System.loadLibrary (Core.NATIVE_LIBRARY_NAME)

Mindkét módszerhívás valóban betölti a szükséges natív könyvtárakat.

A különbség itt az ez utóbbi megköveteli a natív könyvtárak telepítését. Az előbbiek azonban telepíthetik a könyvtárakat egy ideiglenes mappába, ha nem állnak rendelkezésre az adott gépen. E különbség miatt a loadShared módszer általában a legjobb út.

Most, hogy inicializáltuk a könyvtárat, nézzük meg, mit tehetünk vele.

4. Képek betöltése

Kezdeni, töltsük be a mintaképet a lemezről az OpenCV használatával:

public static Mat loadImage (String imagePath) {Imgcodecs imageCodecs = new Imgcodecs (); return imageCodecs.imread (imagePath); }

Ez a módszer megteszi töltse be az adott képet a-ként Mat objektum, amely egy mátrixábrázolás.

A korábban betöltött kép mentéséhez használhatjuk a írni () módszere Imgcodecs osztály:

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

5. Haar kaszkád osztályozó

Mielőtt belevetnénk magunkat az arcfelismerésbe, értsük meg azokat az alapfogalmakat, amelyek ezt lehetővé teszik.

Egyszerűen fogalmazva, az osztályozó olyan program, amely új megfigyelésre törekszik a múlt tapasztalataitól függő csoportba. A lépcsőzetes osztályozók ezt több osztályozó összefűzésével igyekeznek megtenni. Minden következő osztályozó az előző kimenetét használja kiegészítő információként, jelentősen javítva az osztályozást.

5.1. Haar Jellemzők

Az arcfelismerést az OpenCV-ben Haar-funkció alapú kaszkád osztályozók végzik.

A Haar funkciók olyan szűrők, amelyek a kép éleinek és vonalainak érzékelésére szolgálnak. A szűrőket fekete és fehér színű négyzeteknek tekintik:

Ezeket a szűrőket többször alkalmazzák egy képre, pixelenként, és az eredményt egyetlen értékként gyűjtik össze. Ez az érték a fekete négyzet alatti pixelek és a fehér négyzet alatti pixelek összege közötti különbség.

6. Arcfelismerés

Általában, a kaszkádosztályozót elő kell képezni, hogy egyáltalán bármit is észlelni tudjon.

Mivel a képzési folyamat hosszú lehet, és nagy adatállományra lenne szükség, az OpenCV által kínált előre kiképzett modellek egyikét fogjuk használni. Ezt az XML fájlt elhelyezzük a fájlunkban erőforrások mappa a könnyű hozzáférés érdekében.

Lépjünk végig az arc észlelésén:

Megpróbáljuk felismerni az arcot egy piros téglalap felvázolásával.

A kezdéshez be kell töltenünk a képet Mat formátum a forrás elérési útvonalunkról:

Mat loadingImage = loadImage (sourceImagePath);

Akkor kijelentjük a MatOfRect objektum a talált arcok tárolására:

MatOfRect facesDetected = új MatOfRect ();

Ezután inicializálnunk kell a CascadeClassifier az elismerés megtételéhez:

CascadeClassifier cascadeClassifier = new 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, new Size (minFaceSize, minFaceSize), new Size ());

Fent az 1.1 paraméter jelöli azt a méretaránytényezőt, amelyet használni akarunk, meghatározva, hogy az egyes képméretekben mekkora képméret csökken. A következő paraméter, 3, van minSzomszédok. Ez az a szomszédok száma, amellyel a téglalap jelöltnek meg kell maradnia.

Végül végignézzük az arcokat, és elmentjük az eredményt:

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

Amikor megadjuk a forrásképünket, akkor most meg kell kapnunk a kimeneti képet úgy, hogy az összes arcát piros téglalap jelöli:

7. Hozzáférés a fényképezőgéphez OpenCV használatával

Eddig láttuk, hogyan lehet arcfelismerést végezni a betöltött képeken. De legtöbbször valós időben szeretnénk megtenni. Ahhoz, hogy ezt megtehessük, hozzáférnünk kell a kamerához.

Ahhoz azonban, hogy képet tudjunk mutatni kameráról, szükségünk van néhány további dologra, a nyilvánvaló kivételével - egy kamerára. A képek megjelenítéséhez JavaFX-et fogunk használni.

Mivel egy ImageView a fényképezőgépünk által készített képek megjelenítéséhez szükségünk van rá lefordít egy OpenCV-t Mat JavaFX-re Kép:

public Image mat2Img (Mat mat) {MatOfByte bájtok = új MatOfByte (); Imgcodecs.imencode ("img", mat, byte); InputStream inputStream = new ByteArrayInputStream (bytes.toArray ()); return new Image (inputStream); }

Itt átalakítjuk a sajátunkat Mat bájtokká, majd a bájtokat konvertálja Kép tárgy.

Kezdjük azzal, hogy a kameranézetet JavaFX-be továbbítjuk Színpad.

Most inicializáljuk a könyvtárat a loadShared módszer:

OpenCV.loadShared ();

Ezután megtesszük hozza létre a színpadot val,-vel Video felvétel és egy ImageView a Kép:

VideoCapture capture = új VideoCapture (0); ImageView imageView = új ImageView (); HBox hbox = új HBox (imageView); Jelenetjelenet = új Jelenet (hbox); stage.setScene (jelenet); színpad.bemutató ();

Itt, 0 a használni kívánt kamera azonosítója. Nekünk is kell hozzon létre egy AnimationTimera kép beállításának kezelése:

új AnimationTimer () {@Orride public void hand (long l) {imageView.setImage (getCapture ()); } }.Rajt();

Végül a mi getCapture módszer kezeli konvertálása a Mat egy Kép:

public Image getCapture () {Mat mat = new Mat (); elfog.olvas (mat); visszatérő mat2Img (mat); }

Az alkalmazásnak most létre kell hoznia egy ablakot, majd élőben kell közvetítenie a nézetet a kameráról a imageView ablak.

8. Valós idejű arcfelismerés

Végül összekapcsolhatjuk az összes pontot egy alkalmazás létrehozásához, amely valós időben érzékeli az arcokat.

Az előző szakasz kódja felelős a kép fényképezőgépből történő megragadásáért és a felhasználó számára történő megjelenítéséért. Most már csak annyit kell tennünk, hogy feldolgozzuk a megragadott képeket, mielőtt a képernyőn megjelenítenénk őket a CascadeClassifier osztály.

Módosítsuk egyszerűen a sajátunkat getCapture módszer arcfelismerés végrehajtására is:

public Image getCaptureWithFaceDetection () {Mat mat = new Mat (); elfog.olvas (mat); Mat haarClassifiedImg = DetectFace (mat); visszatérő mat2Img (haarClassifiedImg); }

Most, ha futtatjuk az alkalmazásunkat, az arcot piros téglalapgal kell megjelölni.

A kaszkád osztályozók hátrányát is láthatjuk. Ha túlságosan bármely irányba fordítjuk az arcunkat, akkor a piros téglalap eltűnik. Ez azért van, mert egy speciális osztályozót használtunk, amelyet csak az arc elejének észlelésére tanítottak.

9. Összegzés

Ebben az oktatóanyagban megtanultuk az OpenCV használatát a Java-ban.

Előre betanított kaszkád osztályozót használtunk az arcok észlelésére a képeken. A JavaFX segítségével sikerült elérnünk, hogy a besorolók kamerából származó képekkel valós időben észleljék az arcokat.

Mint mindig, az összes kódminta megtalálható a GitHubon.