Erkennen Sie ähnliche Videos in Java und OpenCV Version 1

Einführung

Ich hatte die Gelegenheit, für einen Moment herauszufinden, wie man "ähnliche Bilder erkennt", und dabei dachte ich über Videos nach.

  1. Extrahieren Sie Bilder aus Videos
  2. Vergleichen Sie Bilder

\(^o^)/

Ich kam auf die einfache Idee und beschloss, ein wenig zu machen. ** In Entwicklung **

Bildschirmbild image

Umgebung

Java (Java 9) wird unter Windows verwendet, und Eclipse wird als IDE verwendet. Das Erstellen der GUI erfolgt mit Scene Builder oder JavaFX.

Durch die Installation von OpenCV werden Jars und DLLs erstellt. Platzieren Sie sie an einem Ort, an dem sie gelesen werden können.

→ Nach Windows \ System32 \ kopieren

→ Unter Klassenpfad kopieren, aus Eclipse hinzufügen

Darüber hinaus war es in Java erforderlich, den Ladevorgang in einer Klasse zu beschreiben, die OpenCV verwendet (siehe unten).

	static {
		System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
	}

Extrahieren Sie Bilder aus Videos

Extrahieren Sie einige Bilder aus dem Video als Bilder. Hier habe ich beschlossen, 9 Bilder zu extrahieren. Es gibt keine bestimmte Grundlage, aber es ist ein Urteil, dass es gut aussieht, wenn es in 3x3 mit GUI angeordnet wird. Da das erste und das letzte Bild wahrscheinlich abgedunkelt sind, speichern Sie 9 durch 10 getrennte Bilder. -> FPS-Differenzerkennung ...?

Außerdem werden alle extrahierten Bilder so vergrößert und verkleinert, dass die Breite 200 Pixel beträgt, und dann gespeichert. -> Erkennung von Größenunterschieden ...?

↓ Es sieht so aus.

	static public VideoMetadata captureFrame(Config config, String videoFile) {
		// ------------------------------------------------------------------
		//Öffne das Video
		// ------------------------------------------------------------------
		System.out.println(videoFile);
		VideoCapture capture = new VideoCapture(videoFile);
		if (!capture.isOpened()) {
			System.out.println("file not opened.");
			return null;
		}

		String outputDir = config.getTempDir() + "/" + String.valueOf(videoFile.hashCode()).replace("-", "_");
		File dir = new File(outputDir);
		if (!dir.exists()) {
			dir.mkdir();
		}

		// ------------------------------------------------------------------
		//Erfassung von Videoinformationen
		// ------------------------------------------------------------------
		double fps = capture.get(Videoio.CV_CAP_PROP_FPS);
		int resizeHeight = (int) (config.getImageWidth() / capture.get(Videoio.CV_CAP_PROP_FRAME_WIDTH)
				* capture.get(Videoio.CV_CAP_PROP_FRAME_HEIGHT));
		double allFrameCnt = capture.get(Videoio.CV_CAP_PROP_FRAME_COUNT);
		int captureInterval = (int) (allFrameCnt / (config.getCaptureCount() + 1));
		long time = (long) (allFrameCnt / fps);

		// ------------------------------------------------------------------
		//Ruft die Anzahl der in den Einstellungen angegebenen Frames ab
		// ------------------------------------------------------------------
		for (int i = 1; i < config.getCaptureCount() + 1; i++) {
			int frameIndex = captureInterval * i;
			Mat orgFrame = new Mat();
			Mat resizedFrame = new Mat();
			capture.set(Videoio.CV_CAP_PROP_POS_FRAMES, frameIndex - 1);
			if (!capture.read(orgFrame)) {
				continue;
			}
			Imgproc.resize(orgFrame, resizedFrame, new Size(config.getImageWidth(), resizeHeight));
			Imgcodecs.imwrite(outputDir + "/" + i + ".jpg ", resizedFrame);

		}

		VideoMetadata metadata = new VideoMetadata();
		metadata.setFilename(videoFile);
		metadata.setFrameDirname(outputDir);
		metadata.setPlayTime(time);
		return metadata;
	}

