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

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

ただいまの
回答率

89.13%

SIFT特徴量の使い方、error: 'SiftFeatureDetector' was not declared in this scope

解決済

回答 1

投稿

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

deb

score 17

前提・実現したいこと

C++で画像の特徴抽出をするプログラムを書いています。
SIFT特徴量を使って、読み込んだ画像に特徴点を描画するという内容です。
ブログから引用したのでほぼ自分では書いていませんが、OpenCVのバージョンがブログとは違い、ヘッダファイルのある場所が異なっていたので一部を書き換えました。

該当のソースコード

///sift_keypoint_output.cpp

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp>//SIFTまたはSURFを使う場合は必要(変更ア)
using namespace cv;
using namespace std;

#if _DEBUG
#pragma comment(lib, "opencv_core2413d.lib")
#pragma comment(lib, "opencv_features2d2413d.lib")
#pragma comment(lib, "opencv_highgui2413d.lib")
#pragma comment(lib, "opencv_imgproc2413d.lib")
#pragma comment(lib, "opencv_nonfree2413d.lib")
#else
#pragma comment(lib, "opencv_core2413.lib")
#pragma comment(lib, "opencv_features2d2413.lib")
#pragma comment(lib, "opencv_highgui2413.lib")
#pragma comment(lib, "opencv_imgproc2413.lib")
#pragma comment(lib, "opencv_nonfree2413.lib")
#endif

int main(void)
{
    // 入力画像の取得
    Mat color_image = imread("miyazawa.png", 1);
    if (color_image.empty()) {
        return -1;
    }

    // カラー画像をグレースケールに変換
    Mat gray_image;
    cvtColor(color_image, gray_image, CV_RGB2GRAY);
    normalize(gray_image, gray_image, 0, 255, NORM_MINMAX);

    // SIFT特徴点の抽出
    cv::initModule_nonfree();//SIFTまたはSURFを使う場合はこれを呼び出す(変更イ)
    vector<KeyPoint> keypoints;
    vector<KeyPoint>::iterator itk;
    double threshold = 0.05;
    double edge_threshold = 10.0;
    SiftFeatureDetector detector(threshold, edge_threshold);
    detector.detect(gray_image, keypoints);

    // キーポイントの数を表示
    int keypoint_num = keypoints.size();
    cout << "keypoint_num :" << keypoint_num << endl;

    // 結果を表示
    Mat output_image_1, output_image_2;
    drawKeypoints(color_image, keypoints, output_image_1, Scalar(0, 255, 0), 0);
    drawKeypoints(color_image, keypoints, output_image_2, Scalar(0, 255, 0), 4);
    imshow("Result Keypoint", output_image_1);
    imshow("Result Keypoint Size and Direction", output_image_2);

    // 結果を保存
    imwrite("output_image_1.png", output_image_1);
    imwrite("output_image_2.png", output_image_2);

    waitKey(0);
}

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

sift_keypoint_output.cpp: In function 'int main()':
sift_keypoint_output.cpp:40:9: error: 'initModule_nonfree' is not a member of 'cv'
     cv::initModule_nonfree();//SIFT絛RF・1;31m^~~~~~~~~~~~~~~~~~
sift_keypoint_output.cpp:45:2: error: 'SiftFeatureDetector' was not declared in this scope
  SiftFeatureDetector detector(threshold, edge_threshold);
  ^~~~~~~~~~~~~~~~~~~
sift_keypoint_output.cpp:45:2: note: suggested alternative:
In file included from sift_keypoint_output.cpp:8:
\Anaconda3\Library\include\opencv2\opencv_contrib-3.1.0\opencv_contrib-3.1.0\modules\xfeatures2d\include/opencv2/xfeatures2d/nonfree.hpp:84:14: note:   'cv::xfeatures2d::SiftFeatureDetector'
 typedef SIFT SiftFeatureDetector;
              ^~~~~~~~~~~~~~~~~~~
sift_keypoint_output.cpp:46:2: error: 'detector' was not declared in this scope
  detector.detect(gray_image, keypoints);
  ^~~~~~~~
sift_keypoint_output.cpp:46:2: note: suggested alternative: 'getchar'
  detector.detect(gray_image, keypoints);
  ^~~~~~~~
  getchar


エラーコード上から4行目の'SiftFeatureDetecter' was not ~~でそれが定義されていないと指摘されました。

試したこと

'SiftFeatureDetecter'が定義されているはずのヘッダファイル'nonfree.hpp'の中身を確認しましたが、問題ないように見えますし、ヘッダファイルのインクルードでのエラーは出ていません。
何が問題なのでしょうか。お力添えお願いします。

//nonfree.hpp//

#ifndef __OPENCV_XFEATURES2D_FEATURES_2D_HPP__
#define __OPENCV_XFEATURES2D_FEATURES_2D_HPP__

#include "opencv2/features2d.hpp"

