質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.52%

  • C++

    3439questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • Visual Studio

    1825questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

  • OpenCV

    1069questions

    OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

OpenCVによる画像マッチング

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,429

stdnium

score 6

前提・実現したいこと

VisualStudio15 2017上でOpenCVを動かし、SIFT特徴量を用いた画像マッチングに取り組もうと思っています。
しかし、コンパイルで以下のエラーが発生し解決策が見つからず困っている状況です。

発生している問題・エラーメッセージ

・エラーメッセージ
namespace "cv" にメンバー "initModule_nonfree" がありません
class "cv::Feature2D" にメンバー "create" がありません
class "cv::Feature2D" にメンバー "create" がありません

該当のソースコード

#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp> // SIFT・SURFモジュール用

void FeatureMatching(
    const std::string& lenna,            // 画像1のファイル名
    const std::string& lenna2,            // 画像2のファイル名
    const std::string& STAR,        // detectorType
    const std::string& FREAK,    // descriptorExtractorType
    const std::string& MATCH,    // descriptorMatcherType
    bool crossCheck = true)                // マッチング結果をクロスチェックするかどうか
{
    // 画像の読み込み
    cv::Mat img1 = cv::imread("C:\\opencv\\image\\lenna.jpg");
    cv::Mat img2 = cv::imread("C:\\opencv\\image\\lenna2.jpg");

    // SIFT・SURFモジュールの初期化
    cv::initModule_nonfree();

    // 特徴点抽出
    cv::Ptr<cv::FeatureDetector> detector = cv::FeatureDetector::create("STAR");
    std::vector<cv::KeyPoint> keypoint1, keypoint2;
    detector->detect(img1, keypoint1);
    detector->detect(img2, keypoint2);

    // 特徴記述
    cv::Ptr<cv::DescriptorExtractor> extractor = cv::DescriptorExtractor::create("FREAK");
    cv::Mat descriptor1, descriptor2;
    extractor->compute(img1, keypoint1, descriptor1);
    extractor->compute(img2, keypoint2, descriptor2);

    // マッチング
    cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create("MATCH");
    std::vector<cv::DMatch> dmatch;
    if (crossCheck)
    {
        // クロスチェックする場合
        std::vector<cv::DMatch> match12, match21;
        matcher->match(descriptor1, descriptor2, match12);
        matcher->match(descriptor2, descriptor1, match21);
        for (size_t i = 0; i < match12.size(); i++)
        {
            cv::DMatch forward = match12[i];
            cv::DMatch backward = match21[forward.trainIdx];
            if (backward.trainIdx == forward.queryIdx)
                dmatch.push_back(forward);
        }
    }
    else
    {
        // クロスチェックしない場合
        matcher->match(descriptor1, descriptor2, dmatch);
    }

    // マッチング結果の表示
    cv::Mat out;
    cv::drawMatches(img1, keypoint1, img2, keypoint2, dmatch, out);
    cv::imshow("matching", out);
    while (cv::waitKey(1) == -1);
}

試したこと

