Предыстория:
В настоящее время я работаю над проектом стереозрения с использованием OpenCV. Я пытаюсь создать карту несоответствия из набора двух исправленных изображений, но не получаю ожидаемого результата. При просмотре исправленных изображений между изображениями наблюдается заметный вертикальный сдвиг , которого не должно быть после исправления. Я' м сейчас ищу, в чем может быть ошибка. Мой код основан на стереокалибровке и коде соответствия из книги OpenCV и этом примере . Я использую C ++ интерфейс OpenCV. Моя версия OpenCV - 2.1, из репозитория Ubuntu 11.04.
Краткая версия вопроса:
Какое возвращаемое среднеквадратичное значение приемлемо для функции:
double cv::calibrateCamera(...)
В настоящее время я калибрую каждую камеру, используя набор из ~ 20 пар изображений шахматной доски . Камеры представляют собой два одинаковых глаза PS3 (с разрешением 640 * 480 пикселей), установленных рядом друг с другом. cv :: calibrateCamera
возвращает ошибку RMS от 160 до 300 (у меня был другой результат с разными наборами изображений). Является ли это приемлемым значением для данного разрешения изображения, или я должен попытаться получить более качественные изображения шахматной доски?
Полная версия (подробности, примеры кода):
Чтобы получить работающее стереозрение; Во-первых, я хочу убедиться, что процедура калибровки камеры работает правильно. Я использую серию изображений шахматной доски для калибровки моей стереосистемы, например:
// Find chessboard corners
cv::Mat left = ... //Load image
vector points;
bool found = cv::findChessboardCorners(left, patternSize, points, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_NORMALIZE_IMAGE);
if(found)
cv::cornerSubPix(left, points, cv::Size(11, 11), cv::Size(-1, -1), cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
imagePointsLeft.push_back(points);
Я делаю это для нескольких пар изображений и помещаю полученные точки в imagePointsLeft
и imagePointsRight
. Я выполнил проверку тех же изображений в отдельной программе, где я визуально подтверждаю, что левое и правое изображения правильно регистрируют все углы в том же порядке, используя cv :: drawChessboardCorners
. Для каждой пары изображений я также заполняю набор координат объекта следующим образом:
vector obj;
for(int i = 0; i < ny; i++)
for(int j = 0; j < nx; j++)
obj.push_back(cv::Point3f(i*squareSize,j*squareSize,0.0));
objectPoints.push_back(obj);
Затем я пытаюсь откалибровать камеры с этими изображениями:
double rms = cv::calibrateCamera(objectPoints, imagePointsLeft, m_imageSize, m_cameraMatrixLeft, m_distortionMatrixLeft, rvecsLeft, tvecsLeft);
Я использую встроенные функции камеры из этой функции, когда вызываю cv :: stereoCalibrate
с помощью флага CV_CALIB_FIX_INTRINSIC
(этот способ стереокалибровки предлагается в документации, здесь ).
Я перехожу к вызову cv :: stereoRectify
и cv :: initUndistortRectifyMap
, последний для обеих камер. Исправленные изображения создаются с помощью cv :: remap
с использованием вывода initUndistortRectifyMap
и прямой трансляции камеры. Оба изображения содержат только допустимые пиксели (без черных областей). Моя проблема в том, что пиксели данной строки не соответствуют той же строке на другом изображении (есть небольшое смещение по вертикали). Это затрудняет получение хороших результатов от алгоритмов соответствия, таких как StereoBM.