Verwenden Sie OpenCV_Contrib (ArUco) mit Java! (Teil 2-Programmierung)

Einführung

Dieser Artikel ist ein vorderer und hinterer Teil. Wenn Sie die ArUco-Bibliothek nicht erstellt haben, Verwenden Sie OpenCV_Contrib (ArUco) in Java! (Teil 1-Build).

Der diesmal verwendete Quellcode befindet sich im Allgemeinen in OpenCV_ArucoTest [GitHub]. Ich würde mich freuen, wenn Sie darauf verweisen könnten.

Dieser Artikel beschreibt das Programm bei Verwendung der ArUco-Bibliothek in Java.

Ich dachte daran, es früher zu schreiben, aber ich war zu spät. (Ich fing an, in der Nacht vor Silvester zu schreiben ...) Zur Zeit bin ich für den OpenCV Adventskalender 2018 registriert. (Was hast du nach der Veröffentlichung im neuen Jahr 2019 gesagt?)

Vorbereiten der Verwendung von ArUco mit Eclipse

Befolgen Sie die Anweisungen zum Importieren eines vorhandenen OpenCV mit der in Contrib enthaltenen JAR-Datei.

Erzeugung von Markerbildern

Um sicherzustellen, dass die ArUco-Bibliothek ordnungsgemäß erstellt und eingerichtet wurde Lassen Sie uns ein Markerbild erzeugen.

Die zu verwendende Funktion ist ・ Aruco.drawMarker (Wörterbuch, markerID, sidePixels, markerImage) Wörterbuch: Bestimmt den Markertyp. Die Größe, Auflösung und Anzahl der Arten von Quadraten sind unterschiedlich. markerID: Die im Wörterbuch definierte Marker-ID mit jeweils unterschiedlicher Form. sidePixels: Bestimmt die Auflösung.

Quellcode unten (Details: createMarker [GitHub])

	public static void createMarker() {
		Dictionary dictionary = Aruco.getPredefinedDictionary(Aruco.DICT_4X4_50);

		final int markerID = 0;
		final int sidePixels = 200;
		Mat markerImage = new Mat();
		Aruco.drawMarker(dictionary, markerID, sidePixels, markerImage);

		Imgcodecs.imwrite("F:\\users\\smk7758\\Desktop\\marker_2018-12-01.png ", markerImage);
	}

marker_2018-12-01.png Sie sollten so etwas bekommen.

Markererkennung

Nun, es ist die Produktion von hier.

Die folgenden zwei Funktionen werden verwendet ・ Aruco.detectMarkers (inputImage, Wörterbuch, Ecken, markerIds, Parameter); ・ Aruco.drawDetectedMarkers (inputImage, Ecken, markerIds); Nun, wie bei der Funktion erkennt detectMarkers mehrere Marker. Danach zeichnet drawDetectedMarkers mithilfe von Ecken die vier Ecken von Marker nach. Ecken: Gibt die Bildschirmkoordinaten von Marker zurück. (Der Grund für List liegt darin, dass mehrere Marker erkannt werden und Mat eine Matrix ist und Koordinaten speichern kann.)

(Andere Argumente werden weggelassen)

Quellcode unten (Details: detectMarker [GitHub])

	public static void detectMarker() {
		Dictionary dictionary = Aruco.getPredefinedDictionary(Aruco.DICT_4X4_50);

		Mat inputImage = Imgcodecs.imread("F:\\users\\smk7758\\Desktop\\marker_2018-12-01_test.png ");
		List<Mat> corners = new ArrayList<>();
		Mat markerIds = new Mat();
		DetectorParameters parameters = DetectorParameters.create();
		Aruco.detectMarkers(inputImage, dictionary, corners, markerIds, parameters);

		Aruco.drawDetectedMarkers(inputImage, corners, markerIds);

		Imgcodecs.imwrite("F:\\users\\smk7758\\Desktop\\marker_2018-12-01_detected.png ", inputImage);
	}

marker_2018-12-01_test.png Es wurde von GIMP transformiert, aber im Bild oben

marker_2018-12-01_detected.png Es sollte so aussehen.

Echtzeit-Markererkennung mit einer Kamera

Ehrlich gesagt, als ich hierher kam, war es fast Selbstzufriedenheit, aber als nächstes kombinierte ich JavaFX und VideoCapture (OpenCV), um eine Echtzeiterkennung durchzuführen.

Der Unterschied besteht darin, dass es unter JavaFX ausgeführt wird. Bei Verwendung des ScheduledService ist der zurückgegebene Wert vom Typ Image. ScheduledService ist eine Klasse, die bei der Multithread-Verarbeitung mit JavaFX verwendet wird, und es scheint, dass Task automatisch wiederhergestellt werden kann. Weitere Informationen finden Sie im offiziellen JavaDoc. Der Grund für die Rückgabe mit dem Bildtyp ist auch, dass das Element, das das auf der Seite der Controller-Klasse definierte Bild anzeigt, das Argument ist Dies ist ein Bild zu machen. Für den, der von Mat zu Image konvertiert, habe ich den verwendet, der nach gründlicher Recherche herauskam.