namespace cv
{
namespace xfeatures2d
{

//! @addtogroup xfeatures2d_nonfree
//! @{

/** @brief Class for extracting keypoints and computing descriptors using the Scale Invariant Feature Transform
(SIFT) algorithm by D. Lowe @cite Lowe04 .
 */
class CV_EXPORTS_W SIFT : public Feature2D
{
public:
    /**
    @param nfeatures The number of best features to retain. The features are ranked by their scores
    (measured in SIFT algorithm as the local contrast)

    @param nOctaveLayers The number of layers in each octave. 3 is the value used in D. Lowe paper. The
    number of octaves is computed automatically from the image resolution.

    @param contrastThreshold The contrast threshold used to filter out weak features in semi-uniform
    (low-contrast) regions. The larger the threshold, the less features are produced by the detector.

    @param edgeThreshold The threshold used to filter out edge-like features. Note that the its meaning
    is different from the contrastThreshold, i.e. the larger the edgeThreshold, the less features are
    filtered out (more features are retained).

    @param sigma The sigma of the Gaussian applied to the input image at the octave \#0. If your image
    is captured with a weak camera with soft lenses, you might want to reduce the number.
     */
    CV_WRAP static Ptr<SIFT> create( int nfeatures = 0, int nOctaveLayers = 3,
                                    double contrastThreshold = 0.04, double edgeThreshold = 10,
                                    double sigma = 1.6);
};

typedef SIFT SiftFeatureDetector;
typedef SIFT SiftDescriptorExtractor;

/** @brief Class for extracting Speeded Up Robust Features from an image @cite Bay06 .

The algorithm parameters:
-   member int extended
    -   0 means that the basic descriptors (64 elements each) shall be computed
    -   1 means that the extended descriptors (128 elements each) shall be computed
-   member int upright
    -   0 means that detector computes orientation of each feature.
    -   1 means that the orientation is not computed (which is much, much faster). For example,
if you match images from a stereo pair, or do image stitching, the matched features
likely have very similar angles, and you can speed up feature extraction by setting
upright=1.
-   member double hessianThreshold
Threshold for the keypoint detector. Only features, whose hessian is larger than
hessianThreshold are retained by the detector. Therefore, the larger the value, the less
keypoints you will get. A good default value could be from 300 to 500, depending from the
image contrast.
-   member int nOctaves
The number of a gaussian pyramid octaves that the detector uses. It is set to 4 by default.
If you want to get very large features, use the larger value. If you want just small
features, decrease it.
-   member int nOctaveLayers
The number of images within each octave of a gaussian pyramid. It is set to 2 by default.
@note
   -   An example using the SURF feature detector can be found at
        opencv_source_code/samples/cpp/generic_descriptor_match.cpp
    -   Another example using the SURF feature detector, extractor and matcher can be found at
        opencv_source_code/samples/cpp/matcher_simple.cpp
 */
class CV_EXPORTS_W SURF : public Feature2D
{
public:
    /**
    @param hessianThreshold Threshold for hessian keypoint detector used in SURF.
    @param nOctaves Number of pyramid octaves the keypoint detector will use.
    @param nOctaveLayers Number of octave layers within each octave.
    @param extended Extended descriptor flag (true - use extended 128-element descriptors; false - use
    64-element descriptors).
    @param upright Up-right or rotated features flag (true - do not compute orientation of features;
    false - compute orientation).
     */
    CV_WRAP static Ptr<SURF> create(double hessianThreshold=100,
                  int nOctaves = 4, int nOctaveLayers = 3,
                  bool extended = false, bool upright = false);

    CV_WRAP virtual void setHessianThreshold(double hessianThreshold) = 0;
    CV_WRAP virtual double getHessianThreshold() const = 0;

    CV_WRAP virtual void setNOctaves(int nOctaves) = 0;
    CV_WRAP virtual int getNOctaves() const = 0;

    CV_WRAP virtual void setNOctaveLayers(int nOctaveLayers) = 0;
    CV_WRAP virtual int getNOctaveLayers() const = 0;

    CV_WRAP virtual void setExtended(bool extended) = 0;
    CV_WRAP virtual bool getExtended() const = 0;

    CV_WRAP virtual void setUpright(bool upright) = 0;
    CV_WRAP virtual bool getUpright() const = 0;
};

typedef SURF SurfFeatureDetector;
typedef SURF SurfDescriptorExtractor;

//! @}

}
} /* namespace cv */

#endif

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

Anaconda 3
OpenCV 3.1.0

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+2

namespace cv
{
namespace xfeatures2d
{
...
typedef SIFT SiftFeatureDetector;
typedef SIFT SiftDescriptorExtractor;

cv::xfeatures2d::SiftFeatureDetectorでは。


エラーメッセージにも同じようなことが書いてありますね。

sift_keypoint_output.cpp:45:2: error: 'SiftFeatureDetector' was not declared in this scope
  SiftFeatureDetector detector(threshold, edge_threshold);
  ^~~~~~~~~~~~~~~~~~~
sift_keypoint_output.cpp:45:2: note: suggested alternative:
In file included from sift_keypoint_output.cpp:8:
\Anaconda3\Library\include\opencv2\opencv_contrib-3.1.0\opencv_contrib-3.1.0\modules\xfeatures2d\include/opencv2/xfeatures2d/nonfree.hpp:84:14: note:   'cv::xfeatures2d::SiftFeatureDetector'
 typedef SIFT SiftFeatureDetector;
              ^~~~~~~~~~~~~~~~~~~

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/02/06 12:26

    なるほど!名前空間はしっかり意識しないと忘れてしまいますね…。
    ご指摘ありがとうございます。

    キャンセル

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

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