совпадение для findHomography из списка точек (различной длины), а не изображения - PullRequest
0 голосов
/ 10 октября 2019

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 дескриптором. Есть идеи, как это сделать с помощью набора предопределенных точек?

Заранее спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...