2015-09-11 4 views
1

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

Я работаю с битоновыми изображениями (документами). Если я сделаю копию одного и того же файла изображения и сравню оба (фактически сравнивая субрегион как [той же субрегиона]), я не получаю 100% совпадений, используя SURF. Вот часть моего кода:

public double FindPercentMatch(Bitmap obj, Bitmap scene) 
{ 

    // get scene key points 
    VectorOfKeyPoint scenePoints = GetKeyPoints((Bitmap)scene.Clone()); 

    // if no scene points found, no need to go any further 
    if (scenePoints == null || scenePoints.Size == 0) { return 0; } 

    // get object key points 
    VectorOfKeyPoint objectPoints = GetKeyPoints((Bitmap)obj.Clone());    

    // if not enough object key points found vs scene key points, then match can't be close enough (since 
    // you can't have more matches than scene points anyway, so don't even try to match 
    if (objectPoints == null || objectPoints.Size == 0 || (scenePoints.Size/objectPoints.Size < .15)) { return 0; } 

    // we have enough key points, so compute descriptors for scene and object 
    Matrix<float> objectDescriptors = GetDescriptors(objectPoints,(Bitmap)obj.Clone()); 
    Matrix<float> sceneDescriptors = GetDescriptors(scenePoints, (Bitmap)scene.Clone()); 
    int objectDescriptorCount = objectDescriptors == null ? 0 : objectDescriptors.Size.Height; 
    int sceneDescriptorCount = sceneDescriptors == null ? 0 : sceneDescriptors.Size.Height; 

    // find matches 
    int sim = FindMatches(objectDescriptors, sceneDescriptors); 

    // for testing so we know how many were found so we can monitor it 
    log.Debug("descriptors1 = " + objectDescriptorCount + ", 2 = " + sceneDescriptorCount + ", matches=" + sim); 

    double percent = 0; 
    if (sim != 0) 
    { 
     percent = objectDescriptorCount != 0 ? (double)sim/(double)objectDescriptorCount : 0; 
     log.Debug(percent * 100 + "%"); 
    } 
    return percent; 

} 

public int FindMatches(Matrix<float> dbDescriptors, Matrix<float> queryDescriptors) 
{ 

    double uniquenessThreshold = 0.6; 

    if (dbDescriptors == null || queryDescriptors == null) 
    { 
     return 0; 
    } 
    var indices = new Matrix<int>(queryDescriptors.Rows, 2); // matrix that will contain indices of the 2-nearest neighbors found 
    var dists = new Matrix<float>(queryDescriptors.Rows, 2); // matrix that will contain distances to the 2-nearest neighbors found 

    // create FLANN index with 4 kd-trees and perform KNN search over it look for 2 nearest neighbours 
    var flannIndex = new Index(dbDescriptors, 4); 

    flannIndex.KnnSearch(queryDescriptors, indices, dists, 2, 24); 

    // for eatch match over a certain threshold, add +1 to the number of 'good' matches 
    int sim = 0; 
    for (int i = 0; i < indices.Rows; i++) 
    { 
     // filter out all inadequate pairs based on distance between pairs 
     if (dists.Data[i, 0] < (uniquenessThreshold * dists.Data[i, 1])) 
     { 
      sim++; 
     } 
    } 
    return sim; 
} 

Ожидаемый результат при использовании FindPercentMatch на одной и той же подобласти изображения будет 100%, но в зависимости от изображения, это может быть 70%, 99%, и я даже видел 101%.

ответ

0

Я думаю, что я исправил мою проблему с помощью грубой силы Искателя вместо индекса flann. Кроме того, вместо того, чтобы использовать 2nn и сравнивать их, я нашел только первого ближайшего соседа и подсчитал все, что было под определенным порогом, как «хорошее совпадение». Затем я делю хорошие совпадения на общее количество ключевых точек для объекта OBJECT (а не сцены), поэтому теперь я заканчиваю 0-100% совпадений.

 int numberOfNearestNeighbors = 1; 

     double maxDistance = .30; 

     BruteForceMatcher<float> matcher = new BruteForceMatcher<float>(DistanceType.L2); 

     matcher.Add(dbDescriptors); 

     var indices = new Matrix<int>(queryDescriptors.Rows, numberOfNearestNeighbors); 
     using (Matrix<float> dist = new Matrix<float>(queryDescriptors.Rows, numberOfNearestNeighbors)) 
     { 
      // null = no mask, use whole image 
      matcher.KnnMatch(queryDescriptors, indices, dist, numberOfNearestNeighbors, null); 

      int matchesUnderMaxDistance = 0; 
      float distance = 0; 

      // filter matches that are too different 
      for (int i = 0; i < indices.Rows; i++) 
      { 
       distance = dist.Data[i, 0]; 

       if (distance < maxDistance) 
       { 
        matchesUnderMaxDistance++; 
       } 
      } 

      return matchesUnderMaxDistance; 
     } 
0

, насколько я могу видеть ваши фильтрации не приводит к 1-к-1 objectdescriptor - scenedescriptor (соответствие через определенный порог), поэтому вы можете получить 100+%

Другое дело, что факт, что «objectDescriptorCount равно sceneDescriptorCount» не всегда означает, что «objectDescriptors равнозначению sceneDescriptors». Проверьте дескрипторы вручную, и если они такие же, что будет означать, что ваша логику обработки где-то не так (если считать «сим»)

надежда, что помогает

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