2013-06-08 82 views
22

私はOpenCVの初心者です。私はOpenCV Template Matchingを使って与えられたイメージのテンプレートイメージにマッチするサンプルアンドロイドアプリケーションをやろうとしています。私はインターネットで検索し、私は自分の要件を満たす適切なアンドロイドまたはJavaコードを見つけることができませんでした。しかし、私はC++コードを持っています。私はそれを翻訳する方法を知らない。 http://docs.opencv.org/doc/tutorials/imgproc/histograms/template_matching/template_matching.htmlAndroidでのOpenCVテンプレートマッチング例

適切なJavaまたはAndroidコードを見つけるのに手伝ってください。あるいは、このC++コードをJavaに翻訳してください。私はAndroidアプリケーションの中で使うことができます。

ありがとうございます。

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; 
} 
+0

Google用android-ndk –

+0

あなたはndkを使用して変換することを意味しますか? OpenCVには別のAndroidライブラリがあります。私はこれらのメソッドと型をそのライブラリの正確なメソッドと型にマッチさせるのに苦労しています。 – ssdehero

+0

あなたはandroid sdkのサンプルを実行しましたか? –

答えて

39

に私はあなたがやった同じ問題に直面していました。 Javaのソースはありません。 lena.png template.png templatematch.pngを、あなたが受け取る必要があります。次のオプションを指定してプログラムを実行し、今

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

:javadocのいくつかの検索やconstの値のためのいくつかのヒント後に、私は上記のJavaで書かれたほとんどのサンプルコードである、これを書きました私がしたのと同じ結果。実行時にファイルにアクセスできることを確認してください。もちろん、opencv 2.4.6ライブラリがクラスパスに登録されています。

lena.png template.png templatematch.png

+0

私はあなたのコードを使用しましたが、別のイメージでそれをtchし、イメージが一致しない場合でも矩形が描画されますか?どのようにして一致があるかどうかを知ることができますか、一致しているかどうかを示すブール値が好きではありません(私はそのようなものを意味しますか?) –

+0

わかりません。あなたの問題をより多くの人に見てもらうために、新しい質問を投稿してください。それはより多くの人にとって興味深いかもしれません。 – micfra

+0

しかしあなたのコードは正しいですか?それはなぜ偽のマッチのために矩形を描画するのですか? –

0

あなたがOpenCVの3を使用したいと多くの場合そこにはのHighGUIは、OpenCVの3ではありませんし、あなたの代わりに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); 
} 

}