Ich habe versucht, OpenCV mit Java + Tomcat zu verwenden

Dieser Artikel ist der zweite Tag der Web-Crew Adventskalender 2017. Gestern war @ kouares '"CRUD mit PlayFramework 2.6.7 implementieren, Play-Slick 3.0.2 (Slick 3.2)".

** Einführung **

@ Hahegawa wird für den zweiten Tag verantwortlich sein. Vielen Dank.

Überblick

――In meiner Arbeit hatte ich die Möglichkeit, ein Objekt aus einem Bild erkennen zu wollen, also habe ich OpenCV ausprobiert.

** Annahme **

――Ich habe "Feature Detection" und "Feature Matching" ausprobiert.

Umgebung

Es ist ein bisschen alt, aber ich habe es in der folgenden Umgebung versucht. ・ Windows 10 ・ Sauerstoff verdunkeln ・ OpenCV3.1 ・ Apache Tomcat 7.0

** Projektaufbau **

    1. Eclipse-Installation und Projekterstellung In diesem Artikel weggelassen
  1. Laden Sie die OpenCV-Bibliothek herunter Laden Sie auf der folgenden Seite die Bibliothek des Ver, das Sie verwenden möchten, herunter und entpacken Sie sie an einen geeigneten Speicherort      https://opencv.org/releases.html アドベントカレンダー1-min.png

    1. Windows-Systemumgebungsvariablen hinzugefügt Fügen Sie den Ordner unter "\ build \ java " im entpackten Ordner zu Path hinzu アドベントカレンダー2-min.png

4. Klicken Sie mit der rechten Maustaste auf das Eclipse-Projekt → Buildpfad in Eigenschaften festlegen アドベントカレンダー3-min.png

  1. Benutzerbibliothek hinzufügen Legen Sie beim Hinzufügen denselben Pfad wie 3 zum Speicherort der nativen Bibliothek fest アドベントカレンダー4-min.png

6. Laufzeitkonfiguration hinzufügen Wenn Sie OpenCV unter der Annahme einer Webanwendung ausführen, setzen Sie 5 auf den Klassenpfad der Laufzeitkonfiguration. Fügen Sie dieselbe Benutzerbibliothek hinzu アドベントカレンダー5-min.png

  1. Erstellung des Quellcodes Durch Befolgen des folgenden Verarbeitungsverfahrens wurden Merkmalspunkte aus dem Bild erkannt und abgeglichen. (1) Lesen Sie das Bild und speichern Sie es in der BufferedImage-Klasse (2) Konvertieren Sie von der BufferedImage-Klasse in die Mat-Klasse → Bei der Verarbeitung eines Bildes mit der Methode der OpenCV-Bibliothek Grundsätzlich mit dieser Mat-Klasse (3) Erzeugung eines Merkmalsdetektors → Verwenden Sie diesmal AKAZE (4) Ausführung der Merkmalserkennung + Gegenprüfung → Die Erkennungsgenauigkeit ist höher, wenn der Gegenprüfungsprozess hinzugefügt wird. Die Verarbeitungszeit und die Last werden zunehmen, daher ist dies ein Problem (5) Zeichnen Sie das Erkennungsergebnis des Merkmalspunkts

