Correct barrel distortion in OpenCV manually, without chessboard image

前端 未结 3 1397
轮回少年
轮回少年 2020-12-15 01:03

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

3条回答
  •  时光说笑
    2020-12-15 01:36

    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);
    }
    

提交回复
热议问题