Как добиться согласованной по цвету не мерцающей карты глубины в реальном времени? - PullRequest
0 голосов
/ 05 июня 2019

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

  1. обнаружение ключевых точек (SURF, SIFT)
  2. извлечение дескрипторов (SURF, SIFT)
  3. сравнивать и сопоставлять дескрипторы (подходы BruteForce, Flann)
  4. найти фундаментальный мат (findFundamentalMat ()) из этих пар
  5. stereoRectifyUncalibrated ()
  6. StereoSGBM

Я нашел этот алгоритм здесь: 3D реконструкция из 2 изображений без информации о камере

Я также нашел похожую реализацию: Проект реконструкции Github 3d

И этот урок: Восстановление стерео 3D с OpenCV с использованием камеры iPhone.

С помощью этих трех источников я собрал тестовую реализацию:

    # I size down the original frames
    IMG_L = cv2.resize(IMG_L,(int(WINDOW_WIDTH/3),int(WINDOW_HEIGHT/3)))
    IMG_R = cv2.resize(IMG_R,(int(WINDOW_WIDTH/3),int(WINDOW_HEIGHT/3)))

    window_size = 15
    left_matcher = cv2.StereoSGBM_create(
        minDisparity=0,
        numDisparities=16,
        blockSize=11,
        P1=8 * 3 * window_size ** 2,
        P2=32 * 3 * window_size ** 2,
        disp12MaxDiff=1,
        uniquenessRatio=3,
        speckleWindowSize=1,
        speckleRange=1,
        preFilterCap=63,
        mode=cv2.STEREO_SGBM_MODE_SGBM_3WAY
    )

    right_matcher = cv2.ximgproc.createRightMatcher(left_matcher)

    lmbda = 80000
    sigma = 1.2
    visual_multiplier = 1.0

    wls_filter = cv2.ximgproc.createDisparityWLSFilter(matcher_left=left_matcher)
    wls_filter.setLambda(lmbda)
    wls_filter.setSigmaColor(sigma)

    displ = left_matcher.compute(IMG_L, IMG_R)
    dispr = right_matcher.compute(IMG_R, IMG_L)
    displ = np.int16(displ)
    dispr = np.int16(dispr)
    filteredImg = wls_filter.filter(displ, IMG_L, None, dispr)  # important to put "imgL" here!!!

    filteredImg = cv2.normalize(src=filteredImg, dst=filteredImg, beta=0, alpha=255, norm_type=cv2.NORM_MINMAX);
    filteredImg = np.uint8(filteredImg)

С помощью этого куска кода я генерирую такой вывод: Видео

Теперь вы, наверное, видите мои проблемы:

  1. Моя карта глубины мерцает и не является (как я ее называю) "согласованной по цвету"
  2. Качество карты глубины очень плохое (нечеткое)
  3. Это слишком медленно и поэтому не может использоваться в режиме реального времени

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

Что касается второй проблемы, я, вероятно, имею представление о том, что мне следует делать: мне нужно исправить свои стереоизображения (как предлагает описание алгоритма). Чтобы исправить эти изображения, мне нужно будет использовать SIFT или SURF. Но я читал, что SIFT и SURF слишком медленные, чтобы работать в режиме реального времени, поэтому мне, вероятно, нужно какое-то другое решение?

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

Спасибо за помощь:)

...