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.