Объясните этот алгоритм (сравните точки в алгоритме SURF)

Мне нужно знать, известен ли этот алгоритм:

void getMatches(IpVec &ipts1, IpVec &ipts2, IpPairVec &matches, float ratio) {
    float dist, d1, d2;
    Ipoint *match;

    matches.clear();

    for (unsigned int i = 0; i < ipts1.size(); i++) {
        d1 = d2 = FLT_MAX;

        for (unsigned int j = 0; j < ipts2.size(); j++) {
            dist = ipts1[i] - ipts2[j];

            if (dist < d1) // if this feature matches better than current best
            {
                d2 = d1;
                d1 = dist;
                match = &ipts2[j];
            } else if (dist < d2) // this feature matches better than second best
            {
                d2 = dist;
            }
        }

        // If match has a d1:d2 ratio < 0.65 ipoints are a match
        if (d1 / d2 < ratio) {
            // Store the change in position
            ipts1[i].dx = match->x - ipts1[i].x;
            ipts1[i].dy = match->y - ipts1[i].y;
            matches.push_back(std::make_pair(ipts1[i], *match));
        }
    }
}

class Ipoint {
public:

    //! Destructor

    ~Ipoint() {
    };

    //! Constructor

    Ipoint() : orientation(0) {
    };

    //! Gets the distance in descriptor space between Ipoints

    float operator-(const Ipoint &rhs) {
        float sum = 0.f;
        for (int i = 0; i < 64; ++i) {
            //std::cout << i << "\n";
            try {
                sum += (this->descriptor[i] - rhs.descriptor[i])*(this->descriptor[i] - rhs.descriptor[i]);
            } catch (char *str) {
                std::cout << "Caught some other exception: " << str << "\n";
            }

        }
        return sqrt(sum);
    };

    //! Coordinates of the detected interest point
    float x, y;

    //! Detected scale
    float scale;

    //! Orientation measured anti-clockwise from +ve x-axis
    float orientation;

    //! Sign of laplacian for fast matching purposes
    int laplacian;

    //! Vector of descriptor components
    float descriptor[64];

    //! Placeholds for point motion (can be used for frame to frame motion analysis)
    float dx, dy;

    //! Used to store cluster index
    int clusterIndex;
};

Это сравнивает результаты алгоритма SURF.

  1. Это алгоритм ближайшего соседа? Похоже, что функция ищет ближайшую точку каждой точки.
  2. Могу ли я сделать то же самое, используя Quadtree или kd-tree?
  3. Есть лучший алгоритм для сравнения точек изображений и определения, одинаковы ли они или похожи?
  4. Предпочтительно я хочу сохранить их в mysql и построить kd-дерево для сравнения 1 изображения со всеми изображениями, это возможно?
  5. RANSAC полезен для чего-нибудь в этой задаче?
  6. Есть какой-нибудь способ поймать ложные срабатывания?

person Wiliam    schedule 05.08.2011    source источник
comment
Я проголосовал за ваш последний комментарий, нет нужды и времени отвечать.   -  person Wiliam    schedule 06.08.2011
comment
stackoverflow.com/questions/5962131/ нуждается в продолжении от вас.   -  person Lightness Races in Orbit    schedule 06.08.2011


Ответы (2)


Вы задали много вопросов, и я не думаю, что смогу ответить на все из них, но вот ответы на большинство ваших вопросов, которые я могу.

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

  2. Вы могли сделать это с помощью дерева квадрантов или kd-дерева, но, поскольку все ваши точки являются одномерными значениями, вы могли бы сделать гораздо лучше, используя сбалансированное двоичное дерево поиска. Для такого дерева, если вы пропустите связанный список через узлы, вы можете найти k ближайших соседей к некоторой контрольной точке p, отыскав ближайший элемент p в двоичном дереве поиска, а затем пройдя (k + 1) шагов в каждом направление и взятие k ближайших точек того, что вы найдете. Это выполняется за время O(lg n + k), где n — количество точек, а k такое же, как указано выше. Это значительно более эффективно, чем то, что у вас есть сейчас, что требует O(n) времени на поиск.

    Если размерность вашего вектора признаков больше 1, но меньше 20, то использование kd-деревьев будет очень эффективной мерой.

    Для более высоких размерностей вы можете либо уменьшить количество измерений с помощью PCA перед применением kd-дерева, либо использовать более масштабируемую структуру ANN, такую ​​как хеширование с учетом местоположения.

  3. SURF лучше всего подходит для обнаружения сцен и объектов. Если вам нужно выяснить, являются ли два изображения одинаковыми, вам лучше использовать алгоритмы глобальных дескрипторов, такие как GIST. Преимущество использования глобального дескриптора заключается в том, что вы получаете единый вектор для всего изображения, а сравнение изображений выполняется с помощью простого евклидова расстояния.

  4. Вы определенно можете сделать это с помощью MySQL, потому что вам не нужно kd-дерево. Достаточно простого сбалансированного бинарного дерева.

  5. RANSAC — это метод оценки параметров модели, устойчивый к выбросам. Это полезно для использования функций SURF для объединения нескольких фотографий в 3D-сцену.

  6. Проверка на ложные срабатывания, безусловно, является упражнением по машинному обучению, и я не очень хорошо разбираюсь в этой области. Вы, вероятно, могли бы сделать это с помощью алгоритма обучения с учителем (например, SVM, усиленного дерева решений или нейронной сети), но я недостаточно знаю, чтобы дать вам совет.

Надеюсь это поможет!

person templatetypedef    schedule 05.08.2011
comment
извините, я забыл показать вам класс точек, я думаю, что мне нужны размеры 64/128, поэтому, возможно, для 1 миллиона изображений мне понадобится рандомизированное kd-дерево. Я читал о GIST, теперь я использую SURF, и у меня есть локальные функции, концепция глобальных функций для меня новая, я поищу дополнительную информацию. О MySQL: если я использую kd-tree, мне придется сначала построить дерево. Спасибо. - person Wiliam; 05.08.2011
comment
@Wiliam: kd-деревья работают лучше всего, когда количество измерений меньше 20. Для вашей проблемы вы можете либо сначала уменьшить размерность, используя что-то вроде PCA, либо использовать более масштабируемую структуру ANN, такую ​​​​как хеширование с учетом местоположения. - person Don Reba; 05.08.2011
comment
@templatetypedef, uf, я не знаю, лучшее ли это решение. Я читал в некоторых статьях, что они используют рандомизированное kd-дерево для хранения функций, но я не знаю более подробной информации... - person Wiliam; 05.08.2011

Я просто отвечу 5, так как templatetypedef касается остальных. RANSAC — это метод оценки параметров (вроде поиска линии, наиболее подходящей для набора точек данных). Так что это не очень полезно при поиске ближайших соседей.

person Michael Anderson    schedule 05.08.2011
comment
Спасибо, я прочитал в Интернете, что используется для соединения изображений. - person Wiliam; 05.08.2011