в целях отладки я попытался переопределить функцию переназначения OpenCV. Без учета интерполяции это должно выглядеть примерно так:
for( int j = 0; j < height; j++ )
{
for( int i = 0; i < width; i++ )
{
undistortedImage.at<double>(mapy.at<float>(j,i),mapx.at<float>(j,i)) = distortedImage.at<double>(j,i);
}
}
Чтобы проверить это, я использовал следующие карты, чтобы отразить изображение вокруг оси y:
int width = distortedImage.cols;
int height = distortedImage.rows;
cv::Mat mapx = Mat(height, width, CV_32FC1);
cv::Mat mapy = Mat(height, width, CV_32FC1);
for( int j = 0; j < height; j++)
{
for( int i = 0; i < width; i++)
{
mapx.at<float>(j,i) = width - i - 1;
mapy.at<float>(j,i) = j;
}
}
Но интерполяция это работает так же, как
cv::remap( distortedImage, undistortedImage, mapx, mapy, CV_INTER_LINEAR);
Теперь я попытался применить эту функцию на картах, созданных Набор инструментов OCamCalib за неискаженные изображения. По сути, это то же самое, что и то, что делается с помощью искажения OpenCV.
Моя реализация сейчас, очевидно, не учитывает, что несколько пикселей из исходного изображения отображаются на один и тот же пиксель в конечном изображении. Но это хуже. На самом деле, похоже, что мое исходное изображение появляется три раза в уменьшенных версиях на целевом изображении. В противном случае команда remap работает отлично.
После исчерпывающей отладки я решил попросить вас, ребята, о помощи. Может кто-нибудь объяснить мне, что я делаю неправильно или предоставить ссылку на реализацию remap в OpenCV?
Я понял это сам. Моя оригинальная реализация имеет две фундаментальные ошибки:
Как это сделать правильно:
for( int j = 0; j < height; j++ )
{
for( int i = 0; i < width; i++ )
{
undistortedImage.at<uchar>(mapy.at<float>(j,i),mapx.at<float>(j,i)) = distortedImage.at<uchar>(j,i);
}
}
Я хочу подчеркнуть, что значения интенсивности из изображений теперь извлекаются с использованием .at<Uchar> вместо .at<двойной>, Кроме того, индексы для карт поменялись.
Других решений пока нет …