Я пытаюсь использовать OpenCV для генерации дескрипторов в ключевых точках изображения на iOS. Я сделал обнаружение объектов, используя свой собственный алгоритм, и теперь хочу извлечь дескрипторы в этих точках.
Я реализовал следующий код для этого:
cv::Mat frame = LH_ImageProcessing::extractGrayFromBGRA(Img, 480, 640);
std::vector<cv::KeyPoint> keyPoints;
cv::Mat descriptors;
for (int i = 0; i < cornersDetected; i++) {
keyPoints.push_back(cv::KeyPoint((float) cornerArray[i*2], (float) cornerArray[i*2+1], 5));
}
cv::BriefDescriptorExtractor extractor;
extractor.compute(frame, keyPoints, descriptors);
Однако дескрипторы Mat всегда пустые после того, как я запустил функцию «вычисления». Все указатели просто NULL, хотя я ясно вижу, что массив keyPoints имеет уменьшенный размер после его запуска. Это означает, что он удаляет ключевые точки, для которых он не может извлечь дескрипторы.
Я подумал, что это моя реализация, поэтому я использовал встроенный детектор (SurfDetector) и скопировал реализацию из примера OpenCV FREAK. Но в итоге я получаю тот же результат.
У кого-то еще есть проблемы, или я пропустил что-то фундаментальное в OpenCV?
РЕДАКТИРОВАТЬ:
Так что я еще раз отследил проблему. Похоже, что передача по ссылке не меняет исходную структуру данных cv :: Mat.
Объявление функции для функции вычисления выглядит следующим образом:
void DescriptorExtractor::compute( const Mat& image, std::vector<KeyPoint>& keypoints, Mat& descriptors ) const
{
....
computeImpl( image, keypoints, descriptors );
}
ComputeImpl — это функция, которая фактически вычисляет дескрипторы. В моем случае КРАТКИЙ дескриптор.
void BriefDescriptorExtractor::computeImpl(const Mat& image, std::vector<KeyPoint>& keypoints, Mat& descriptors) const
Когда computeImpl функция возвращает дескрипторы переменная это то, что я ожидал. Он был инициализирован и содержит данные, которые я хочу. Тем не менее, когда DescriptorExtractor :: вычислить Метод возвращает новую структуру дескрипторов, которая не передается обратно в мой основной код, даже если это метод передачи по ссылке.
Что может быть причиной этого?
РЕДАКТИРОВАТЬ 2:
Вот несколько скриншотов моих переменных наблюдения во время отладки.
Дескрипторы Mat внутри функции .compute непосредственно перед возвратом функции
Сразу после того, как функция .compute возвращается в мою вызывающую функцию
Так что я наконец понял это. Хитрость заключается в том, чтобы использовать указатель и инициализировать пустой cv :: Mat, а затем передать этот указатель в функцию вычисления. Затем OpenCV повторно инициализирует его в функции .compute, а когда все возвращает, указатель указывает на новую структуру данных.
Кажется, что проблема возникла из-за того, что компилятор оптимизировал создание пустого cv :: Mat, поэтому, когда compute вернула память, память была освобождена.
Я изменился:
cv::Mat descriptors;
...
ext.compute(frame, keyPoints, descriptors);
в
cv::Mat *descriptors = new cv::Mat;
...
ext.compute(frame, keyPoints, *descriptors);
и теперь все отлично работает.