Здравствуйте, я пытаюсь извлечь данные из дескриптора SURF, когда я пытаюсь это с дескриптором ORB, он работает. Когда я использую SURF, программа завершается с ошибкой сегментации 11 в строке кодирования base64, я использую функцию base64 с этого сайта: Кодирование и декодирование base64.
Точная проблема в том, что формат дескриптора ORB CV_8UC1
и дескриптор SURF CV_32FC1
, Таким образом, я должен base64 кодировать 32-разрядное число с плавающей запятой вместо 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
Одним из источников ваших проблем может быть вы не проверяете inBuffer
за NULL
значения, прежде чем использовать его. Если из изображения, которое вы передаете, не было создано никаких дескрипторов, desc.data
и, соответственно, inBuffer
, будет NULL
,
Еще несколько вещей:
Ваше использование reinterpret_cast
является ненужным и, возможно, небезопасным. Увидеть этот вопрос для хорошего объяснения типов актеров. Если вам нужен постоянный указатель на данные дескриптора, вы можете просто назначить его так:
const uchar* inBuffer = desc.data;
SURF использует float
дескрипторы, в то время как ORB использует двоичные дескрипторы. Если вы намереваетесь использовать SURF, возможно, вам придется изменить свой код. Назначение inBuffer
может быть изменен на
const float* inBuffer = reinterpret_cast<const float*>(desc.data);
В этом случае использование reinterpret_cast
может быть уместным. Тем не менее, может быть целесообразно избегать прямых манипуляций с указателями, если в этом нет необходимости. Рассмотреть возможность использования cv::Mat_<float>
для доступа к элементу.
РЕДАКТИРОВАТЬ: В свете обновленного вопроса пункт 2 является менее актуальным. Возникает дополнительная проблема: преобразование из float
в uchar
с помощью convertTo()
потеряет информацию. В этом случае преобразование сделает исходную точность данных дескриптора невосстановимой. Может быть возможно просто обработать данные дескриптора как прежде, предполагая, что ваша кодировка base64 работает, но это выходит за рамки этого вопроса.
cv::initModule_nonfree(); //Patent protection related.
Не забудьте включить библиотеку (например, opencv_nonfree243.lib).