Создание карты несоответствия субпиксельной точности в OpenCV

Цель состоит в том, чтобы создать карту диспаратности для откалиброванных стереоизображений.

3D-модель проецируется на пару калиброванных стереоизображений (слева / справа) с помощью функции OpenCV cv :: projectPoints (). Cv :: projectPoints () дает точки по координате 2D-изображения в cv :: Point2f, что является субпиксельной точностью.

Поскольку некоторые 3D-точки проецируются на одну и ту же область пикселей, я сохраняю только точку с меньшей глубиной / Z из-за того, что дальнейшие точки перекрываются более близкой точкой.

Таким образом я могу получить два индексных изображения для левого и правого изображения соответственно. Каждый пиксель индексного изображения относится к его положению в 3D-модели (хранящейся в std :: vector) или в 2D (std :: vector).

Следующий фрагмент должен кратко объяснить процедуры:

std::vector<cv::Point3f> model_3D;
std::vector<cv::point2f> projectedPointsL, projectedPointsR;
cv::projectPoints(model_3D, rvec, tvec, P1.colRange(0,3), cv::noArray(), projectedPointsL);
cv::projectPoints(model_3D, rvec, tvec, P2.colRange(0,3), cv::noArray(), projectedPointsR);


// Each pixel in indexImage is a index pointing to a position in the vector of projected points 
cv::Mat indexImageL, indexImageR;
// This function filter projected points and return the index image
filterProjectedPoints(projectedPointsL, model_3D, indexImageL);
filterProjectedPoints(projectedPointsR, model_3D, indexImageR);

Чтобы создать карту несоответствия, я могу:

1. Для каждого пикселя в карте диспаратности найдите соответствующую позицию пикселя в левом / правом индексных изображениях и вычтите их положение. Таким образом достигается целочисленная диспаратность (не субпиксельная точность);

2. Для каждого пикселя на карте диспаратности найдите его положение в 2D (с плавающей точностью) в обеих точках левой и правой проекций и вычислите разницу по оси x как диспаратность. Таким образом обеспечивается несоответствие в точности субпикселей.

Первый способ прост и приводит к ошибке из-за игнорирования точек проецирования субпикселей. Однако второй способ также вносит ошибку, поскольку пара проецируемых пикселей (из одних и тех же трехмерных точек) может проецироваться в разные места в пределах пикселя. Например, проецируемая точка на левом изображении - (115,289, 80,393), на правом изображении - (145,686, 79,883). Его положение на карте диспаратности будет (115, 80), а диспаратность может быть: 145,686 - 115,289 = 30,397. Как видите, они могут быть не точно выровнены по строкам, чтобы иметь одинаковую координату y.

Вопросы следующие: 1. Правильны ли оба способа (кроме внесения ошибки)? 2. Если 2-й способ верен, если ошибка игнорируется при вычислении несоответствия точности субпикселей.

Ну, вы также можете сказать мне, как бы вы рассчитали карту субпиксельного несоответствия в этом сценарии.


person linzhang.robot    schedule 14.09.2014    source источник
comment
почему бы не взглянуть на код и документацию для создания карт несоответствия, которые уже доступны в OpenCV? BlockMatching или StereoSGBM.   -  person Unapiedra    schedule 15.09.2014
comment
@Unapiedra, я думал об этом и пробовал читать код. Однако для меня это было немного непонятно, так как есть операции с памятью и отсутствие комментариев. Я прочитаю это еще раз и посмотрю, смогу ли я понять, спасибо.   -  person linzhang.robot    schedule 15.09.2014
comment
@Unapiedra Кроме того, OpenCV BM и SGBM пытаются найти несоответствие для каждого пикселя, что минимизирует стоимость, тогда как здесь у меня уже есть соответствие и я хочу вычислить несоответствие.   -  person linzhang.robot    schedule 15.09.2014
comment
Зачем вам нужна карта несоответствия, если вы уже знаете трехмерное положение объекта? И почему вы не можете найти его аналитически, то есть на бумаге?   -  person Unapiedra    schedule 16.09.2014
comment
@Unapiedra Мне нужно сгенерировать карту несоответствия истинности для целей оценки стерео алгоритма   -  person linzhang.robot    schedule 16.09.2014
comment
Я не могу сейчас ответить, но я бы сделал это аналитически. Не стесняйтесь задавать вопрос комментарием через неделю.   -  person Unapiedra    schedule 16.09.2014


Ответы (1)


В паре выпрямленных изображений диспаратность равна просто d=f*b/(z+f), где f - фокусное расстояние, b - базовая линия между двумя камерами, а z - расстояние до объекта, перпендикулярное плоскостям изображения. Это предполагает базовую модель камеры с отверстиями для штифта.

Приближая z >> f, получается d = f * b / z, то есть обратная природа d и z.

Таким образом, вы можете просто рассчитать карту несоответствия аналитически.

person Unapiedra    schedule 27.09.2014