I get images from a camera where it is not possible to take a chessboard picture and calculate the correction matrix using OpenCV. Up to now I corrected the images using ima
This is a complementary function to undistort, may be faster or better ways to do it but it works:
void distort(const cv::Mat& src, cv::Mat& dst, const cv::Mat& cameraMatrix, const cv::Mat& distCoeffs)
{
cv::Mat distort_x = cv::Mat(src.size(), CV_32F);
cv::Mat distort_y = cv::Mat(src.size(), CV_32F);
cv::Mat pixel_locations_src = cv::Mat(src.size(), CV_32FC2);
for (int i = 0; i < src.size().height; i++) {
for (int j = 0; j < src.size().width; j++) {
pixel_locations_src.at(i,j) = cv::Point2f(j,i);
}
}
cv::Mat fractional_locations_dst = cv::Mat(src.size(), CV_32FC2);
cv::undistortPoints(pixel_locations_src, pixel_locations_dst, cameraMatrix, distCoeffs);
cv::Mat pixel_locations_dst = cv::Mat(src.size(), CV_32FC2);
const float fx = cameraMatrix.at(0,0);
const float fy = cameraMatrix.at(1,1);
const float cx = cameraMatrix.at(0,2);
const float cy = cameraMatrix.at(1,2);
// is there a faster way to do this?
for (int i = 0; i < fractional_locations_dst.size().height; i++) {
for (int j = 0; j < fractional_locations_dst.size().width; j++) {
const float x = fractional_locations_dst.at(i,j).x*fx + cx;
const float y = fractional_locations_dst.at(i,j).y*fy + cy;
pixel_locations_dst.at(i,j) = cv::Point2f(x,y);
}
}
cv::remap(src, dst, pixel_locations_dst, cv::Mat(), CV_INTER_LINEAR);
}