как применить преобразование Делоне после сопоставления с SIFT

#python #image-processing

Вопрос:

У меня есть два спутниковых снимка (полосы 02), я хочу выровнять их на основе преобразования Делоне. цель состоит в том, чтобы получить изображение RGB высокого качества.

Примечание: этот код успешно выполнен функцией CV2.perspectiveTransform, но мне нужно другое преобразование для большей точности.

 def matching(ms, i1, i2):
  from scipy.spatial import Delaunay
  from scipy.interpolate import LinearNDInterpolator

  ms = cv2.imread(ms, 1)
  img1 = cv2.imread(i1, 0)  # queryImage

  img2 = cv2.imread(i2, 0)  # trainImage
  # image8bit = cv2.normalize(
  # img2, None, 0, 255, cv2.NORM_MINMAX).astype('uint8')

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

  # find the keypoints and descriptors with SIFT
  # Here img1 and img2 are grayscale images
  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)
  # do the matching

  flann = cv2.FlannBasedMatcher(index_params, search_params)

  matches = flann.knnMatch(des1, des2, k=2)
  filtered = list(
    filter(lambda x: x[0].distance < 0.7*x[1].distance, matches))
  good = list(map(lambda x: x[0], filtered))

  draw_params = dict(matchColor=(0, 255, 0),
                   singlePointColor=None,
                   flags=2)

  result = cv2.drawMatches(img1, kp1, img2, kp2,
                         good, None, **draw_params)
  plt.imshow(result), plt.show()

  # extract coordinated for query and train image points
  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)

  # here im1 is the original RGB (or BGR because of cv2) image
  h, w, b = ms.shape
  pts = np.float32([[0, 0], [0, h-1], [w-1, h-1], [w-1, 0]]
                 ).reshape(-1, 1, 2)


  tri = Delaunay(src_pts) # Compute the triangulation

  # Perform the interpolation with the given values:
  interpolator = LinearNDInterpolator(tri, src_pts)
  values_mesh2 = interpolator(dst_pts)

  # for now I only displayed it using polylines, depending on what you need you can use these points to do something else
  # I overwrite the original RGB (or BGR) image with a red rectangle where the smaller image should be
  im2 = cv2.polylines(img2, [np.int32(values_mesh2)], True,
                    (0, 0, 255), 10, cv2.LINE_AA)
  cv2.imwrite('overlap3.tif', im2)

if __name__ == "__main__":


  matching('ms.png', 'b1.png', 'b3.png')
 

Это приведет к ошибке:

 tri = Delaunay(src_pts)  # Compute the triangulation
File "qhull.pyx", line 1840, in scipy.spatial.qhull.Delaunay.__init__
File "qhull.pyx", line 259, in scipy.spatial.qhull._Qhull.__init__
ValueError: Buffer has wrong number of dimensions (expected 2, got 3)
 

Как исправить эту ошибку ??

Ответ №1:

Я решил эту ошибку, изменив ФОРМУ:

  src_pts = np.float32(
    [kp1[m.queryIdx].pt for m in good]).reshape(-1, 2)
 dst_pts = np.float32(
    [kp2[m.trainIdx].pt for m in good]).reshape(-1, 2)
 

наконец, это работает, но не дает ожидаемого результата.
Спасибо всем.