2
votes

Hello I am trying to extract the data from a SURF descriptor, when I try this with an ORB descriptor it works. When I use the SURF one the program quits with a segmentation fault 11 on the base64 encode line, I use the base64 function from this site: Encoding and decoding base64.

The exact problem is that the format for the ORB descriptor is CV_8UC1 and the SURF descriptor CV_32FC1. So I must base64 encode a 32 bit float instead of a 8 bit unsigned char.

How can I do this?

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
2
Please be a little more specific. Which line causes the segfault?Aurelius
I'm sorry you are right, I updated the question with more information.tversteeg
I can only reproduce the segfault when the descriptor data is NULL. Also, see my edited answer. Your edited question is much better, and more accurately describes your actual problem. Also note that you will be much more likely to get good answers if your questions don't boil down to "please debug my code for me" requests.Aurelius
Yes I agree that my question is better this way, but I thought the problem was somewhere else. And I am not necessary looking for someone to debug my code, I am trying to get a pointer to where the problem could be and how I could fix it; I really want to find out myself but the documentation on these subjects is so limited.tversteeg
Ah, that is understandable. I meant no offense.Aurelius

2 Answers

1
votes

One source of your problems could be you do not check inBuffer for NULL values before you use it. If no descriptors were generated from the image you pass in, desc.data, and by extension inBuffer, will be NULL.

A few more things:

  1. Your use of reinterpret_cast is unnecessary, and quite possibly unsafe. See this question for a good explanation of cast types. If you want a const pointer to the descriptor data, you can simply assign one like so:

    const uchar* inBuffer = desc.data;
    
  2. SURF uses float descriptors, while ORB uses binary descriptors. If you intend to use SURF, you may need to change your code. The assignment of inBuffer could be changed to

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

    In this case the use of reinterpret_cast may be appropriate. However, it might be advisable to avoid doing the direct pointer manipulation unless you really have to. Consider using cv::Mat_<float> for element access.

EDIT: In light of the updated question, point 2 is less relevant. An additional issue arises: Converting from float to uchar via convertTo() will lose information. In this case, the conversion will make the original precision of the descriptor data unrecoverable. It may be possible to simply treat descriptor data as before, assuming your base64 encoding works, but that is beyond the scope of this question.

0
votes
cv::initModule_nonfree(); //Patent protection related.

Don't forget to include the library (e.g. opencv_nonfree243.lib).