Quellcode unten (Details: [DetectMarkerByCamera --MarkerDetectorService.java [GitHub]](https://github.com/smk7758/OpenCV_ArucoTest/blob/master/test-2018-12-01_OpenCV_Contrib_Aruco_3_detectMarkerByCm//com/s / /MarkerDetectorService.java)))

	@Override
	protected Task<Image> createTask() {
		return new Task<Image>() {
			@Override
			protected Image call() throws Exception {
				if (!vc.isOpened()) {
					System.err.println("VC is not opened.");
					this.cancel();
					return null;
				}

				Mat inputImage = new Mat();

				if (!vc.read(inputImage) || inputImage == null) {
					System.err.println("Cannot load camera image.");
					this.cancel();
					return null;
				}

				List<Mat> corners = new ArrayList<>();
				Mat markerIds = new Mat();
				// DetectorParameters parameters = DetectorParameters.create();
				Aruco.detectMarkers(inputImage, dictionary, corners, markerIds);

				Aruco.drawDetectedMarkers(inputImage, corners, markerIds);

				return convertMatToImage(inputImage);
			}
		};
	}

	private Image convertMatToImage(Mat inputImage) {
		MatOfByte byte_mat = new MatOfByte();
		Imgcodecs.imencode(".bmp", inputImage, byte_mat);

		return new Image(new ByteArrayInputStream(byte_mat.toArray()));
	}

SC_test_2018-12-2_21-37-9_No-00.png Es sollte so aussehen.

[DetectMarker (Center) CoordinatesByCamera [GitHub]](https://github.com/smk7758/OpenCV_ArucoTest/blob/master/test-2018-12-01_OpenCV_Contrib_Aruco_3_detectMarkerCoordinatesByCamera/src/sm// In) wird die Funktion auf der OpenCV-Seite verwendet, um die Koordinaten des Schwerpunkts aus den Punkten an den vier Ecken des Markers zu ermitteln und die Punkte zu zeichnen.

Echtzeit-Marker-Haltungsschätzung mit einer Kamera

Schließlich möchte ich die Haltungsschätzung am besten durchführen.

Nun, ich würde es gerne sofort tun, aber tatsächlich gibt es etwas zu tun, bevor ich die Haltung abschätze. Es heißt Kamerakalibrierung. Die folgende Funktion kann ohne die hier erhaltene Matte nicht ausgeführt werden. Weitere Informationen finden Sie unter Ich habe die OpenCV-Kamerakalibrierung mit Java durchgeführt. Ich möchte, dass du es tust. (Tatsächlich hat es einige Wochen gedauert, bis sich das vorherige Kapitel entwickelt hat. Dies ist die Ursache für die Verzögerung.)

Beginnen wir noch einmal mit der Funktion. ・ Aruco.estimatePoseSingleMarkers (Ecken, 0.05f, cameraMatrix, DistortionCoefficients, rotationMatrix, translationVectors); ・ Aruco.drawAxis (inputImage, cameraMatrix, distortionCoefficients, rotationMatrix, translationVectors, 0.1f);

Wie der Name schon sagt, schätzt die obige Funktion die Haltung von Marker und gibt eine Rotationsmatrix und einen parallelen Bewegungsvektor zurück. Die folgende Funktion zeichnet die Achse oder Koordinatenachse.

Quellcode unten (Details: [detectMarkerPoseByCamera [GitHub]]](https://github.com/smk7758/OpenCV_ArucoTest/blob/master/test-2018-12-01_OpenCV_Contrib_Aruco_4_detectMarkerPoseByCamera/src/sm// ))

	List<Mat> corners = new ArrayList<>();
	Mat markerIds = new Mat();
	// DetectorParameters parameters = DetectorParameters.create();
	Aruco.detectMarkers(inputImage, dictionary, corners, markerIds);

	Aruco.drawDetectedMarkers(inputImage, corners, markerIds);

	Mat rotationMatrix = new Mat(), translationVectors = new Mat(); //erhalten
	Aruco.estimatePoseSingleMarkers(corners, 0.05f, cameraMatrix, distortionCoefficients,rotationMatrix, translationVectors);

	for (int i = 0; i < markerIds.size().height; i++) { // TODO
		Aruco.drawAxis(inputImage, cameraMatrix, distortionCoefficients, rotationMatrix, translationVectors, 0.1f);
	}

SC_test_2018-12-31_0-36-22_No-00.png SC_test_2018-12-31_0-36-13_No-00.png SC_test_2018-12-31_0-35-37_No-00.png Es sollte so aussehen.

abschließend

Es hat einige Zeit gedauert, aber es hat vorerst angefangen zu arbeiten. Es war besonders schwierig, die Kamerakalibrierung zu verstehen ... Ich möchte mich weiterhin der Java-Version von OpenCV widmen.

(Ich habe es Ende 2018 genossen) [Obwohl der Artikel selbst Anfang 2019 geschrieben wurde]

Da dieser Artikel von einem Anfänger verfasst wurde, würden wir uns freuen, wenn Sie Fehler oder schlechte Punkte haben, wenn Sie auf Twitter kommentieren oder kommentieren könnten.

Referenzlink

Die Formel war am einfachsten zu verstehen.

ArUco-Markererkennung (Aruco-Modul) - OpenCV-BeamterErkennung von ArUco-Markern - OpenCV OfficialPosenschätzung mit Opencv Aruco Teil 1 - MaschinenlernmemorandumPosenschätzung mit Opencv Aruco Teil 2 - Memorandum über maschinelles LernenOpenCV aruco marker - Persönliches Memo zum Programm ・ [Verwenden Sie das Aruco-Modul --atinfinity / lab (GitHub)](https://github.com/atinfinity/lab/wiki/aruco%E3%83%A2%E3%82%B8%E3%83%A5 % E3% 83% BC% E3% 83% AB% E3% 82% 92% E4% BD% BF% E3% 81% A3% E3% 81% A6% E3% 81% BF% E3% 82% 8B) ・ Schätzung der Kameraposition und -ausrichtung mithilfe von Markern (OpenCV + ArUco) - Herstellung eines fliegenden RobotersUntersuchung von ArUco, einer leichtgewichtigen AR-BibliothekFür mich: OpenCV3.4.3-Kamerakalibrierung

Recommended Posts

Verwenden Sie OpenCV_Contrib (ArUco) mit Java! (Teil 2-Programmierung)
Verwenden Sie OpenCV_Contrib (ArUco) mit Java! (Teil 1-Build) (OpenCV-3.4.4)
Einschränkungsprogrammierung in Java
Verwenden Sie OpenCV mit Java
Verwenden Sie PreparedStatement in Java
[Java] Grundbegriffe der Programmierung
Verwenden wir Twilio in Java! (Einführung)
[Java] Verwenden Sie nicht "+" im Anhang!
Verwenden Sie zusammengesetzte Schlüssel in Java Maps.
Wie verwende ich Klassen in Java?
Führen Sie eine Phrasenanalyse in Java 8 durch (Teil 2).
Verwenden Sie Stream in Java?
Erstellen einer Phrasenanalyse in Java 8 (Teil 1)
Mehrsprachige Unterstützung für Java Verwendung des Gebietsschemas
[Java] Verwenden Sie kryptografische Technologie mit Standardbibliotheken
Verwenden Sie "Rhino", das JavaScript in Java ausführt
Erstellen einer Matrixklasse in Java Teil 1
Lassen Sie uns darüber nachdenken, was deklarative Programmierung in Java und Elm ist (Teil 1).
Partisierung in Java
Die Geschichte des Lernens von Java in der ersten Programmierung
Grundlagen der Java-Programmierung
Änderungen in Java 11
[Java] Verwendung von final in der lokalen Variablendeklaration
Janken in Java
Java-Übung Teil 1
Java Generische Programmierung
Was ich in Java gelernt habe (Teil 2) Was sind Variablen?
[JAVA] [Spring] [MyBatis] Verwenden Sie IN () mit SQL Builder
[Java] Verwenden Sie Collectors.collectingAndThen
Umfangsrate in Java
FizzBuzz in Java
Programmierung mit dem direkten Summentyp in Java (Nachrichten)
[LeJOS] Programmieren wir mindstorm-EV3 mit Java [Umgebungskonstruktion Teil 2]
Ein kurzer Überblick über Java, das in Klasse 4 gelernt wurde
Ich möchte ES2015 auch in Java verwenden! → (´ ・ ω ・ `)
Was ich in Java gelernt habe (Teil 3) Anweisung zur Ausführung von Anweisungen
Ein kurzer Überblick über Java, das in Klasse 3 gelernt wurde
Ein kurzer Überblick über Java, das in Klasse 2 gelernt wurde
[JAVA] [Spring] [MyBatis] Verwenden Sie GROUP BY in SQL Builder
Verwendung von Abstract Class und Interface in Java richtig
~ Ich habe jetzt versucht, funktionale Programmierung mit Java zu lernen ~
Hinweise zur Verwendung regulärer Ausdrücke in Java
Schnell lernen Java "Einführung?" Teil 3 Von der Programmierung wegreden
Lesen Sie JSON in Java
Interpreter-Implementierung durch Java
Machen Sie einen Blackjack mit Java
Janken App in Java
Setzen Sie Java8 in Centos7
NVL-artiger Typ in Java
Verbinden Sie Arrays in Java
"Hallo Welt" in Java
Aufrufbare Schnittstelle in Java
Verwenden Sie java.time mit Jackson
Kommentare in der Java-Quelle
Azure funktioniert in Java
Formatieren Sie XML in Java
Einfache HTML-Spezialchars in Java
Boyer-Moore-Implementierung in Java