3D-реконструкция только из двух 2D-изображений с камерой iPhone 7

Основная проблема:

Восстановите объект только по 2 изображениям (по крайней мере, что можно воспринять по 2 изображениям).

О камере:

Я использую камеру iPhone 7 и делаю свои собственные снимки, что означает, что я могу откалибровать свою камеру. Я могу получить фокусное расстояние (4 мм) и ширину сенсора (3,99 мм) по адресу: https://www.anandtech.com/show/10685/the-iphone-7-and-iphone-7-plus.-review/6. Я также знаю, что могу получить свое фокусное расстояние в пикселях из этих известных значений и моих c_x и c_y из ширины и высоты. Я не уверен, что калибровка правильная.

Мой текущий подход:

Я использую очень похожий подход, который использовался в этом сообщении: 3D-реконструкция из 2 изображений с базовой линией и калибровкой одной камеры

Алгоритм:

criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03)

feature_params = dict( maxCorners = 100, qualityLevel = 0.3, minDistance = 7, blockSize = 7 )

lk_params = dict( winSize = (15,15),maxLevel = 20, criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))

  • Обнаружение углов на левом изображении с помощью enter code hereвведите код здесь cv2.goodFeaturesToTrack(gray,mask = None, **feature_params)
  • Уточните углы, найденные с помощью corners1= cv2.cornerSubPix(gray,corners1,(11,11),(-1,-1),criteria)
  • Найдите углы на правом изображении с помощью оптического потока corners_r, st, err = cv2.calcOpticalFlowPyrLK(gray, r_gray, corners1, None, **lk_params)
  • Оставьте только хорошие моменты good_left = corners1[st==1] и good_right = corners_r[st==1] (Функции соответствуют изображениям)
  • Найдите фундаментальную матрицу из выбранных точек F, mask = cv2.findFundamentalMat(good_left,good_right,cv2.FM_RANSAC)
  • Рассчитать H1, H2 для исправления изображений с помощью _,H1,H2=cv2.stereoRectifyUncalibrated(good_left, good_right, F, right.shape[:2], threshold=5.0)
  • Исправьте изображения new_left = cv2.warpPerspective(img5,H1,img5.shape[:2],cv2.INTER_LINEAR or cv2.INTER_NEAREST) new_right= cv2.warpPerspective(img3,H2,img3.shape[:2],cv2.INTER_LINEAR or cv2.INTER_NEAREST) (изображения, изображенные ниже рис. 1)
  • Рассчитайте карту несоответствий, используя sgbm в opencv.
  • Реконструировать 3D-объект с помощью reprojectImageTo3D

Проблемы:

  • В настоящее время изображения не искажаются, так как использование моей матрицы камеры array([[ 3.25203085e+03, 0.00000000e+00, 1.54093581e+03], [ 0.00000000e+00, 3.26746422e+03, 1.91792736e+03], [ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]) и dist_coeffs array([[ 0.16860882, -1.25881837, -0.01130431, -0.01046869, 2.09480747]]) искажает мои изображения. Рассчитали эти значения, используя 46 изображений шахматной доски под разными углами и перспективами.
  • Использование warpPerspective с H1 и H2 для соответствующих изображений немного сдвигает изображение. Посмотрите здесь обрезанные изображения (рис. 1).

Вопросы:

  • Я получил total error: 0.457120388 (я думаю, неплохо) для калибровки камеры, следуя инструкциям здесь: >https://docs.opencv.org/3.1.0/dc/dbb/tutorial_py_dication.html Это хорошая ошибка?
  • Является ли стрижка на моих изображениях такой, какой она должна быть на самом деле? Я думаю, что это дополнительное смещение возникает из-за сопоставления функций с использованием оптического потока, и, возможно, есть пара функций, которые на самом деле не совпадают. Каковы хорошие способы их фильтрации еще больше, чтобы быть более точным? Я слышал, что также могу использовать алгоритм Чжана для исправления этого сдвига, но не уверен, как бы я его применил. Это должно работать и для других изображений, а это означает, что я хочу иметь более надежный подход не только к этим двум изображениям, если это возможно.

Извините, если было не так точно, пожалуйста, дайте мне знать, если вам нужна дополнительная информация. Я также некоторое время искал ответы, поэтому я задаю этот вопрос только потому, что мне пока некуда обратиться.

Любая помощь очень ценится заранее. Спасибо вам, ребята!


person maxmine11    schedule 15.01.2018    source источник
comment
Здравствуйте, maxmine11.. много усилий приложено к вашему вопросу. Но... завершите тур и отредактируйте свой вопрос таким образом, чтобы мы видели код, ошибки и воспроизводили его, тестируя. Оттуда мы можем помочь и попытаться решить проблему под рукой с вами. Подсказка для вашего алгоритма: см. для этого Как создать минимальный, полный и проверяемый пример. Наслаждайтесь ТАК ;-)   -  person ZF007    schedule 16.01.2018
comment
Привет @ ZF007, спасибо за совет. Я внес некоторые изменения в свой вопрос, чтобы сделать его более понятным. Кроме того, ошибки, которые я получаю, связаны с процедурой, которую я использую (скорее всего, неправильно), а не с фактическим кодом, поэтому я пытался сосредоточиться на передаче этого, но я открыт для дополнительной критики, как я хочу улучшить себя :) Еще раз спасибо!   -  person maxmine11    schedule 16.01.2018
comment
То, что вы пытаетесь сделать, довольно сложно. Шаг 1 всегда заключается в правильной калибровке, к которой вы, похоже, уже на пути. Мне также повезло с апрельской калибровкой, которую иногда проще использовать, чем калибровку OpenCV. april.eecs.umich.edu/wiki/Camera_suite. Вторая часть — определить, действительно ли вам нужно сделать только два изображения и ничего больше. Можете ли вы получить другие данные, которые могли бы сказать вам, как перемещалась камера? Без других данных масштабный коэффициент будет затруднен. Например, как вы можете сказать разницу между объектом и крошечной фотографией объекта?   -  person abarry    schedule 22.02.2021


Ответы (1)


Несколько моментов:

  1. Ваша калибровка RMSE кажется немного завышенной для удобства. Вы должны стремиться к 0,1 пикселя. Я предлагаю построить остаточные векторы изображение за изображением и посмотреть, есть ли у вас выбросы. См. также дополнительные рекомендации в этом ответе.
  2. Коэффициенты искажения обычно не публикуются. Вам нужно откалибровать, чтобы получить их.
  3. Сдвиг, который вы наблюдаете, происходит из-за выпрямления. Вы можете визуально проверить эпиполярную ошибку без исправления — выберите пиксель x на одном изображении, нарисуйте соответствующую эпиполярную линию на другом изображении и посмотрите, подходит ли она для пикселя x, совпадающего с x. Повторите несколько х.
  4. Визуальная проверка исправленных изображений заключается в том, выровнены ли соответствующие строки двух изображений.
person Francesco Callari    schedule 16.01.2018
comment
Привет, @FrancescoCallari, спасибо за совет по калибровке, я попробую! Что касается сдвига, я понимаю, что сопряженные эпиполярные линии должны совпадать друг с другом, но мне было интересно, есть ли более общее исправление для этого сдвига из-за выпрямления вместо проверки того, что каждая точка лежит на соответствующей эпиполярной линии? Не знаю, будет ли это эффективно, если мне это нужно каждый раз, когда я делаю два снимка объекта. Еще раз спасибо, что нашли время, чтобы помочь мне! - person maxmine11; 16.01.2018