2013-06-08 10 views
22

Ich bin ein Anfänger zu OpenCV. Ich versuche, eine Beispiel-Android-Anwendung zu tun, um ein Vorlagenbild in einem gegebenen Bild unter Verwendung des OpenCV-Vorlagenvergleichs abzugleichen. Ich suchte im Internet und konnte keinen richtigen Android- oder Java-Code finden, der meine Anforderung erfüllt. Aber ich habe C++ Code. Ich weiß nicht, wie ich es übersetzen soll. http://docs.opencv.org/doc/tutorials/imgproc/histograms/template_matching/template_matching.htmlOpenCV Template Matching Beispiel in Android

Können Sie mir bitte helfen, einen richtigen Java oder Android Code zu finden. Oder helfen Sie mir bitte bei der Übersetzung dieses C++ Codes in Java, die ich in Android-Anwendung verwenden kann.

Vielen Dank im Voraus.

C++ Code

#include "opencv2/highgui/highgui.hpp" 
#include "opencv2/imgproc/imgproc.hpp" 
#include <iostream> 
#include <stdio.h> 

using namespace std; 
using namespace cv; 

/// Global Variables 
Mat img; Mat templ; Mat result; 
char* image_window = "Source Image"; 
char* result_window = "Result window"; 

int match_method; 
int max_Trackbar = 5; 

/// Function Headers 
void MatchingMethod(int, void*); 

/** @function main */ 
int main(int argc, char** argv) 
{ 
    /// Load image and template 
    img = imread(argv[1], 1); 
    templ = imread(argv[2], 1); 

    /// Create windows 
    namedWindow(image_window, CV_WINDOW_AUTOSIZE); 
    namedWindow(result_window, CV_WINDOW_AUTOSIZE); 

    /// Create Trackbar 
    char* trackbar_label = "Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED"; 
    createTrackbar(trackbar_label, image_window, &match_method, max_Trackbar, MatchingMethod); 

    MatchingMethod(0, 0); 

    waitKey(0); 
    return 0; 
} 

/** 
* @function MatchingMethod 
* @brief Trackbar callback 
*/ 
void MatchingMethod(int, void*) 
{ 
    /// Source image to display 
    Mat img_display; 
    img.copyTo(img_display); 

    /// Create the result matrix 
    int result_cols = img.cols - templ.cols + 1; 
    int result_rows = img.rows - templ.rows + 1; 

    result.create(result_cols, result_rows, CV_32FC1); 

    /// Do the Matching and Normalize 
    matchTemplate(img, templ, result, match_method); 
    normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat()); 

    /// Localizing the best match with minMaxLoc 
    double minVal; double maxVal; Point minLoc; Point maxLoc; 
    Point matchLoc; 

    minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat()); 

    /// For SQDIFF and SQDIFF_NORMED, the best matches are lower values. For all the other methods, the higher the better 
    if(match_method == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED) 
    { matchLoc = minLoc; } 
    else 
    { matchLoc = maxLoc; } 

    /// Show me what you got 
    rectangle(img_display, matchLoc, Point(matchLoc.x + templ.cols , matchLoc.y + templ.rows), Scalar::all(0), 2, 8, 0); 
    rectangle(result, matchLoc, Point(matchLoc.x + templ.cols , matchLoc.y + templ.rows), Scalar::all(0), 2, 8, 0); 

    imshow(image_window, img_display); 
    imshow(result_window, result); 

    return; 
} 
+0

google für android-ndk –

+0

du meinst es mit ndk konvertieren? Für OpenCV hat eine separate Android-Bibliothek. Ich habe Schwierigkeiten, diese Methoden und Typen mit genauen Methoden und Typen in dieser Bibliothek abzugleichen. – ssdehero

+0

hast du die beispiele für den android sdk ausgeführt? –

Antwort

39

Ich war vor dem gleichen Problem Sie haben. Keine Quelle in Java verfügbar. Einige Suche in der JavaDoc und einige Hinweise für const Werte später schrieb ich dies, die Code fast die Probe oben in Java geschrieben ist:

package opencv; 

import org.opencv.core.Core; 
import org.opencv.core.Core.MinMaxLocResult; 
import org.opencv.core.CvType; 
import org.opencv.core.Mat; 
import org.opencv.core.Point; 
import org.opencv.core.Scalar; 
import org.opencv.highgui.Highgui; 
import org.opencv.imgproc.Imgproc; 

class MatchingDemo { 
    public void run(String inFile, String templateFile, String outFile, int match_method) { 
     System.out.println("\nRunning Template Matching"); 

     Mat img = Highgui.imread(inFile); 
     Mat templ = Highgui.imread(templateFile); 

     ///Create the result matrix 
     int result_cols = img.cols() - templ.cols() + 1; 
     int result_rows = img.rows() - templ.rows() + 1; 
     Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1); 

