Computer Vision mit OpenCV – Einstieg mit Java

Keine Kommentare

Wer sich mit OpenCV beschäftigt, kommt an Python kaum vorbei. Doch es gibt Alternativen!

Sicher: In Kombination mit Python bildet das OpenCV Framework ein effizientes Gespann. Doch nicht in jedem Fall ist eine Nutzung mit Python möglich oder gewünscht, weswegen ich in diesem Artikel die ersten Schritte mit Java beschreibe.

Ihr sucht einen guten Einstieg in OpenCV und/oder wollt doch lieber mit Python loslegen? Dann schaut doch mal, was mein Kollege Oli Moser geschrieben hat!

Vorbedingungen

Zunächst ist eine OpenCV Installation erforderlich. Zusätzlich benötigen wir:

  • Die Java Library (opencv-3xx.jar)
  • Die Native Library (libopencv_java3xx.so)

(Gelegentlich treten beim Bauen mit CMake Komplikationen auf, aber Hilfe ist relativ einfach zu finden. Falls es trotzdem nicht klappt, schreib doch einfach einen Kommentar unter diesen Artikel)

Nun müssen wir unserer IDE mitteilen, wo die beiden Artefakte zu finden sind. Bei IntelliJ fügt man hierzu einem bestehenden Modul eine Dependency hinzu:

  • Unter „File“ -> [Project Structure] -> [Project Settings] -> [Modules] das Modul auswählen.
  • Im Reiter [Dependencies] über [+] [JARs or directories] die Java Library hinzufügen.
  • Checkbox [Export] aktivieren
  • Die hinzugefügte Dependency doppelklicken und über [+] das Verzeichnis mit der Native Library hinzufügen.

So sieht das dann bei mir aus:
Dependencies

Wenn folgender Code keinen Fehler wirft, hat alles geklappt, wie es soll:
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
System.out.println(
Mat.eye(1, 1, CvType.CV_64F)
.dump());

Wichtige Objekte und Klassen

Um richtig loslegen zu können, helfen uns zunächst drei Klassen:
org.opencv.core.Core stellt (statische) Basisfunktionalitäten wie Addition, Subtraktion oder bitweise Operationen zur Verfügung.
org.opencv.imgproc.Imgproc stellt (statische) Bildverarbeitungsmethoden zur Verfügung, zum Beispiel um Konturen zu finden und zu zeichnen, Bounding Boxen oder Moments zu berechnen.
org.opencv.core.Mat (sowie davon abgeleitete) stellen die „Zeichenvorlage“ dar und repräsentiert ein Bild in einem bestimmten Format oder einer bestimmten Kodierung.

Viele Methoden, die OpenCV uns zur Verfügung stellt, sind statisch und besitzen keinen Rückgabewert. Stattdessen wird eine (oder mehrere) Referenzen als Parameter übergeben, in denen die Rückgabewerte gespeichert werden. Zum Beispiel folgende Methode zur Konvertierung:

public static void cvtColor(Mat src, Mat dst, int code)

Hier stellt „src“ das zu konvertierende Objekt dar, und in „dst“ finden wir das Ergebnis. Das erscheint aus Sicht des Java-Entwicklers zunächst etwas ungewohnt und umständlich, liegt aber vermutlich daran, dass viele Funktionen mehr als einen Rückgabewert besitzen und sich dies so leichter automatisiert generieren lässt.

Zeit für ein Experiment

Solange man das Ergebnis nicht sehen kann, macht die Arbeit mit Computer Vision nicht viel Spaß. In Java ist jedoch ein wenig Boilerplate Code erforderlich, um ein Ergebnis zu sehen. Das habe ich schon mal für euch hier (github) erledigt.

Nach dem Klonen findet ihr die Klasse „Start“. Hier passt ihr den Pfad von „IMAGE_PATH“ so an, dass er auf ein Bild auf eurer Festplatte zeigt. Werft anschließend einen Blick auf die Methode „processImage(…)“, denn hier wird euch dieses Bild als Parameter übergeben, und ihr könnt mit ihm arbeiten. Als kleines Beispiel zum Starten habe ich die Farben auf Schwarz/Weiß umgestellt.

Wenn ihr das Programm nun startet, öffnet sich ein Fenster mit dem Original-Bild sowie der bearbeiteten Version:

First Run

An dieser Stelle ist der Einstieg geschafft. Ich möchte euch trotzdem noch ein paar Zeilen Code zur Inspiration mit auf den Weg geben, die ihr einfach direkt (einzeln oder in Kombination) ausprobieren könnt. Viel Spaß!

Imgproc.threshold(processed, processed, 100, 255, Imgproc.THRESH_BINARY);

Mat kernx = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(7, 7));
Imgproc.morphologyEx(processed, processed, Imgproc.MORPH_OPEN, kernx );

Imgproc.Canny(processed, processed, 180, 255);

Imgproc.dilate(processed.clone(), processed, new Mat(), new Point(0, 0), 2);

Tobias Schaber

Neben seinem Schwerpunkt „Verteilte Systeme“ beschäftigt sich Tobias mit der Automatisierung von Infrastruktur und komplexen Systemen wie z.B. Elasticsearch-Clustern. Mit ihm im Team ist außerdem immer ein leidenschaftlicher Verfechter agiler Softwareentwicklung zur Stelle, der gerne mal ein flammendes Plädoyer für agile Methoden hält.

Share on FacebookGoogle+Share on LinkedInTweet about this on TwitterShare on RedditDigg thisShare on StumbleUpon

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.