Tl; dr;
Я хочу использовать bf.matcher
, без использования sift, surf или любого из этих методов. У меня просто есть два набора точек (разной длины), которые я бы хотел сопоставить.
Есть идеи, как это сделать?
Здравствуйте,
У меня естьполучил фотографию, на которой я обнаружил приблизительные центры некоторых отдельных объектов (с помощью специального метода). Я не обнаруживаю их всех, и есть несколько выбросов.
Я знаю положение этих объектов в реальном мире.
Теперь я бы хотел сопоставить эти приблизительные позиции с реальными позициями . Конечная цель состоит в том, чтобы установить реальную систему координат (в метрах) в моем изображении (в пикселях).
Полагаю, я просто хочу найти гомографию между моими двумя наборами, верно?
# Let's say for example that my set of image coordinates is:
Xim = [735, 760, 610, 462]
Yim = [-685, -631, -485, -319]
# And that they have to be matched with:
Xreal = [0.75, 0.875, 0.125, -0.625, -0.125, 0.25]
Yreal = [1.625, 1.875, 2.625, 3.5, 4.25, 4.75]
Если я хочу использовать функцию opencv cv2.findHomography
, мне нужно иметь одинаковое количество очков в двух наборах. Поэтому я собирался протестировать каждую возможную комбинацию точек (6 choose 4 = 15 here
), вычислить их матрицы гомографии и выбрать ту, которая имеет наименьшее искажение.
import itertools
import numpy as np
import cv2
# I need 4 points in both sets, so I'm trying all combinations:
Xreal_test=[]; Yreal_test = []
combin = itertools.combinations(np.arange(len(Xreal)),len(Xim))
for k,c in enumerate(combin):
Xreal_test = Xreal_test + [[Xreal[list(c)[i]] for i in range(len(list(c)))]]
Yreal_test = Yreal_test + [[Yreal[list(c)[i]] for i in range(len(list(c)))]]
# Formatting the sets that way cv2.findHomography wants them, and calculate homography
H=[]
pts_xim = np.array([[Xim[x],Yim[x]] for x in range(len(Xim))])
for i in range(len(Xreal_test)):
pts_xreal = np.array([[Xreal_test[i][x],Yreal_test[i][x]] for x in range(len(Xim))])
# Calculate homography
h, _ = cv2.findHomography(pts_xreal, pts_xim, cv2.RANSAC)
H = H + [h]
И это все!
Но, конечно,У меня гораздо больше, чем эти баллы, и попытка всех комбинаций будет чрезвычайно ресурсоемкой (если не глупой).
Поэтому вместо вычисления гомографии для всех возможных комбинаций, я 'Я хотел бы использовать что-то чуть менее "грубое", например, с bf.Matcher()
.
Вот где я сейчас нахожусь. Я знаю, как сделать это с изображениями, но не с набором точек (что должно быть проще). Поиск гомографий по изображениям можно выполнить следующим образом:
img1 = cv2.imread('box.png',0)
img2 = cv2.imread('box_in_scene.png',0)
surf = cv2.xfeatures2d.SURF_create()
kp1, des1 = surf.detectAndCompute(img1,None)
kp2, des2 = surf.detectAndCompute(img2,None)
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1,des2, k=2)
good = []
for m,n in matches:
if m.distance < 0.7*n.distance:
good.append(m)
src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2)
dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2)
h, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0)
kp, des = surf.detectAndCompute(img,None)
дает два выхода, keypoints
и descriptors
. Мне не нужно использовать surf (или sift, orb) для моей задачи, однако мне нужно передать bf.matcher дескриптором. Есть идеи, как это сделать с помощью набора предопределенных точек?
Заранее спасибо!