2013-02-16 8 views
3

У меня есть вопрос о последней части работы SiftDescriptorExtractor,Как SiftDescriptorExtractor от OpenCV конвертирует дескриптор?

Я делаю следующее:

SiftDescriptorExtractor extractor; 
    Mat descriptors_object; 
    extractor.compute(img_object, keypoints_object, descriptors_object); 

Теперь я хочу, чтобы проверить элементы объекта descriptors_object Mat:

std::cout<< descriptors_object.row(1) << std::endl; 

выход выглядит следующим образом:

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 32, 15, 0, 0, 0, 0, 0, 0, 73, 33, 11, 0, 0, 0, 0, 0, 0, 5, 114, 1, 0, 0, 0, 0, 51, 154, 20, 0, 0, 0, 0, 0, 154, 154, 1, 2, 1, 0, 0, 0, 154, 148, 18, 1, 0, 0, 0, 0, 0, 2, 154, 61, 0, 0, 0, 0, 5, 60, 154, 30, 0, 0, 0, 0, 34, 70, 6, 15, 3, 2, 1, 0, 14, 16, 2, 0, 0, 0, 0, 0, 0, 0, 154, 84, 0, 0, 0, 0, 0, 0, 154, 64, 0, 0, 0, 0, 0, 0, 6, 6, 1, 0, 1, 0, 0, 0] 

Но в Lowe paper говорится, что:

Таким образом, мы уменьшаем влияние больших градиентов величин с помощью Thresholding значений в вектор признаков блока к каждому из них будет не больше , чем 0,2, а затем перенормировки к единица измерения длина. Это означает, что сопоставление величин для больших градиентов уже не столь важно и что распределение ориентации имеет больший акцент. Значение 0,2 составляло , определяемое экспериментально с использованием изображений , содержащих различную освещенность для тех же трехмерных объектов.

Таким образом, цифры из вектор-функции должны быть не более 0,2.

Вопрос в том, как эти значения были преобразованы в объект Mat?

ответ

6

Таким образом, цифры из вектор-функции должны быть не более 0,2 .

Нет. В документе сказано, что Просеять дескрипторы:

  1. нормализованы (с нормой L2)
  2. усечены с использованием 0.2 в качестве порогового значения (т.е. цикл по нормированных значений и усечение, когда это уместно)
  3. нормализованы снова

Таким образом, в теории любой компонент SIFT дескрипторов между [0, 1], хотя на практике наблюдаемый эффективный диапазон меньше (см. Ниже).

Вопрос в том, как эти значения были преобразованы в объект Mat?

Они преобразуются из значений с плавающей точкой в ​​unsigned char-s.

Вот соответствующий раздел из OpenCV modules/nonfree/src/sift.cppcalcSIFTDescriptor метод:

float nrm2 = 0; 
len = d*d*n; 
for(k = 0; k < len; k++) 
    nrm2 += dst[k]*dst[k]; 
float thr = std::sqrt(nrm2)*SIFT_DESCR_MAG_THR; 
for(i = 0, nrm2 = 0; i < k; i++) 
{ 
    float val = std::min(dst[i], thr); 
    dst[i] = val; 
    nrm2 += val*val; 
} 
nrm2 = SIFT_INT_DESCR_FCTR/std::max(std::sqrt(nrm2), FLT_EPSILON); 
for(k = 0; k < len; k++) 
{ 
    dst[k] = saturate_cast<uchar>(dst[k]*nrm2); 
} 

С:

static const float SIFT_INT_DESCR_FCTR = 512.f; 

Это потому, что классические реализации Просеять квантовать нормализованные значения с плавающей запятой в unsigned char целое через 512 множитель , что эквивалентно рассмотрению того, что любой SIFT-компонент варьируется от [0, 1/2] и, таким образом, избегает потери точности, пытаясь кодировать полный [0, 1] область.

+0

спасибо за объяснение! Итак, теперь у нас есть float dst с 128 значениями для каждой ключевой точки. Как поместить их все в объект Mat? – fen1ksss

+0

Если обнаружены ключевые точки «N», дескрипторы сохраняются в матрице «N x 128», то есть в строках «N», где каждая строка (= ключевая точка) имеет 128 столбцов для хранения компонентов SIFT. – deltheil

+0

дополнительно еще один вопрос http://stackoverflow.com/questions/15038797/how-to-use-sift-algorithm-with-a-color-inverted-image – fen1ksss