如何在没有插值的情况下获得未失真的图像
how to obtain undistorted image without interpolation
我一直在努力获得没有插值的未失真图像。但是当执行下面的代码时,我得到一些奇怪的 image.I 我正在使用函数 initUndistortRectifyMap ,它给出类型 CV_16SC2 的 mapx 和 mapy 稍后使用 convertMaps 函数我将 mapx 和 mapy 转换为类型 CV_32FC1.I 一直在尝试调试原因,但找不到任何有用的信息。
扭曲的图像
在没有插值的情况下应用 undistort 后的图像
int main()
{
Mat Cam1MatrixParam, Cam1Distortion;
Mat cf1;
cf1=imread("cam1.distort1.jpg", CV_LOAD_IMAGE_COLOR);
Size imagesize = cf1.size();
FileStorage fs1("cameracalibration.xml", FileStorage::READ);
fs1["camera_matrix"] >> Cam1MatrixParam;
fs1["distortion_coefficients"] >> Cam1Distortion;
Mat R = Mat::eye(3, 3, CV_32F) * 1;
int width = cf1.cols;
int height = cf1.rows;
Mat undistorted = Mat(height, width, CV_8UC3);
Mat mapx = Mat(height, width, CV_32FC1);
Mat mapy = Mat(height, width, CV_32FC1);
initUndistortRectifyMap(Cam1MatrixParam, Cam1Distortion, Cam1MatrixParam, R, imagesize, CV_16SC2, mapx, mapy);
convertMaps(mapx, mapy, mapx, mapy, CV_32FC1, false);
for (int j = 0; j < height; j++)
{
for ( int i = 0; i < width; i++)
{
undistorted.at<uchar>(mapy.at<float>(j, i), mapx.at<float>(j, i)) = cf1.at<uchar>(j, i);
}
}
imwrite("cam1.undistortimage.png", undistorted);
}
使用此版本代码的图像
undistorted.at(j, i) = cf1.at(mapy.at(j, i), mapx.at(j, i));
具有不失真功能的图像(使用最近的插值重新映射)
看起来它并没有消除扭曲,而是再次应用了扭曲。
mapx
和 mapy
从显示坐标映射到照片坐标。
undistorted.at<cv::Vec3b>(j, i) = distort.at<cv::Vec3b>(mapy.at<float>(j, i), mapx.at<float>(j, i));
您可以将此代码解释为:对于每个显示坐标{j, i}
在照片中找到其对应的(扭曲的)坐标,然后复制像素。
您使用的是彩色图像 (cv::Vec3b),所以尝试改用:
undistorted.at<cv::Vec3b>(mapy.at<float>(j, i), mapx.at<float>(j, i)) = cf1.at<cv::Vec3b>(j, i);
如果 undistort map 是反向的,可能会结合 Maxim Egorushkin 的答案
我一直在努力获得没有插值的未失真图像。但是当执行下面的代码时,我得到一些奇怪的 image.I 我正在使用函数 initUndistortRectifyMap ,它给出类型 CV_16SC2 的 mapx 和 mapy 稍后使用 convertMaps 函数我将 mapx 和 mapy 转换为类型 CV_32FC1.I 一直在尝试调试原因,但找不到任何有用的信息。
扭曲的图像
int main()
{
Mat Cam1MatrixParam, Cam1Distortion;
Mat cf1;
cf1=imread("cam1.distort1.jpg", CV_LOAD_IMAGE_COLOR);
Size imagesize = cf1.size();
FileStorage fs1("cameracalibration.xml", FileStorage::READ);
fs1["camera_matrix"] >> Cam1MatrixParam;
fs1["distortion_coefficients"] >> Cam1Distortion;
Mat R = Mat::eye(3, 3, CV_32F) * 1;
int width = cf1.cols;
int height = cf1.rows;
Mat undistorted = Mat(height, width, CV_8UC3);
Mat mapx = Mat(height, width, CV_32FC1);
Mat mapy = Mat(height, width, CV_32FC1);
initUndistortRectifyMap(Cam1MatrixParam, Cam1Distortion, Cam1MatrixParam, R, imagesize, CV_16SC2, mapx, mapy);
convertMaps(mapx, mapy, mapx, mapy, CV_32FC1, false);
for (int j = 0; j < height; j++)
{
for ( int i = 0; i < width; i++)
{
undistorted.at<uchar>(mapy.at<float>(j, i), mapx.at<float>(j, i)) = cf1.at<uchar>(j, i);
}
}
imwrite("cam1.undistortimage.png", undistorted);
}
使用此版本代码的图像
undistorted.at(j, i) = cf1.at(mapy.at(j, i), mapx.at(j, i));
具有不失真功能的图像(使用最近的插值重新映射)
看起来它并没有消除扭曲,而是再次应用了扭曲。
mapx
和 mapy
从显示坐标映射到照片坐标。
undistorted.at<cv::Vec3b>(j, i) = distort.at<cv::Vec3b>(mapy.at<float>(j, i), mapx.at<float>(j, i));
您可以将此代码解释为:对于每个显示坐标{j, i}
在照片中找到其对应的(扭曲的)坐标,然后复制像素。
您使用的是彩色图像 (cv::Vec3b),所以尝试改用:
undistorted.at<cv::Vec3b>(mapy.at<float>(j, i), mapx.at<float>(j, i)) = cf1.at<cv::Vec3b>(j, i);
如果 undistort map 是反向的,可能会结合 Maxim Egorushkin 的答案