     ///Do the Matching and Normalize 
     Imgproc.matchTemplate(img, templ, result, match_method); 
     Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat()); 

     ///Localizing the best match with minMaxLoc 
     MinMaxLocResult mmr = Core.minMaxLoc(result); 

     Point matchLoc; 
     if (match_method == Imgproc.TM_SQDIFF || match_method == Imgproc.TM_SQDIFF_NORMED) { 
      matchLoc = mmr.minLoc; 
     } else { 
      matchLoc = mmr.maxLoc; 
     } 

     ///Show me what you got 
     Core.rectangle(img, matchLoc, new Point(matchLoc.x + templ.cols(), 
       matchLoc.y + templ.rows()), new Scalar(0, 255, 0)); 

     // Save the visualized detection. 
     System.out.println("Writing "+ outFile); 
     Highgui.imwrite(outFile, img); 

    } 
} 

public class TemplateMatching { 
    public static void main(String[] args) { 
     System.loadLibrary("opencv_java246"); 
     new MatchingDemo().run(args[0], args[1], args[2], Imgproc.TM_CCOEFF); 
    } 
} 

Nun führen Sie das Programm mit den folgenden Optionen: lena.png template.png templatematch.png und Sie sollten erhalten Das gleiche Ergebnis habe ich gemacht. Stellen Sie sicher, dass auf die Dateien von Ihrer Laufzeit zugegriffen werden kann, und natürlich ist die Bibliothek von opencv 2.4.6 in Ihrem Klassenpfad registriert.

lena.png template.png templatematch.png

+0

Ich benutzte deinen Code, aber wenn ich ma tch es mit einem anderen Bild dann auch das Rechteck gezeichnet wird, auch wenn das Bild nicht übereinstimmt? und woher weiß ich, ob es eine Übereinstimmung gibt oder nicht wie eine Boolean, die besagt, dass es eine Übereinstimmung ist oder nicht (ich meine, so etwas ist dort?) –

+0

Ich weiß es nicht. Um mehr Leute auf Ihr Problem aufmerksam zu machen, schreiben Sie bitte eine neue Frage. Es könnte für mehr Leute interessant sein. – micfra

+0

Aber es ist dein Code richtig? Es zeichnet ein Rechteck auch für eine falsche Übereinstimmung, warum ist das so? –

0

Wenn Sie OpenCV verwenden möchten 3 und mehr sollten Sie diesen Code

verwenden, weil es keine Highgui in OpenCV 3 ist, und Sie sollten stattdessen imgcodecs verwenden.

import org.opencv.core.Core; 
import org.opencv.core.Core.MinMaxLocResult; 
import org.opencv.core.CvType; 
import org.opencv.core.Mat; 
import org.opencv.core.Point; 
import org.opencv.core.Scalar; 
import org.opencv.imgcodecs.Imgcodecs; 
import org.opencv.imgproc.Imgproc; 

class MatchingDemo { 
    public void run(String inFile, String templateFile, String outFile, 
     int match_method) { 
    System.out.println("\nRunning Template Matching"); 

    Mat img = Imgcodecs.imread(inFile); 
    Mat templ = Imgcodecs.imread(templateFile); 

    ///Create the result matrix 
    int result_cols = img.cols() - templ.cols() + 1; 
    int result_rows = img.rows() - templ.rows() + 1; 
    Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1); 

    ///Do the Matching and Normalize 
    Imgproc.matchTemplate(img, templ, result, match_method); 
    Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat()); 

    ///Localizing the best match with minMaxLoc 
    MinMaxLocResult mmr = Core.minMaxLoc(result); 

    Point matchLoc; 
    if (match_method == Imgproc.TM_SQDIFF 
      || match_method == Imgproc.TM_SQDIFF_NORMED) { 
     matchLoc = mmr.minLoc; 
    } else { 
     matchLoc = mmr.maxLoc; 
    } 

    ///Show me what you got 
    Imgproc.rectangle(img, matchLoc, new Point(matchLoc.x + templ.cols(), 
      matchLoc.y + templ.rows()), new Scalar(0, 255, 0)); 

    // Save the visualized detection. 
    System.out.println("Writing " + outFile); 
    Imgcodecs.imwrite(outFile, img); 

} 
} 

public class TemplateMatching { 

public static void main(String[] args) { 
    System.loadLibrary("opencv_java300"); 
    new MatchingDemo().run(args[0], args[1], args[2], Imgproc.TM_CCOEFF); 
} 

}