C#OpenCV镜头失真校正

时间:2016-02-23 17:37:39

标签: c# opencv

任何人都可以帮我解决这个问题吗?我在c ++中找到了一些解决方案并尝试用C#重写它,但我不知道如何继续。我有Cv.Mat,但我不知道如何将新的CvPoint2D32f添加到pixel_locations_src [i,j]以及如何将fractional_locations_dst [i,j]转换为CvPoint2D32f并获得此点的X和Y.这是我的工作代码:

    public static Bitmap BarrelDistortionOpenCV(Bitmap img, CvMat cameraMatrix, CvMat distCoeffs)
    {
        IplImage image = BitmapConverter.ToIplImage(img);
        CvMat src = bitmapToMat(img);
        CvMat dst = new CvMat();

        CvMat pixel_locations_src = Cv.Mat<CvPoint2D32f>(src.Rows, src.Cols, MatrixType.F32C2, new CvPoint2D32f[] { });

        for (int i = 0; i < src.GetSize().Height; i++)
        {
            for (int j = 0; j < src.GetSize().Width; j++)
            {
                pixel_locations_src[i, j] = new CvPoint2D32f(j, i);
            }
        }

        CvMat pixel_locations_dst = Cv.Mat<CvPoint2D32f>(src.Rows, src.Cols, MatrixType.F32C2, new CvPoint2D32f[] { });

        Cv.UndistortPoints(pixel_locations_src, pixel_locations_dst, cameraMatrix, distCoeffs, new CvMat(), new CvMat());

        CvMat fractional_locations_dst = new CvMat(src.Rows, src.Cols, MatrixType.F32C2);

        float fx = (float)cameraMatrix[0, 0];
        float fy = (float)cameraMatrix[1, 1];
        float cx = (float)cameraMatrix[0, 2];
        float cy = (float)cameraMatrix[1, 2];

        // is there a faster way to do this?
        for (int i = 0; i < fractional_locations_dst.GetSize().Height; i++)
        {
            for (int j = 0; j < fractional_locations_dst.GetSize().Width; j++)
            {
                float x = fractional_locations_dst[i, j].X * fx + cx;
                float y = fractional_locations_dst[i, j].Y * fy + cy;
                pixel_locations_dst[i, j] = new CvPoint2D32f(x, y);
            }
        }

        Cv.Remap(src, dst, pixel_locations_dst, new CvMat(), Interpolation.Linear);

        return BitmapConverter.ToBitmap(matToIplImage(dst, image.Depth, image.NChannels));
    }

以下是我使用的原始c ++代码:

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<cv::Point2f>(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<double>(0,0);
  const float fy = cameraMatrix.at<double>(1,1);
  const float cx = cameraMatrix.at<double>(0,2);
  const float cy = cameraMatrix.at<double>(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<cv::Point2f>(i,j).x*fx + cx;
      const float y = fractional_locations_dst.at<cv::Point2f>(i,j).y*fy + cy;
      pixel_locations_dst.at<cv::Point2f>(i,j) = cv::Point2f(x,y);
    }
  }

  cv::remap(src, dst, pixel_locations_dst, cv::Mat(), CV_INTER_LINEAR);
}

感谢任何想法如何解决它或任何其他工作解决方案。

0 个答案:

没有答案