(2)~(5)Quellcode


  //Mattenkonvertierung des vom Bildschirm gesendeten Bildes
  Mat src = new Mat(bufImg.getHeight(), bufImg.getWidth(), CvType.CV_8UC3);
  byte[] bufImgBinary = ((DataBufferByte)bufImg.getRaster().getDataBuffer()).getData();
  src.put(0, 0, bufImgBinary);

  //Mattenkonvertierung des zur Merkmalserkennung verwendeten Vorlagenbildes
  Mat tempSrc = new Mat(tmpImg.getHeight(), tmpImg.getWidth(), CvType.CV_8UC3);
  byte[] tempImgBinary = ((DataBufferByte)tmpImg.getRaster().getDataBuffer()).getData();
  tempSrc.put(0, 0, tempImgBinary);

  //Graustufenkonvertierung zur Merkmalserkennung
  Mat srcGray = new Mat(bufImg.getHeight(), bufImg.getWidth(), CvType.CV_8UC1);
  Imgproc.cvtColor(src, srcGray, Imgproc.COLOR_BGR2GRAY);
  Core.normalize(srcGray, srcGray, 0, 255, Core.NORM_MINMAX);
  Mat tempSrcGray = new Mat(tmpImg.getHeight(), tmpImg.getWidth(), CvType.CV_8UC1);
  Imgproc.cvtColor(tempSrc, tempSrcGray, Imgproc.COLOR_BGR2GRAY);
  Core.normalize(tempSrcGray, tempSrcGray, 0, 255, Core.NORM_MINMAX);

  MatOfKeyPoint keyPointSrc = new MatOfKeyPoint();
  MatOfKeyPoint keyPointTemp = new MatOfKeyPoint();
  Mat descriptersSrc = new Mat(src.rows(), src.cols(), src.type());
  Mat descriptersBase = new Mat(tempSrc.rows(), tempSrc.cols(), tempSrc.type());

  //Feature-Detektor-Generation 1
  FeatureDetector akazeDetector = FeatureDetector.create(FeatureDetector.AKAZE);
  DescriptorExtractor akazeExtractor = DescriptorExtractor.create(DescriptorExtractor.AKAZE);
  akazeDetector.detect(srcGray, keyPointSrc);  
  akazeDetector.detect(tempSrcGray, keyPointTemp);
  akazeExtractor.compute(srcGray, keyPointSrc, descriptersSrc);  
  akazeExtractor.compute(tempSrcGray, keyPointTemp, descriptersBase);

  //Feature-Detektor-Generation 2
  DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE);

  MatOfDMatch matche = new MatOfDMatch();
  List<MatOfDMatch> matches = new ArrayList<MatOfDMatch>();
  List<DMatch> dmatch = new ArrayList<DMatch>();

  //Merkmale Gegenprüfung verfügbar
  if(CROSS_CHECK_FLG){

    MatOfDMatch srcToBase = new MatOfDMatch();
    MatOfDMatch baseToSrc = new MatOfDMatch();
    
    matcher.match(descriptersSrc, descriptersBase, srcToBase);
    matcher.match(descriptersBase, descriptersSrc, baseToSrc);

    List<DMatch> ldm_srcToBase = srcToBase.toList();
    List<DMatch> ldm_baseToSrc = baseToSrc.toList();

    for(int i=0; i<ldm_srcToBase.size(); i++) {

      DMatch forward = ldm_srcToBase.get(i);
      DMatch backward = ldm_baseToSrc.get(forward.trainIdx);

      if(backward.trainIdx == forward.queryIdx){
        dmatch.add(forward);
      }

    }

    matche.fromList(dmatch);

  }
  //Merkmale Keine Gegenprüfung
  else{

    System.out.println("Merkmale Normale Prüfausführung");
    matcher.match(descriptersSrc, descriptersBase, matche);

  }

  Mat matchResult = new Mat(src.rows()*2, src.cols()*2, src.type());
  Features2d.drawMatches(src, keyPointSrc, tempSrc, keyPointTemp, matche, matchResult);
  //↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ Verifizierungsbildausgabe ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
  BufferedImage image = ImageConverter.convertMToBI(matchResult);
  File ouptut = new File("C:\\testlog\\sample_20171202.jpg ");
  ImageIO.write(image, "jpg", ouptut);

Laden der OpenCV-Bibliothek


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

** Ausführungsergebnis **

Obwohl es einige Fehlerkennungen gibt, können die Merkmale erkannt werden. 6-min

** Was ich darüber nachgedacht habe **

――Das Schreiben des Codes hat lange gedauert, da er langsam war. Wenn Sie jedoch schnell einen Code finden oder schreiben, können Sie das Bild problemlos verarbeiten, wenn Sie die Grundlagen und Erklärungen der verschiedenen in diesem Artikel beschriebenen Methoden verstehen. Ich hatte das Gefühl, dass ich es schaffen könnte. ――Wenn Sie Ihr Unternehmen planen, möchten Sie wirklich "Was ist vor der Funktionserkennung zu tun?" Verwenden. Lesen Sie diesen Artikel und konzentrieren Sie sich auf die Verarbeitung, die Sie wirklich ohne zusätzlichen Aufwand implementieren möchten. I würde es schätzen wenn du könntest.

Morgen ist @wc_moriyama. Vielen Dank.