Bilder vergleichen

Im vorherigen Abschnitt haben wir 9 Bilder pro Video erstellt. Dieses Mal werden wir dies vergleichen.

In Bezug auf den Vergleich von Bildern habe ich beschlossen, die Histogramme zu vergleichen. Ich denke, diesbezüglich gibt es viel Raum für Überlegungen.

Der Durchschnitt der Vergleichsergebnisse jedes der 9 Bilder wurde als Vergleichsergebnis des gesamten Videos verwendet.

Der Code ist unten.

	static public VideoComparison compareImages(Config config, VideoMetadata video1, VideoMetadata video2) {

		List<Double> histList = new ArrayList<Double>();
		// ------------------------------------------------------------------
		//Vergleichen Sie nach Bild
		// ------------------------------------------------------------------
		for (int i = 1; i < config.getCaptureCount() + 1; i++) {
			String filename1 = video1.getFrameDirname() + "/" + i + ".jpg ";
			String filename2 = video2.getFrameDirname() + "/" + i + ".jpg ";
			File file1 = new File(filename1);
			File file2 = new File(filename2);
			if (!(file1.exists() && file2.exists())) {
				continue;
			}

			// ------------------------------------------------------------------
			//Histogramm
			// ------------------------------------------------------------------
			Mat img1 = Imgcodecs.imread(filename1);
			List<Mat> src1 = new ArrayList<Mat>();
			src1.add(img1);
			Mat hist1 = new Mat();
			Imgproc.calcHist(src1, new MatOfInt(0), new Mat(), hist1, new MatOfInt(256), new MatOfFloat(0, 256));

			Mat img2 = Imgcodecs.imread(filename2);
			List<Mat> src2 = new ArrayList<Mat>();
			src2.add(img2);
			Mat hist2 = new Mat();
			Imgproc.calcHist(src2, new MatOfInt(0), new Mat(), hist2, new MatOfInt(256), new MatOfFloat(0, 256));

			histList.add(Imgproc.compareHist(hist1, hist2, 0));

		}

		VideoComparison videoComparison = new VideoComparison();
		videoComparison.setVideo1(video1);
		videoComparison.setVideo2(video2);
		videoComparison.setHist(calcAvg(histList));
		return videoComparison;
	}

Versuchen Sie es GUI zu machen

Ich möchte es zu einer GUI machen, weil es Bilder verarbeitet. Ich war besorgt, aber ich entschied mich, es mit JavaFX zu machen, um an die Veröffentlichung von Java9 zu erinnern. (JavaFX ist 8 ...)

In JavaFX kann das Entwurfslayout in XML (fxml) beschrieben werden, und Scene Builder kann dies grafisch bearbeiten. XML und Code werden durch das Attribut fx: id in XML und die Annotation @FMXL in .java verknüpft.

Wenn beispielsweise die Steuerung der Ausführungsschaltfläche wie folgt angeordnet ist,

<Button fx:id="executeBtn" layoutX="214.0" layoutY="31.0" mnemonicParsing="false" onAction="#doExecuteAction" prefHeight="38.0" prefWidth="115.0" text="execute" />

Gehen Sie auf der Java-Codeseite wie folgt vor:

	@FXML
	void doExecuteAction(ActionEvent event) {
        // ...
    }

Jetzt können Sie den Vorgang anhängen, der ausgeführt wird, wenn Sie die Taste drücken.

Die diesmal verwendeten Steuerelemente und Aktionen sind wie folgt.

--Ausführen

Schließlich

Ich habe den Code zum ersten Mal seit langer Zeit in Java geschrieben, aber es gibt viele nervige Aspekte im persönlichen Gebrauch. Eigentlich habe ich es zuerst in Python geschrieben, aber ich wollte es zu einer GUI machen, was soll ich mit Threads machen und so weiter ... → OpenCV kann auch mit Java gemacht werden. Also habe ich es Java gemacht.

Ich habe das Gefühl, dass ich seit AWT keine GUI in Java mehr gemacht habe, aber JavaFX war besser als ich erwartet hatte.

