3

OpenCV 3.0.0 を使用して、画像を別の画像に配置しています。アプリオリに関数 matchTemplate を使用する必要がありますが、結果を見るともうわかりません。

問題は、入力画像に応じて、結果が完全に正確または完全に不正確になることです。

例 1:

メイン画像

単純

テンプレート

単純

結果

単純

ここに苦情はありません。この場合、マッチングは完璧です。しかし、今は使用したい画像に置き換えて...

メイン画像

複雑

テンプレート

複雑

結果

ここに画像の説明を入力

そのため、まったく機能していません (画像の右上に長方形が表示されます)。いずれの方法 (この例では CORR NORMED) も、テンプレートが配置されている四角形を出力します。すべての結果は正確とはほど遠いものです。

だから、私の質問は、 matchTemplate の結果は、メイン画像の色/形状の数に依存しますか? ここで SURF または SIFT は役に立ちますか? テンプレートを別の画像に配置するのに役立つ機能はありますか?

前もって感謝します!

PS: 最初の例がうまく機能するので、そのような問題ではないと思うので、コードを追加しませんでした。

4

1 に答える 1

10

あなたの問題は、テンプレートのマッチングがスケール不変ではないこと、テンプレートのサイズがオブジェクトのサイズに合わないことです。

この入力とコードを使用すると、次の出力が得られます。

入力画像:

ここに画像の説明を入力

入力テンプレート:

ここに画像の説明を入力

コード: 基本的に opencv チュートリアルから取得: http://docs.opencv.org/doc/tutorials/imgproc/histograms/template_matching/template_matching.html

int main()
{
    cv::Mat input = cv::imread("../inputData/TemplateMatch.jpg");

    cv::Mat gray;
    cv::cvtColor(input,gray,CV_BGR2GRAY);

    cv::Mat templ = cv::imread("../inputData/Template2.jpg");

    cv::Mat img = input;
    cv::Mat result;
    /// 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 );

    int match_method = CV_TM_SQDIFF;

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

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

    minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, cv::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
    cv::rectangle( input, matchLoc, cv::Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), cv::Scalar::all(0), 2, 8, 0 );
    cv::rectangle( result, matchLoc, cv::Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), cv::Scalar::all(0), 2, 8, 0 );


    cv::imshow("input", input);
    cv::imshow("template", templ);

    cv::imwrite("../outputData/TemplateMatch.jpg", input);
    cv::waitKey(0);
    return 0;
}

出力:

ここに画像の説明を入力

于 2014-10-29T15:26:16.537 に答える