OpenCV cvRemap Кадрирование изображения - PullRequest
3 голосов
/ 12 января 2012

Так что я очень новичок в OpenCV (2.1), поэтому имейте это в виду.

Итак, мне удалось откалибровать мою дешевую веб-камеру, которую я использую (с широким углом * 1004).* приложение), используя метод калибровки шахматной доски, чтобы получить внутренние коэффициенты и коэффициенты искажения.

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

Однако я столкнулся с проблемой.Я знаю, что когда он деформирует / корректирует изображение, он создает несколько искаженных участков, а затем форматирует изображение, чтобы обрезать любые черные области.Тогда мой вопрос: могу ли я просмотреть полное искаженное изображение, включая некоторые регионы с черными областями?Ниже приведен пример черных областей с перекосами, которые я пытался передать, если моя терминология была отключена:

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

В настоящее время: cvRemap () возвращает в основном желтое поле на изображении, связанном выше, но я хочу увидеть всеизображение, поскольку есть соответствующие данные, которые я хочу получить из него.

То, что я пробовал: Применение преобразования масштаба к карте изображения для подгонки к полному изображению (включая растянутые части) в кадр

        CvMat *intrinsic = (CvMat*)cvLoad( "Intrinsics.xml" );
        CvMat *distortion = (CvMat*)cvLoad( "Distortion.xml" );

        cvInitUndistortMap( intrinsic, distortion, mapx, mapy );

        cvConvertScale(mapx, mapx, 1.25, -shift_x);   // Some sort of scale conversion
        cvConvertScale(mapy, mapy, 1.25, -shift_y);   // applied to the image map

        cvRemap(distorted,undistorted,mapx,mapy);

cvConvertScale, когда мне кажется, что я правильно выровнял сдвиг x / y (угадывание / проверка), каким-то образом искажает карту изображения, делая коррекцию бесполезной.Здесь может быть какая-то математика, которую я неправильно понимаю / понимаю.

У кого-нибудь есть какие-либо другие предложения по решению этой проблемы, или что я могу делать неправильно?Я также пытался написать свой собственный код, чтобы исправить проблемы с искажениями, но давайте просто скажем, что OpenCV уже знает, как это сделать хорошо.

1 Ответ

4 голосов
/ 13 января 2012

Из памяти необходимо использовать InitUndistortRectifyMap(cameraMatrix,distCoeffs,R,newCameraMatrix,map1,map2), из которых InitUndistortMap является упрощенной версией.

cvInitUndistortMap( intrinsic, distort, map1, map2 )

эквивалентно:

cvInitUndistortRectifyMap( intrinsic, distort, Identity matrix, intrinsic, 
                           map1, map2 )

Новые параметры R и newCameraMatrix.R определяет дополнительное преобразование (например, вращение) для выполнения (просто установите его в единичную матрицу).

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

Вы получаете новую матрицу камеры с GetOptimalNewCameraMatrix(cameraMat, distCoeffs, imageSize, alpha,...).Вы в основном вводите intrinsic, distort, исходный размер изображения и параметр alpha (вместе с контейнерами для хранения матрицы результатов см. Документацию).Параметр alpha достигнет того, что вы хотите.

Я цитирую из документации:

Функция вычисляет оптимальную новую матрицу камеры на основе параметра свободного масштабирования.Изменяя этот параметр, пользователь может получить только разумные пиксели alpha = 0 , сохранить все исходные пиксели изображения, если в углах есть альфа = 1 , или получить что-то среднее между,Когда альфа> 0, результат искажения, скорее всего, будет иметь несколько черных пикселей, соответствующих «виртуальным» пикселям за пределами захваченного искаженного изображения.Исходная матрица камеры, коэффициенты искажения, вычисленная матрица новой камеры и newImageSize должны быть переданы в InitUndistortRectifyMap для создания карт для Remap.

Так что для крайнего примера со всеми черными битами, которые вы хотите видетьalpha=1.

В итоге:

  • вызов cvGetOptimalNewCameraMatrix с alpha=1 для получения newCameraMatrix.
  • использование cvInitUndistortRectifymap с Rбудучи матрицей тождества и newCameraMatrix установленной на ту, которую вы только что рассчитали
  • вставьте новые карты в cvRemap.
...