Der Rest dreht sich um Folgendes.

--Visualisierung des Verarbeitungsstatus

--Verarbeitungsstatusprotokoll anzeigen

--Andere ...?

Urlaubsprogrammierung hat Spaß gemacht. Ende.

Referenz

OpenCV: OpenCV modules

Client-Technologie: Java-Plattform, Standard Edition (Java SE) 8, Version 8

JavaFX Scene Builder 1.x Archive

Entwickeln von JavaFX 8 mit Eclipse mithilfe von Designer-Qiita

bitWalk's: JavaFX: ListView mit CheckBox

Recommended Posts

Erkennen Sie ähnliche Videos in Java und OpenCV Version 2
Erkennen Sie ähnliche Videos in Java und OpenCV Version 3
Erkennen Sie ähnliche Videos in Java und OpenCV Version 1
Verwenden Sie OpenCV mit Java
Beispiel für Codierung und Decodierung in Java
StringBuffer- und StringBuilder-Klasse in Java
Java + OpenCV 3.X mit IntelliJ IDEA
Hallo Welt in Java und Gradle
Unterschied zwischen final und Immutable in Java
Ich habe die OpenCV-Kamerakalibrierung in Java durchgeführt
Unterschied zwischen Arrylist und verknüpfter Liste in Java
Programmieren Sie PDF-Kopf- und Fußzeilen in Java
Lernen Sie Flyweight-Muster und ConcurrentHashMap in Java
Die Richtung von Java in "C ++ Design and Evolution"
Von Java nach C und von C nach Java in Android Studio
Lesen und Schreiben von GZIP-Dateien in Java
Unterschied zwischen int und Integer in Java
Diskriminierung von Enum in Java 7 und höher
In Bezug auf transiente Modifikatoren und Serialisierung in Java
Verwenden Sie OpenCV_Contrib (ArUco) mit Java! (Teil 1-Build) (OpenCV-3.4.4)
Parallele und parallele Verarbeitung in verschiedenen Sprachen (Java Edition)
Unterschied zwischen next () und nextLine () in Java Scanner
Unterschiede beim Schreiben von Java-, C # - und Javascript-Klassen
Erfassen und speichern Sie die Selen-Installation in Java
Hinzufügen, Lesen und Löschen von Excel-Kommentaren mit Java
Überprüfen Sie das statische und öffentliche Verhalten in Java-Methoden
[Java] Verstehe in 10 Minuten! Assoziatives Array und HashMap
Unterscheiden Sie in Java zwischen positiven und negativen Zahlen
Java fügt Wasserzeichen in Word-Dokumenten hinzu und entfernt sie
Repräsentiert "nächster Tag" und "vorheriger Tag" in Java / Android
Fragen in Java-Ausnahmebehandlung werfen und versuchen-fangen
Laden Sie Notizen in Java auf S3 hoch und laden Sie sie herunter
Verschlüsseln / Entschlüsseln mit AES256 in PHP und Java
Generieren Sie OffsetDateTime aus Clock und LocalDateTime in Java
Änderungen in Java 11
Janken in Java
Java und JavaScript
XXE und Java
Umfangsrate in Java
FizzBuzz in Java
[Android / Java] Bildschirmübergang und Rückgabeverarbeitung in Fragmenten
Konvertieren Sie JSON und YAML in Java (mit Jackson und SnakeYAML)
Schreiben Sie ABNF in Java und geben Sie die E-Mail-Adresse weiter
Organisieren Sie Builds in C ++ / Java- und Win / Linux-Kombinationen
Vektorisieren und bildgeben Sie handgeschriebene numerische MNIST-Bilddaten mit Java
Schreiben Sie eine Klasse in Kotlin und nennen Sie sie in Java
In der Abbildung verstandene Java-Klassen und -Instanzen
Java-Join- und Split-Tabellenzellen im Word-Dokument
Dies und das zum Bearbeiten von ini in Java. : inieditor-java
Subtrahieren Sie Enum-Konstanten von Zeichenfolgen und Werten in Java zurück
Verwendung von Abstract Class und Interface in Java richtig