Подтвердить что ты не робот

Как использовать алгоритм SIFT, чтобы вычислить, насколько похожи два изображения?

Я использовал реализацию SIFT Андреа Ведальди, чтобы вычислить дескрипторы просеивания двух похожих изображений (второе изображение на самом деле является увеличенным изображением одного и того же объекта под другим углом).

Теперь я не могу понять, как сравнить дескрипторы, чтобы сказать, насколько похожи изображения?

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

мало что я сделал для генерации дескрипторов:

>> i=imread('p1.jpg');
>> j=imread('p2.jpg');
>> i=rgb2gray(i);
>> j=rgb2gray(j);
>> [a, b]=sift(i);  % a has the frames and b has the descriptors
>> [c, d]=sift(j);
4b9b3361

Ответ 1

Во-первых, разве вы не должны использовать vl_sift вместо просеивания?

Во-вторых, вы можете использовать сопоставление функций SIFT, чтобы найти соответствия в двух изображениях. Вот пример кода:

    I = imread('p1.jpg');
    J = imread('p2.jpg');

    I = single(rgb2gray(I)); % Conversion to single is recommended
    J = single(rgb2gray(J)); % in the documentation

    [F1 D1] = vl_sift(I);
    [F2 D2] = vl_sift(J);

    % Where 1.5 = ratio between euclidean distance of NN2/NN1
    [matches score] = vl_ubcmatch(D1,D2,1.5); 

    subplot(1,2,1);
    imshow(uint8(I));
    hold on;
    plot(F1(1,matches(1,:)),F1(2,matches(1,:)),'b*');

    subplot(1,2,2);
    imshow(uint8(J));
    hold on;
    plot(F2(1,matches(2,:)),F2(2,matches(2,:)),'r*');

vl_ubcmatch() выполняет, по существу, следующее:

Предположим, что у вас есть точка P в F1, и вы хотите найти "лучший" матч в F2. Один из способов сделать это - сравнить дескриптор P в F1 со всеми дескрипторами в D2. По сравнению, я имею в виду найти евклидово расстояние (или L2-норму разности двух дескрипторов).

Тогда я нахожу две точки в F2, скажем, U и V, которые имеют наименьшее и второе минимальное расстояние (например, Du и Dv) от P соответственно.

Здесь, что рекомендовал Лоу: если Dv/Du >= порог (я использовал 1.5 в примере кода), то это соответствие допустимо; в противном случае он неоднозначно сопоставляется и отклоняется как соответствие, и мы не сопоставляем точку в F2 с P. По существу, если есть большая разница между лучшим и вторым лучшим совпадением, вы можете ожидать, что это будет соответствовать качеству.

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

Вы можете выполнить сопоставление любым количеством способов. Вы можете сделать это очень легко с помощью MATLAB, или вы можете ускорить его, используя KD-дерево или приблизительный поиск ближайшего номера, например FLANN, который был реализован в OpenCV.

EDIT: Кроме того, существует несколько kd-tree-реализаций в MATLAB.

Ответ 2

Вы должны прочитать Дэвид Лоу paper, в котором говорится о том, как это сделать. Этого должно быть достаточно, если вы хотите сравнить изображения одного и того же объекта. Если вы хотите совместить изображения разных объектов той же категории (например, автомобили или самолеты), вы можете захотеть посмотреть на Пирамидное ядро ​​матча от Grauman и Даррелл.

Ответ 3

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

Ответ 4

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

Если вы хотите сравнить дескриптор SIFT, рядом с эвклидовым расстоянием вы также можете использовать "диффузное расстояние" - получение дескриптора по прогрессивно более грубым масштабам и объединение их с оригинальным дескриптором. Таким образом, сходство с "крупным масштабом" будет иметь больший вес.

Ответ 5

Если вы хотите выполнить сопоставление между изображениями, вы должны использовать vl_ubcmatch (в случае, если вы его не использовали). Вы можете интерпретировать выходные "оценки", чтобы увидеть, насколько близки функции. Это представляет собой квадрат евклидова расстояния между двумя дескрипторами дескриптора. Вы также можете изменить пороговое значение между наилучшим совпадением и вторым лучшим совпадением в качестве входных данных.

Ответ 6

Я получаю наилучшие совпадения, используя методы дерева RANSAC и KD в Python, мой вопрос заключается в том, как извлечь сдвиг между двумя заданными изображениями.

def main(): ap = argparse.ArgumentParser()

#construct the argument parser and parse the argument
ap.add_argument("-s", "--src", required=True, help="Path for the source fits file")
ap.add_argument("-t", "--template", required=True, help="Path for the second fits file")
args = vars(ap.parse_args())

MIN_MATCH_COUNT = 10

path1 = "..//exposures//"+args["src"]
path2 = "..//exposures//"+args["template"]

data_1 = (fits.open(path1)[1]).data
data_2 = (fits.open(path2)[1]).data

# convert 32 bits fits file to 8 bits
img1 = fits2images(data_1)
img2 = fits2images(data_2)

# Initiate SIFT detector
sift = cv2.xfeatures2d.SIFT_create()

# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks = 50)

flann = cv2.FlannBasedMatcher(index_params, search_params)

matches = flann.knnMatch(des1,des2,k=2)
print('numbers of matchs :',len(matches))
# store all the good matches as per Lowe ratio test.
good_matches = []
for m,n in matches:
    if m.distance < 0.7*n.distance:
        good_matches.append(m)

print('numbers of good matchs :',len(good_matches))

x1_points = good_matches[2:3]
y1_points = good_matches[3:2]
print(x1_points)
print(y1_points)    

if name == ' main ': main()