Я искал неискаженное изображение, используя коэффициенты искажения, которые я вычислил для своей камеры, без изменения матрицы камеры. Это именно то, что делает undistort()
, но я хотел бы сделать вывод на более крупном изображении холста.Понимание неискаженной функции OpenCV
Когда я попытался это:
Mat drawtransform = getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, size, 1.0, size * 2);
undistort(inputimage, undistorted, cameraMatrix, distCoeffs, drawtransform);
Это еще выписал же размера изображения, а только верхнюю левую четверть уложенных вверх-по-два неискаженной результата. Like the documentation says, нестандартная запись в целевое изображение того же размера.
Совершенно очевидно, что я могу просто скопировать и переопределить слегка измененную версию undistort()
, но у меня возникли проблемы с пониманием того, что она делает. Вот источник:
void cv::undistort(InputArray _src, OutputArray _dst, InputArray _cameraMatrix,
InputArray _distCoeffs, InputArray _newCameraMatrix)
{
Mat src = _src.getMat(), cameraMatrix = _cameraMatrix.getMat();
Mat distCoeffs = _distCoeffs.getMat(), newCameraMatrix = _newCameraMatrix.getMat();
_dst.create(src.size(), src.type());
Mat dst = _dst.getMat();
CV_Assert(dst.data != src.data);
int stripe_size0 = std::min(std::max(1, (1 << 12)/std::max(src.cols, 1)), src.rows);
Mat map1(stripe_size0, src.cols, CV_16SC2), map2(stripe_size0, src.cols, CV_16UC1);
Mat_<double> A, Ar, I = Mat_<double>::eye(3,3);
cameraMatrix.convertTo(A, CV_64F);
if(distCoeffs.data)
distCoeffs = Mat_<double>(distCoeffs);
else
{
distCoeffs.create(5, 1, CV_64F);
distCoeffs = 0.;
}
if(newCameraMatrix.data)
newCameraMatrix.convertTo(Ar, CV_64F);
else
A.copyTo(Ar);
double v0 = Ar(1, 2);
for(int y = 0; y < src.rows; y += stripe_size0)
{
int stripe_size = std::min(stripe_size0, src.rows - y);
Ar(1, 2) = v0 - y;
Mat map1_part = map1.rowRange(0, stripe_size),
map2_part = map2.rowRange(0, stripe_size),
dst_part = dst.rowRange(y, y + stripe_size);
initUndistortRectifyMap(A, distCoeffs, I, Ar, Size(src.cols, stripe_size),
map1_part.type(), map1_part, map2_part);
remap(src, dst_part, map1_part, map2_part, INTER_LINEAR, BORDER_CONSTANT);
}
}
Около половины линий здесь предназначены для проверки работоспособности и инициализации входных параметров. То, что я смущен, это то, что происходит с map1
и map2
. Эти имена, к сожалению, менее наглядны, чем большинство. Мне нужно упустить какое-то объяснение, возможно, оно убрано на какой-то странице введения или под документом для другой функции.
map1
- это двухканальная сигнальная короткая целочисленная матрица, а map2
- это беззнаковая короткая целочисленная матрица, размеры которой (высота, макс (4096/ширина, 1)). Вопрос в том, почему? Что будут содержать эти карты? Каково значение и цель этой чередовании? Каково значение и цель странного измерения полос?
Не будет ли это менее точным, чем выборка для большего выходного изображения с функцией отображения? Это просто будет масштабировать его 2x, который не улучшает разрешение ... –