web-dev-qa-db-fra.com

Exemple de correspondance de modèles OpenCV dans Android

Je suis un débutant à OpenCV. J'essaie de faire un exemple Android pour faire correspondre une image de modèle dans une image donnée en utilisant la correspondance de modèles OpenCV. J'ai cherché sur Internet et je n'ai pas trouvé de bon Android ou Java qui satisfait mes besoins. Mais j'ai du code C++. Je ne sais pas comment le traduire. http://docs.opencv.org /doc/tutorials/imgproc/histograms/template_matching/template_matching.html

Pouvez-vous s'il vous plaît m'aider à trouver un bon Java ou Android. Ou bien s'il vous plaît aidez-moi à traduire ce code C++ en Java, que je peux utiliser à l'intérieur Android.

Merci d'avance.

Code C++

#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;
}
24
ssdehero

J'étais confronté au même problème que vous. Aucune source dans Java disponible. Quelques recherches dans JavaDoc et quelques conseils pour les valeurs const plus tard, j'ai écrit ceci, qui est presque l'exemple de code ci-dessus écrit en Java:

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);
    }
}

Maintenant, exécutez le programme avec les options suivantes: lena.png template.png templatematch.png et vous devriez recevoir le même résultat que moi. Assurez-vous que les fichiers sont accessibles par votre runtime et, bien sûr, la bibliothèque opencv 2.4.6 est enregistrée dans votre chemin de classe.

lena.pngtemplate.pngtemplatematch.png

44
micfra

Si vous souhaitez utiliser OpenCV 3 et plus, vous devez utiliser ce code

car il n'y a pas de Highgui dans OpenCV 3 et vous devriez plutôt utiliser imgcodecs.

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);
}

}
4
daaniaal