Я пытаюсь создать карту глубины в реальном времени из некалиброванной стереокамеры. Я знаю, как примерно должен выглядеть алгоритм:
- обнаружение ключевых точек (SURF, SIFT)
- извлечение дескрипторов (SURF, SIFT)
- сравнивать и сопоставлять дескрипторы (подходы BruteForce, Flann)
- найти фундаментальный мат (findFundamentalMat ()) из этих пар
- stereoRectifyUncalibrated ()
- 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)
С помощью этого куска кода я генерирую такой вывод: Видео
Теперь вы, наверное, видите мои проблемы:
- Моя карта глубины мерцает и не является (как я ее называю) "согласованной по цвету"
- Качество карты глубины очень плохое (нечеткое)
- Это слишком медленно и поэтому не может использоваться в режиме реального времени
Для первой проблемы мне нужно хорошее решение, чтобы избавиться от этого мерцания. Есть ли способ принять предыдущую карту глубины к ответственности?
Что касается второй проблемы, я, вероятно, имею представление о том, что мне следует делать: мне нужно исправить свои стереоизображения (как предлагает описание алгоритма). Чтобы исправить эти изображения, мне нужно будет использовать SIFT или SURF. Но я читал, что SIFT и SURF слишком медленные, чтобы работать в режиме реального времени, поэтому мне, вероятно, нужно какое-то другое решение?
Прежде чем попытаться оптимизировать программу, я сосредоточусь на первой и второй проблемах, поэтому вы можете пока игнорировать мою третью проблему (пока).
Спасибо за помощь:)