2013-03-07 1 views
2

Здравствуйте, я пытаюсь извлечь данные из дескриптора SURF, когда я пытаюсь использовать этот дескриптор ORB, он работает. Когда я использую SURF, программа завершает работу с ошибкой сегментации 11 в кодировке base64, я использую функцию base64 с этого сайта: Encoding and decoding base64.Кодирование CV_32FC1 Данные мата с base64

Точная проблема заключается в том, что формат дескриптора ORB составляет CV_8UC1 и дескриптор SURF CV_32FC1. Поэтому я должен base64 кодировать 32-битный float вместо 8-битного беззнакового символа.

Как это сделать?

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 
+0

Пожалуйста, будьте более конкретными. Какая строка вызывает segfault? – Aurelius

+0

Прошу прощения, что вы правы, я уточнил вопрос с дополнительной информацией. – tversteeg

+0

Я могу воспроизвести segfault только тогда, когда данные дескриптора 'NULL'. Также см. Мой отредактированный ответ. Ваш отредактированный вопрос намного лучше, и более точно описывает вашу фактическую проблему. Также обратите внимание, что у вас будет гораздо больше шансов получить хорошие ответы, если ваши вопросы не сводятся к просьбам «отлаживать мой код для меня». – Aurelius

ответ

1

Одним из источников ваших проблем может быть не проверка inBuffer за NULL значений перед использованием. Если дескрипторы не были сгенерированы из изображения, которое вы проходите, desc.data, а также по расширению inBuffer, будет NULL.

Еще несколько вещей:

  1. Использование reinterpret_cast является ненужным, и вполне возможно, небезопасно. См. this question для хорошего объяснения типов литья. Если вы хотите константный указатель на данные дескриптора, вы можете просто присвоить один так:

    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> для доступа к элементу.

EDIT: В свете обновленного вопроса, точка 2 является менее актуальной. Возникает дополнительная проблема: преобразование с float в uchar через convertTo() потеряет информацию. В этом случае преобразование сделает исходную точность данных дескриптора неустранимой. Возможно, можно просто обрабатывать данные дескриптора, как и раньше, предполагая, что ваша кодировка base64 работает, но это выходит за рамки этого вопроса.

+0

Мне может потребоваться добавить дополнительную информацию, я использую функцию кодирования base64 для отправки данных Mat: 'string base64_encode (unsigned char const * bytes_to_encode, unsigned int in_len)', но можно ли отлировать float в байты без потери информации? – tversteeg

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

Не забудьте включить библиотеку (например, opencv_nonfree243.lib).

+0

Мне пришлось добавить '#include ', и я добавил свой код, но я все еще получаю ошибку сегментации. – tversteeg

Смежные вопросы