2013-11-11 5 views
6

Я искал неискаженное изображение, используя коэффициенты искажения, которые я вычислил для своей камеры, без изменения матрицы камеры. Это именно то, что делает 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)). Вопрос в том, почему? Что будут содержать эти карты? Каково значение и цель этой чередовании? Каково значение и цель странного измерения полос?

ответ

2

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

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

2

Возможно, вы захотите прочитать описание функции remap. Карта представляет местоположение пикселя X, Y в исходном изображении для каждого пикселя целевого изображения. Map1_part - это каждое местоположение X в источнике, а Map2_part - каждое местоположение Y в источнике.

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

EDIT:

Кроме того, если вы хотите просто масштабировать изображение до большего размера можно просто изменить размер выходного изображения.

double scaleX = 2.0; 
double scaleY = 2.0; 
cv::Mat undistortedScaled; 

cv::resize(undistorted, undistortedScaled, cv::Size(0,0), scaleX, scaleY); 
+1

Не будет ли это менее точным, чем выборка для большего выходного изображения с функцией отображения? Это просто будет масштабировать его 2x, который не улучшает разрешение ... –

Смежные вопросы