如何" undistort" OpenCV中的一组图像?

时间:2017-04-27 22:21:03

标签: c++ opencv computer-vision crop camera-calibration

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

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

Picture

我尝试了this,但它没有帮助我。

有没有办法计算一个裁剪(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;
}

谢谢你,

安东

更新: 我想我找到了一些解决方案,但我还没有机会正确地解决这个问题。它似乎工作。所以理念是:在我的CameraMatrix中,cx和cy是留置权的中心点#34;。例如,它位于我的投资回报率中间(让它为200,200)。我的投资回报率是(0,180,400,220)。我将投资回报率降低,并将相机的第一个中心转移到我的新中心。因为现在我的投资回报率是(0,0,400,40)。我的cx保持200,但cy必须转移到20.然后我根据我的cropize更改initUndistortRectifyMap大小。然后我可以投入&#34;重新映射&#34;已经是我的作物图片。代码如下。

#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;

}

0 个答案:

没有答案