Nous avons apporté des améliorations depuis la dernière fois.
Détection de vidéos similaires en Java et OpenCV rev.1 --Qiita
En plus de l'histogramme, les caractéristiques sont comparées. Il existe différents algorithmes de quantité de caractéristiques, mais ici nous utiliserons quelque chose appelé "AKAZE". Je ne connais pas les détails, mais il semble avoir été ajouté à partir d'OpenCV3, et cela avait l'air bien (divers).
Conversion en échelle de gris avant le traitement.
FeatureDetector detector = FeatureDetector.create(FeatureDetector.AKAZE);
DescriptorExtractor executor = DescriptorExtractor.create(DescriptorExtractor.AKAZE);
Mat gray = new Mat();
Imgproc.cvtColor(resizedFrame, gray, Imgproc.COLOR_RGB2GRAY);
MatOfKeyPoint point = new MatOfKeyPoint();
detector.detect(gray, point);
Mat desc = new Mat();
executor.compute(gray, point, desc);
Ensuite, utilisez Descriptor Matcher pour comparer la quantité de caractéristiques acquise Mat. Vous pouvez également choisir plusieurs méthodes pour cela, mais je n'en suis pas sûr non plus, j'ai donc choisi BRUTE FORCE.
DescriptorMatcher macher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE);
MatOfDMatch feature = new MatOfDMatch();
macher.match(video1.getFeatureImg().get(i - 1), video2.getFeatureImg().get(i - 1), feature);
List<Double> distanceList = new ArrayList<>();
for (DMatch dMatch : feature.toList()) {
distanceList.add(Double.valueOf(dMatch.distance));
}
Cette fois, j'ai décidé de gérer les résultats de comparaison vidéo en moyenne. Puisqu'il s'agit de "distance", on peut juger que la valeur la plus petite est "similaire".
Dans le but de réduire le temps de traitement, nous n'avons pas comparé ceux avec une différence de temps de lecture de plus de 10%.
long playtime1 = video1.getPlayTime();
long playtime2 = video2.getPlayTime();
long playtimeDiff = Math.abs(playtime1 - playtime2);
if ((playtimeDiff / playtime1) > 0.1) {
return null;
}
En raison du mécanisme actuel, il est inévitable car il n'est pas possible de comparer des éléments liés aux vidéos "incluses".
Ajout d'un menu contextuel pour que vous puissiez vérifier le fichier après avoir vérifié le résultat. Voici comment ajouter un menu contextuel à un TableView.
ContextMenu menu = new ContextMenu();
MenuItem mi = new MenuItem("Ouvrir dans l'explorateur");
mi.setOnAction(event -> {
TableItem item = table.getSelectionModel().getSelectedItem();
String command1 = "explorer /select," + item.getOrg().getVideo1().getFilename();
String command2 = "explorer /select," + item.getOrg().getVideo2().getFilename();
try {
Runtime.getRuntime().exec(command1);
Runtime.getRuntime().exec(command2);
} catch (IOException e) {
e.printStackTrace();
}
});
menu.getItems().add(mi);
table.setContextMenu(menu);
La gestion des exceptions est appropriée ...
J'ai pu détecter des "vidéos similaires" simplement en comparant les histogrammes plus que prévu. Je pense qu'il est suffisamment précis pour détecter les données liées aux données originales compressées, telles que la fréquence d'images et la résolution. Je me demande si ce sera un apprentissage en profondeur si cela devient plus que cela.
Le prochain défi est le côté non fonctionnel.
Le temps d'exécution était d'environ 90 secondes pour 70 fichiers dans un environnement avec Core i5-4690 et 4 Go de mémoire alloués. Je l'exécute en regardant jconsole, mais la mémoire semble être sévère à mesure que le nombre de fichiers augmente, il semble donc y avoir place à l'amélioration.
Je travaille actuellement sur la mise en cache des résultats et l'écriture d'histogrammes et de fonctionnalités dans un fichier et de les quitter en mémoire, mais cela ne fonctionne pas.
Je veux l'améliorer.
La fin.
Recommended Posts