Recommended Posts

Ich habe versucht, OpenCV mit Java + Tomcat zu verwenden
Ich habe versucht, Java REPL zu verwenden
Ich habe versucht, JOOQ mit Gradle zu verwenden
Ich habe versucht, mit Java zu interagieren
Ich habe versucht, UDP mit Java zu kommunizieren
Ich habe versucht, die Java8 Stream API zu verwenden
Ich habe versucht, JWT in Java zu verwenden
Ich habe versucht, Java Memo LocalDate zu verwenden
Ich habe versucht, Google HttpClient von Java zu verwenden
[Java] Ich habe versucht, über den Verbindungspool eine Verbindung mit Servlet (Tomcat) & MySQL & Java herzustellen
Ich habe versucht, die CameraX-Bibliothek mit Android Java Fragment zu verwenden
Ich habe versucht, die Elasticsearch-API in Java zu verwenden
Ich habe versucht, Realm mit Swift UI zu verwenden
Ich habe versucht, Scalar DL mit Docker zu verwenden
Ich habe versucht, OnlineConverter mit SpringBoot + JODConverter zu verwenden
Ich habe versucht, Gson zu benutzen
Ich habe versucht, TestNG zu verwenden
Ich habe versucht, Galasa zu benutzen
Ich habe versucht, eine Standardauthentifizierung mit Java durchzuführen
Ich habe versucht, den Block mit Java zu brechen (1)
Ich habe DI mit Ruby versucht
Ich habe versucht, TCP / IP + BIO mit JAVA zu implementieren
[Java 11] Ich habe versucht, Java auszuführen, ohne mit Javac zu kompilieren
Ich habe versucht, SQS mit AWS Java SDK zu betreiben
Ich habe versucht, Azure Cloud-Init zu verwenden
Ich habe Drools (Java, InputStream) ausprobiert.
Ich habe versucht, Log4j2 auf einem Java EE-Server zu verwenden
Ich habe versucht, Apache Wicket zu verwenden
Ich habe versucht, mit OCR eine PDF-Datei mit Java zu verarbeiten
Verwenden von Mapper mit Java (Spring)
Ich habe versucht, Sterling Sort mit Java Collector zu implementieren
Ich habe versucht, die erweiterte for-Anweisung in Java zu verwenden
Ich habe UPSERT mit PostgreSQL ausprobiert.
Ich habe BIND mit Docker ausprobiert
Ich habe versucht, ein Aktienchart mit Java (Jsoup) zu kratzen.
Ich habe versucht, Metaprogrammierung mit Java
Ich habe versucht, mit Chocolatey eine Java8-Entwicklungsumgebung zu erstellen
Ich habe versucht, eine Java EE-Anwendung mit OpenShift zu modernisieren.
Ich habe versucht, Dapr in Java zu verwenden, um die Entwicklung von Mikroservices zu erleichtern
Ich habe versucht, eine PDF-Datei mit Java part2 zu verarbeiten
Ich habe versucht, mit Swagger mit Spring Boot zu beginnen
Ich habe jetzt versucht, Anakia + Jing zu verwenden
Installieren Sie Java und Tomcat mit Ansible
Ich habe versucht, Spring + Mybatis + DbUnit zu verwenden
Ich habe eine morphologische Analyse mit MeCab versucht
Versuchen Sie es mit Redis mit Java (jar)
Aktivieren Sie OpenCV mit Java8. (Für mich)
Ich habe das Java-Framework "Quarkus" ausprobiert.
Verwenden von Java mit AWS Lambda-Eclipse-Vorbereitung
Was ich mit Java Gold gelernt habe
HTML5-Entwicklung von Java mit TeaVM
Ich habe GraphQL mit Spring Boot ausprobiert
Ich habe versucht, das Java-Lernen zusammenzufassen (1)
[Android] Ich habe versucht, das Koordinatorlayout zu verwenden.
Ich habe Flyway mit Spring Boot ausprobiert
Ich habe versucht, Pari GP Container zu verwenden
Was ich mit Java Silver gelernt habe
Ich habe versucht, WebAssembly Stadio (Version 2018/4/17) zu verwenden.
Ich habe jetzt versucht, Java 8 zusammenzufassen
Verwenden des Proxy-Dienstes mit Java-Crawling