如何在 OpenCV 中“消除扭曲”图像裁剪?

Ant*_*on 5 c++ opencv crop computer-vision camera-calibration

我正在使用具有宽鱼眼的 IDS 相机。它是 2D 相机,但我只需要中间的线。我知道了如何校准相机:我可以获得不失真的图像。

我的问题是我需要快速计算。所以我试图找到一种方法,如何只计算裁剪而不是整个图片,然后裁剪。我需要这样的东西:

图片

我已经尝试过这个,但它对我没有帮助。

有什么方法可以只计算裁剪(1280x6)而不是所有图片(1280x960)?

int main ()
{
   timespec time1, time2, timeAfterS, timeStart, execTime;
   Mat intrinsic = Mat (3, 3, CV_32FC1);
   Mat newCamMat=Mat (3, 3, CV_32FC1);
   Mat distCoeffs;
   FileStorage fs ("cameraData.xml", FileStorage::READ);
   fs["intrinsic"] >> intrinsic;
   fs["distCoeffs"] >> distCoeffs;
   fs.release ();
   VideoCapture capture = VideoCapture (0);


   Mat image;
   Mat imageUndistorted;
   int l = 0;
   clock_gettime (CLOCK_REALTIME, &timeStart);

   //For Example i need to compute just this following crop of image
   //    |
   //    V
   Rect recT(10,10,20,20);
   while (l != 27)
   {

      capture >> image;
      newCamMat=getOptimalNewCameraMatrix (intrinsic, distCoeffs,  
                      image.size(),0.5,image.size(),&recT,false);
      newCamMat.at<double>(0,2)=0;
      newCamMat.at<double>(1,2)=20;
      undistort (image, imageUndistorted, intrinsic,   
                              distCoeffs,newCamMat);

      imshow ("win1", image);
      imshow ("win2", imageUndistorted);
      l = waitKey (1);

  }

  capture.release ();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

提前谢谢你了,

安东

更新:我想我找到了一些解决方案,但我还没有机会正确解决它。似乎正在发挥作用。所以想法是:在我的 CameraMatrix 中,cx 和 cy 是“留置权中心”的点。例如,它位于我的投资回报率的中间(假设为 200,200)。我的投资回报率是(0,180,400,220)。我剪掉了投资回报率,然后首先将相机的中心移动到我的新中心。因为现在我的投资回报率是 (0,0,400,40)。我的 cx 保持为 200,但 cy 必须转移到 20。然后我根据我的裁剪尺寸更改 initUn DistaultRectifyMap 大小。然后我可以输入“重新映射”我的裁剪图片。代码如下。

#include <iostream>
#include "opencv2/opencv.hpp"
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <sstream>
#include <ctime>
#include <time.h>
#include <cmath>
using namespace cv;
using namespace std;

timespec diff (timespec start, timespec end)
{
    timespec temp;
    if ((end.tv_nsec - start.tv_nsec) < 0)
    {
        temp.tv_sec = end.tv_sec - start.tv_sec - 1;
        temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
    }
    else
    {
        temp.tv_sec = end.tv_sec - start.tv_sec;
        temp.tv_nsec = end.tv_nsec - start.tv_nsec;
    }
    return temp;
}
int main ()
{
    timespec time1, time2, timeAfterS, timeStart, execTime;
    Mat intrinsic = Mat (3, 3, CV_32FC1);
    Mat newCamMat = Mat (3, 3, CV_32FC1);
    Mat distCoeffs;
    FileStorage fs ("cameraData.xml", FileStorage::READ);
    fs["intrinsic"] >> intrinsic;
    fs["distCoeffs"] >> distCoeffs;
    fs.release ();
    intrinsic.copyTo(newCamMat);
    VideoCapture capture = VideoCapture (0);
    capture.set (CAP_PROP_FPS, 90);
    Mat image;
    Mat imageUndistorted;
    Mat imageUndistorted1;
    int l = 0;
    capture >> image;
    clock_gettime (CLOCK_REALTIME, &timeStart);
    Rect recT (10, 10, 20, 20);
    Rect roi (0, 400, 640, 30);//Region of Interests
    Rect roi1 (0, 360, 640, 60); // To show borders of ROI
    Mat view, rview, map1, map2,map3,map4,crop2;
    Mat crop = Mat (30, 640, CV_8UC3); // here I define the size of crop
    intrinsic.at<double> (1, 2) = intrinsic.at<double> (1, 2) - 400; // here i shift the cy to the new middle of frish cut ROI
initUndistortRectifyMap (intrinsic, distCoeffs, Mat (), intrinsic, crop.size (), CV_16SC2, map1, map2); // here i apply transform.. at least i believe i do it :)
while (l != 27)
{
    capture >> image;
    rectangle (image, recT, Scalar (255, 0, 0), 2, 8, 0);
    rectangle (image, roi, Scalar (255, 0, 0), 2, 8, 0);
    clock_gettime (CLOCK_REALTIME, &time1);
    remap (image(roi), imageUndistorted, map1, map2, INTER_LINEAR);

    initUndistortRectifyMap (newCamMat, distCoeffs, Mat (),  
    newCamMat, image.size (), CV_16SC2, map3, map4);// to compare with uncroped picture
    remap (image, imageUndistorted1, map3, map4, INTER_LINEAR);

    clock_gettime (CLOCK_REALTIME, &time2);
    execTime = diff (time1, time2);
        cout << "  FPS: " << 1000000000. / execTime.tv_nsec << " per second, " << endl;
    imshow("image(roi)",image(roi1));
    imshow ("win1", image);
    imshow ("win2", imageUndistorted);
    imshow ("win3", imageUndistorted1);
    l = waitKey (1);
}
capture.release ();
return 0;
Run Code Online (Sandbox Code Playgroud)

}