OpenCV cvRemap обрезка изображения


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

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

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

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

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

В настоящее время: 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 3

1 ответ:

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

cvInitUndistortMap( intrinsic, distort, map1, map2 )

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

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

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

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

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

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

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

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

Вкратце:

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