OpenCVのソースをCmakeでコンパイルし導入。
(参照サイト:https://qiita.com/tomochiii/items/fa26404ebc5fcd4481b9)
(contrib\moduleのパスも設定済)

さらに別サイト(http://whoopsidaisies.hatenablog.com/entry/2013/12/07/135810)を参考にソースコードを入力し、OpenCV3以降の仕様変更に合わせ
"#include <opencv2/nonfree/nonfree.hpp>"
の部分を
"#include <opencv2/xfeatures2d/nonfree.hpp>"
に変更しました。
また、元のソースコードのfilename1,filename2,featureDetectorName,descriptorExtractorName,descriptorMatcherNameに何かしらの入力が必要かと思い、それぞれ適当な文字列を入力しました。

補足情報(言語/FW/ツール等のバージョンなど)

VisualStudio15 2017
OpenCV 3.2.0
(OpenCV 3.1.0でも試したところ同エラーにより動かず)

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+3

こんにちは。

SHIFTやSURF等の特許が絡むようなものはどうやらcontribに移動しているようです。(OpenCV3.0.0-alphaの特徴抽出・マッチングまとめ
↓が参考になりそうです。
Visual Studio 2017にOpenCV3.2.0とopencv_contribを導入する方法

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/30 12:16

    contribを導入しmoduleのパスも設定済でした。
    OpenCVが3.1.0だったため、サイトを参照し3.2.0を導入し試してみましたが同じエラーが出て動かず…でした。

    キャンセル

  • 2017/10/30 12:58

    ということは、ヘッダのパス以外にも変更点があるということになります。
    その変更点を知っている人がここで回答してくれれば良いのですが、ごめんなさい、私は把握していません。

    回答が得られない場合は、その変更点を何らかの方法(OpenCVの変更来歴や解説サイトを探す、OpenCVのソースを読むなど)で見つけるか、動作することが分かっているOpenCVの古いバージョンでやってみるのが常套手段と思います。

    キャンセル

checkベストアンサー

+2

OpenCV3.1では、次のコードで動作しました。

#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp> // SIFT・SURFモジュール用

void FeatureMatching(void)
{
    // 画像の読み込み
    cv::Mat img1 = cv::imread(R"(C:\Users\MyName\Pictures\Lenna.png)");
    cv::Mat img2 = cv::imread(R"(C:\Users\MyName\Pictures\Lenna.png)");

    // 特徴点抽出
    auto detector = cv::xfeatures2d::StarDetector::create();
    std::vector<cv::KeyPoint> keypoint1, keypoint2;
    detector->detect(img1, keypoint1);
    detector->detect(img2, keypoint2);

    // 特徴記述
    auto extractor = cv::xfeatures2d::FREAK::create();
    cv::Mat descriptor1, descriptor2;
    extractor->compute(img1, keypoint1, descriptor1);
    extractor->compute(img2, keypoint2, descriptor2);

    // マッチング
    auto matcher = cv::DescriptorMatcher::create("BruteForce-L1");
    std::vector<cv::DMatch> dmatch;
    if (true)
    {
        // クロスチェックする場合
        std::vector<cv::DMatch> match12, match21;
        matcher->match(descriptor1, descriptor2, match12);
        matcher->match(descriptor2, descriptor1, match21);
        for (size_t i = 0; i < match12.size(); i++)
        {
            cv::DMatch forward = match12[i];
            cv::DMatch backward = match21[forward.trainIdx];
            if (backward.trainIdx == forward.queryIdx)
                dmatch.push_back(forward);
        }
    }
    else
    {
        // クロスチェックしない場合
        matcher->match(descriptor1, descriptor2, dmatch);
    }

    // マッチング結果の表示
    cv::Mat out;
    cv::drawMatches(img1, keypoint1, img2, keypoint2, dmatch, out);
    cv::imshow("matching", out);
    while (cv::waitKey(1) == -1);
}

int main(void) {
    FeatureMatching();
    return 0;
}

リファレンス実装を漁っていたらなんとなく動きました。
SIFTも試してみましたが、initModule_nonfreeはやはり不要なようです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/06 22:49

    ご回答ありがとうございます。
    上記のソースコードでビルドしてみたところ、

    LNK2001 外部シンボル ""void __cdecl cv::imshow(class cv::String const &,class cv::_InputArray const &)" (?imshow@cv@@YAXAEBVString@1@AEBV_InputArray@1@@Z)" は未解決です。

    なるエラーを吐きました。
    VisualStudioのバージョンは2017、OpenCVのバージョンは3.1.0です。
    もし解決方法がわかれば教えて頂きたいです。

    キャンセル

  • 2017/11/06 22:51

    追加の依存ファイルにopencv_highgui310.libかopencv_highgui310d.libを足してください。
    前者がリリースモード、後者がデバッグモードに対応します。

    キャンセル

  • 2017/11/07 01:24

    お陰様でビルドに成功しました。
    ご丁寧にありがとうございます。

    続けて申し訳ないのですが、デバッグを行うと、

    ハンドルされない例外が 0x00007FFB4CB69E08 で発生しました (Project.exe 内): Microsoft C++ の例外: cv::Exception (メモリの場所 0x00000086804FE340)。 が発生しました

    といったエラーが出てプログラムの動作が止まってしまいます。
    この解決方法についてご教授頂けないでしょうか。
    よろしくお願いします。

    キャンセル

  • 2017/11/07 01:28

    コメントアウトで確認した結果、//特徴記述 以降で発生しています。

    キャンセル

  • 2017/11/07 01:36

    度々の追記失礼いたします。

    extractor->compute(img1, keypoint1, descriptor1);

    で躓いているようです。

    キャンセル

  • 2017/11/07 02:02

    画像は確かに二枚とも開けていますか?

    キャンセル

  • 2017/11/07 02:05

    cv::imshowを挿入し表示してみたところ、img1,img2は二枚とも無事表示できました。

    キャンセル

  • 2017/11/07 02:10

    記述子の生成に失敗しているように思います。とりあえずFREAK以外を試してみてください。

    キャンセル

  • 2017/11/07 02:16

    FREAKをSIFTに変更すると動きました…!
    テストプログラムであり、今後FREAKを使う予定はないので問題解決です。
    ご親切にありがとうございました。BAにさせて頂きます。

    キャンセル

  • 2017/11/07 09:44

    うまくいったようで良かったです。頑張ってくださいね。

    キャンセル

0

もしかして: cmakeした時にBUILD_opencv_nonfreeOFFになっていた

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/27 13:20

    ご回答ありがとうございます。
    只今Cmakeを確認してみたところ、BUILD_opencv_nonfreeなる項目が存在しませんでした…。

    キャンセル

  • 2017/10/27 13:28

    おおっと、古い情報だった、失礼

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 受付中

    OpenCVで動画の読み込みがうまくできません。

    以前別のプログラムで動画の読み込みができましたが、今現在取り組んでいるプログラムではうまくいきません。   言語はC++を使用しています。  ・ソースコード  ヘッダファ

  • 解決済

    opencvのcvConvertScaleAbs関数エラーを直したい

    こんにちは。 どうしても解決できず、ずっと悩んでいるのでご助力いただけないかと思い投稿しました。 前提・実現したいこと XcodeでC++、opencvを用いて行列操作を

  • 解決済

    opencv 動画 再生

    #include <stdio.h> #include <cv.h> #include <highgui.h> int main(int argc, char* argv[])

  • 解決済

    OpenCVを用いた物体検出

    現在OpenCV2.1を用いた上で顔検出にチャレンジしています。 学習等については問題なく行うことができ、顔の検出を行おうと思っているのですが、検出の段階で設定するパラメータの"m

  • 解決済

    OpenCVを使った笑顔検出での問題

    前提・実現したいこと OpenCVで元からあるサンプルコード「smiledetect.cpp」を用いて笑顔検出のシステムを作っています。 検出機能を実装中に以下の問題が発生しました

  • 解決済

    OpenCVを使って動画の書き出しができない

    aviファイルを読み込み,1フレームずつ間隔をSleep関数を用いて変化させて再生速度を変えるプログラムを作っています. 0倍速,等倍速,2倍速,3倍速,4倍速,5倍速の速度を行き

  • 解決済

    OpenCVでのcv::Mat型のデータへのアクセス方法

    前提・実現したいこと cv::Mat型のデータへのアクセスの仕方に困っています。 c++とOpenCVを使い画像から特徴量を抽出するプログラムを作成しました。 アルゴリズムはA

  • 解決済

    OpenCV Error: Assertion failed が発生したりしなかったりします

    visual studio 2017  version 15.8.4で opencv3.1.0の関数を利用する時に Assertion failed が起きたり起きなかったりするの

同じタグがついた質問を見る

  • C++

    3439questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • Visual Studio

    1825questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

  • OpenCV

    1069questions

    OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。