2014-10-24 1 views
1

Я смотрю в код в Features2D + Homography to find a known object OpenCV учебник ..OpenCV Keypoint расстояние соответствие DMatch переменной

я явно не понимаю, что переменная расстояния в классе Matcher. Является ли это расстоянием между пикселями совпадающих ключевых точек на обоих изображениях?

Этот знак QA указывает его меру подобия (либо эвклидовое расстояние, либо расстояние до Хэмминга двоичных дескрипторов) и рассчитывается по расстоянию между векторами дескриптора.

Может ли какой-либо орган передать информацию о том, как рассчитывается это расстояние или как совместить ключевые точки без использования существующих сокетов от OpenCV.

//-- Step 3: Matching descriptor vectors using FLANN matcher 
    FlannBasedMatcher matcher; 
    std::vector<DMatch> matches; 
    matcher.match(descriptors_object, descriptors_scene, matches); 

    double max_dist = 0; double min_dist = 100; 

    //-- Quick calculation of max and min distances between keypoints 
    for(int i = 0; i < descriptors_object.rows; i++) 
    { double dist = matches[i].distance; // --> What Distance indicate here 
    if(dist < min_dist) min_dist = dist; 
    if(dist > max_dist) max_dist = dist; 
    } 

enter image description here

Спасибо.

+2

это расстояние между дескрипторами, а не расстояние между характерными точками – berak

+0

@berak вы можете дать больше информации, как вычислить его. Потому что мне нравится выполнять сопоставление ключевых слов, не используя существующие соединители. – nayab

ответ

1

У меня возникла проблема, когда я работал над сопоставлением объектов в реальном времени с использованием детектора функции SIFT. Вот мое решение на видео.

Сначала я создал структуру для хранения сопоставленных ключевых точек. Структура содержит местоположение ключевой точки в шаблоне, расположение ключевой точки в методе inputImage и подобия. Здесь я использовал взаимную корреляцию векторов как меру подобия.

struct MatchedPair 
    { 
     Point locationinTemplate; 
     Point matchedLocinImage; 
     float correlation; 
     MatchedPair(Point loc) 
     { 
      locationinTemplate=loc; 
     } 
    } 

Я буду выбирать сорт совпавших в соответствии с ключевыми точками их сходств, поэтому я нужен вспомогательная функцией, которая будет сказать std::sort() к тому, как сравнивать мои MatchedPair объектов.

bool comparator(MatchedPair a,MatchedPair b) 
{ 
     return a.correlation>b.correlation; 
} 

Теперь начинается основной код. Я использовал стандартный метод для обнаружения и дешифрования функций как из входного изображения, так и из шаблона. После вычислений я реализовал свою собственную функцию соответствия. Это ответ, который вы ищете

int main() 
    { 
     Mat templateImage = imread("template.png",IMREAD_GRAYSCALE); // read a template image 
     VideoCapture cap("input.mpeg"); 
     Mat frame; 

     vector<KeyPoint> InputKeypts,TemplateKeypts; 
     SiftFeatureDetector detector; 
     SiftDescriptorExtractor extractor; 
     Mat InputDescriptor,templateDescriptor,result; 
     vector<MatchedPair> mpts; 
     Scalar s; 
     cap>>frame; 
     cvtColor(image,image,CV_BGR2GRAY); 
     Mat outputImage =Mat::zeros(templateImage.rows+frame.rows,templateImage.cols+frame.cols,CV_8UC1); 
     detector.detect(templateImage,TemplateKeypts); // detect template interesting points 
     extractor.compute(templateImage,TemplateKeypts,templateDescriptor); 

     while(true) 
     { 
      mpts.clear(); // clear for new frame 
      cap>>frame; // read video to frame 
      outputImage=Mat::zeros(templateImage.rows+frame.rows,templateImage.cols+frame.cols,CV_8UC1); // create output image 
      cvtColor(frame,frame,CV_BGR2GRAY); 
      detector.detect(frame,InputKeypts); 
      extractor.compute(frame,InputKeypts,InputDescriptor); // detect and descrypt frames features 

      /* 
       So far we have computed descriptors for template and current frame using traditional methods 
       From now onward we are going to implement our own match method 

    - Descriptor matrixes are by default have 128 colums to hold features of a keypoint.  
    - Each row in descriptor matrix represent 128 feature of a keypoint. 

Match methods are using this descriptor matrixes to calculate similarity. 

My approach to calculate similarity is using cross correlation of keypoints descriptor vector.Check code below to see how I achieved. 
     */ 

    // Iterate over rows of templateDesciptor (for each keypoint extracted from  // template Image) i keypoints in template,j keypoints in input 
      for (int i=0;i<templateDescriptor.rows;i++) 
      { 
       mpts.push_back(MatchedPair(TemplateKeypts[i].pt)); 
       mpts[i].correlation =0; 
       for (int j=0;j<InputDescriptor.rows;j++) 
       { 
        matchTemplate(templateDescriptor.row(i),InputDescriptor.row(j),result,CV_TM_CCOR_NORMED); 
// I have used opencvs built function to calculate correlation.I am calculating // row(i) of templateDescriptor with row(j) of inputImageDescriptor. 
        s=sum(result); // sum is correlation of two rows 
// Here I am looking for the most similar row in input image.Storing the correlation of best match and matchLocation in input image. 
        if(s.val[0]>mpts[i].correlation) 
        { 
         mpts[i].correlation=s.val[0]; 
         mpts[i].matchedLocinImage=InputKeypts[j].pt; 
        } 
       } 

      } 

// I would like to show template,input and matching lines in one output.   templateImage.copyTo(outputImage(Rect(0,0,templateImage.cols,templateImage.rows))); 
      frame.copyTo(outputImage(Rect(templateImage.cols,templateImage.rows,frame.cols,frame.rows))); 

    // Here is the matching part. I have selected 4 best matches and draw lines   // between them. You should check for correlation value again because there can // be 0 correlated match pairs. 

      std::sort(mpts.begin(),mpts.end(),comparator); 
      for(int i=0;i<4;i++) 
      { 

       if (mpts[i].correlation>0.90) 
       { 
// During drawing line take into account offset of locations.I have added 
// template image to upper left of input image in output image. 
      cv::line(outputImage,mpts[i].locationinTemplate,mpts[i].matchedLocinImage+Point(templateImage.cols,templateImage.rows),Scalar::all(255)); 
       } 
      } 
      imshow("Output",outputImage); 
      waitKey(33); 
     } 

    } 
+1

Не могли бы вы уменьшить свой пост, чтобы он сосредоточился на решении вопроса OP, вместо того, чтобы говорить о вашем методе и как он решил ** вашу проблему? – rayryeng

+0

@rayryeng Я хочу, чтобы он и будущие посетители поняли легко, поэтому я использовал много комментариев. Точка фокусировки - это часть математики, и я предварительно определил некоторые переменные и структуру, чтобы они отображались в коде. Также я рассказал, как я сравнивая desciptor, чтобы он мог реализовать свой собственный метод совпадения вместо того, чтобы использовать мой, как только он понял смысл дескрипторов. Я ценю ваши советы, если вы можете отредактировать мой ответ, чтобы сделать его более понятным. –

+0

О, я вижу! Тогда все в порядке. Я оставлю это :) – rayryeng

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