Соответствие двухмерного набора точек - PullRequest
2 голосов
/ 08 декабря 2011

Каков наилучший способ сопоставления наборов точек сканирования (снятых фотографий) с набором точек шаблона (синие, зеленые, красные, розовые круги на изображениях)?Я использую opencv / c ++.Может быть, какой-то алгоритм ICP?Я хочу обернуть отсканированное изображение в шаблонное изображение!

набор точек шаблона: template image

набор точек сканирования: scan image

Ответы [ 4 ]

1 голос
/ 09 декабря 2011

Вы должны соответствовать красным прямоугольникам?Исходное изображение содержит четыре черных прямоугольника в углах, которые кажутся сделанными для соответствия.Я могу надежно найти их с помощью 4 строк кода Mathematica:

lotto = [source image]
lottoBW = Image[Map[Max, ImageData[lotto], {2}]]

Это занимает максимум (R, G, B) для каждого пикселя, то есть отфильтровывает красно-желтую печать (более или менее).Результат выглядит следующим образом:

bw filter result

Затем я просто использую фильтр LoG, чтобы найти темные пятна и искать локальные максимумы в результирующем изображении

lottoBWG = ImageAdjust[LaplacianGaussianFilter[lottoBW, 20]]
MaxDetect[lottoBWG, 0.5]

Результат: enter image description here

1 голос
/ 08 декабря 2011

Если объект достаточно жесткий и выровненный, простая автокорреляция поможет.Если нет, я бы использовал RANSAC , чтобы оценить трансформацию между объектом и шаблоном (кажется, что у вас есть характерные точки).Пожалуйста, предоставьте некоторые детали по проблеме.

Редактировать: RANSAC (случайный выборочный консенсус) может быть использован в вашем случае.Думайте о ненужных точках в вашем шаблоне как о шуме (ложные функции, обнаруженные детектором функций) - они являются контурами.RANSAC может обрабатывать планировщики, потому что он выбирает небольшое подмножество характерных точек (минимальное количество, которое может инициировать вашу модель) случайным образом, запускает модель и вычисляет, насколько ваша модель соответствует заданным данным (сколько других точек в шаблоне соответствуют вашимдругие моменты).Если вы выберете неправильное подмножество, это значение будет низким, и вы отбросите модель.Если вы выберете правильное подмножество, оно будет высоким, и вы сможете улучшить соответствие с помощью алгоритма LMS.

0 голосов
/ 07 августа 2013

Выполните следующие действия:

  1. Совпадение точек или объектов на двух изображениях, это определит вашу упаковку;
  2. Определите, какую трансформацию вы ищете для своей упаковки. Самым общим будет гомография (см. Cv :: findHomography ()), а менее общим будет простой перевод (используйте cv :: matchTempalte ()). Промежуточным случаем будет перемещение по x, y и поворот. Для этого я написал быструю функцию, которая лучше, чем «Гомография», поскольку она использует меньше степеней свободы, в то же время оптимизируя правильные метрики (квадратные различия в координатах): https://stackoverflow.com/a/18091472/457687
  3. Если вы считаете, что в ваших матчах много выбросов, используйте RANSAC в верхней части вашего шага 1. В основном вам нужно случайным образом выбрать минимальный набор точек, необходимых для поиска параметров, решить, определить значения, снова решить, используя все значения и затем повторите итерацию, пытаясь улучшить текущее решение (увеличить число ошибок, уменьшить ошибку или и то, и другое). См. Википедию для алгоритма RANSAC: http://en.wikipedia.org/wiki/Ransac
0 голосов
/ 09 декабря 2011

Вы смотрели на образец дескриптора_extractor_matcher.cpp OpenCV? В этом примере RANSAC используется для определения гомографии между двумя входными изображениями. Я полагаю, когда вы говорите обернуть, вы на самом деле имеете в виду деформацию? Если вы хотите деформировать изображение с помощью матрицы гомографии, которую вы обнаружили, обратите внимание на функцию warpPerspective . Наконец, здесь - это несколько хороших руководств, использующих различные детекторы функций в OpenCV.

РЕДАКТИРОВАТЬ: Возможно, у вас нет функций SURF, но у вас наверняка есть особенности с разными классами. Сопоставление на основе признаков обычно делится на две фазы: обнаружение признаков (которое вы уже сделали) и извлечение, которое необходимо для сопоставления. Таким образом, вы можете попытаться преобразовать свои функции в KeyPoint , а затем выполнить извлечение и сопоставление функций. Вот небольшой фрагмент кода о том, как вы можете это сделать:

typedef int RED_TYPE = 1;
typedef int GREEN_TYPE = 2;
typedef int BLUE_TYPE = 3;
typedef int PURPLE_TYPE = 4;

struct BenFeature
{
    Point2f pt;
    int classId;
};

vector<BenFeature> benFeatures;

// Detect the features as you normally would in addition setting the class ID

vector<KeyPoint> keypoints;
for(int i = 0; i < benFeatures.size(); i++)
{
    BenFeature bf = benFeatures[i];
    KeyPoint kp(bf.pt,
                10.0, // feature neighborhood diameter (you'll probaby need to tune it)
                -1.0,  // (angle) -1 == not applicable
                500.0, // feature response strength (set to the same unless you have a metric describing strength)
                1, // octave level, (ditto as above)
                bf.classId // RED, GREEN, BLUE, or PURPLE.
                );
    keypoints.push_back(kp);
}

// now proceed with extraction and matching...

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

...