2

こんにちは私はSURF記述子からデータを抽出しようとしています。これをORB記述子で試してみると機能します。SURFを使用すると、プログラムはbase64エンコードラインのセグメンテーション違反11で終了します。このサイトのbase64関数を使用します:base64のエンコードとデコード

正確な問題は、ORB記述子の形式がCV_8UC1とSURF記述子であるということCV_32FC1です。したがって、8ビットのunsignedcharではなく32ビットのfloatをbase64でエンコードする必要があります。

これどうやってするの?

Mat desc;
vector<KeyPoint> kp;

SurfFeatureDetector detector(500);
SurfDescriptorExtractor extractor;
// OrbDescriptorExtractor extractor; This works

detector.detect(image, kp);
extractor.compute(image, kp, desc);

desc.convertTo(desc, CV_8UC1, 255, 0);

unsigned char const* inBuffer = reinterpret_cast<unsigned char const*>(desc.data);
unsigned int in_len = desc.total();
string code = base64_encode(inBuffer, in_len).c_str(); // This line causes the error
4

2 に答える 2

1

問題の原因の1つは、使用する前に値をチェックしないことinBufferです。NULL渡した画像から記述子が生成されなかった場合、、、desc.dataおよび拡張子inBufferは、になりますNULL

さらにいくつか:

  1. の使用reinterpret_castは不要であり、おそらく安全ではありません。キャストタイプの適切な説明については、この質問を参照してください。記述子データへのconstポインターが必要な場合は、次のように割り当てることができます。

    const uchar* inBuffer = desc.data;
    
  2. SURFはfloat記述子を使用し、ORBはバイナリ記述子を使用します。SURFを使用する場合は、コードを変更する必要があるかもしれません。の割り当てを次のinBufferように変更できます

    const float* inBuffer = reinterpret_cast<const float*>(desc.data);
    

    この場合、の使用reinterpret_castが適切な場合があります。ただし、本当に必要な場合を除いて、直接ポインタ操作を行わないことをお勧めします。cv::Mat_<float>要素へのアクセスに使用することを検討してください。

編集:更新された質問に照らして、ポイント2はあまり関連性がありません。追加の問題が発生します。floatからuchar経由に変換convertTo()すると、情報が失われます。この場合、変換により、記述子データの元の精度が回復不能になります。base64エンコーディングが機能すると仮定すると、記述子データを以前と同じように単純に扱うことができる場合がありますが、それはこの質問の範囲を超えています。

于 2013-03-07T17:04:32.623 に答える
0
cv::initModule_nonfree(); //Patent protection related.

ライブラリ(例:opencv_nonfree243.lib)を含めることを忘れないでください。

于 2013-03-07T15:38:58.690 に答える