2013-08-21 29 views
5

我有一個PointGrey瓢蟲3相機。這是一個全景(多)攝像頭(5個攝像頭做360º和1個攝像頭)。 我已經完成了所有校準和校正,所以我最終得到的是6張圖像的所有像素,我知道它是全球框架的3d位置。 我現在要做的是將此3d點轉換爲全景圖像。最常見的是類似以下的徑向(等距離長方圓柱)投影: Radial Porjection使用opencv從3d點創建全景圖像

對於所有的3D點(X,Y,Z)有可能找到theta和PHI協調,如:

Radial Picture Equation

我的問題是,是否有可能使用opencv自動執行此操作?或者,如果我手動執行此操作,將theta中的一串像素轉換爲phi座標到圖像的最佳方法是什麼?

官方的瓢蟲SDK使用OpenGL的所有這些操作,但我想知道是否有可能在opencv中做到這一點。

謝謝,

塞普

回答

4

我用來解決這個問題的方法是以下內容:

  1. 與所需的輸出尺寸創建一個空的圖像。
  2. 對於輸出圖像中的每個像素,找到theta和phi座標。 (線性)Theta從-Pi到Pi和從0到Pi的φ
  3. 設置投影半徑R並從theta,phi和R找到三維座標。
  4. 查找有多少相機是可見的3D點,以及對應的像素位置。
  5. 複製像素靠近主點的圖像像素。或任何其他有效的標準...

我的代碼如下所示:

cv::Mat panoramic; 
panoramic=cv::Mat::zeros(PANO_HEIGHT,PANO_WIDTH,CV_8UC3); 
double theta, phi; 
double R=calibration.getSphereRadius(); 
int result; 

double dRow=0; 
double dCol=0; 

for(int y = 0; y!= PANO_HEIGHT; y++){ 
    for(int x = 0; x !=PANO_WIDTH ; x++) { 
      //Rescale to [-pi, pi] 
     theta=-(2*PI*x/(PANO_WIDTH-1)-PI); //Sign change needed. 
      phi=PI*y/(PANO_HEIGHT-1); 

     //From theta and phi find the 3D coordinates. 
     double globalZ=R*cos(phi); 
      double globalX=R*sin(phi)*cos(theta); 
     double globalY=R*sin(phi)*sin(theta); 


     float minDistanceCenter=5000; // Doesn't depend on the image. 

     float distanceCenter; 

     //From the 3D coordinates, find in how many camera falls the point! 
     for(int cam = 0; cam!= 6; cam++){ 
      result=calibration.ladybugXYZtoRC(globalX, globalY, globalZ, cam, dRow, dCol); 
      if (result==0){ //The 3d point is visible from this camera 
       cv::Vec3b intensity = image[cam].at<cv::Vec3b>(dRow,dCol); 
       distanceCenter=sqrt(pow(dRow-imageHeight/2,2)+pow(dCol-imageWidth/2,2)); 
       if (distanceCenter<minDistanceCenter) { 
        panoramic.ptr<unsigned char>(y,x)[0]=intensity.val[0]; 
        panoramic.ptr<unsigned char>(y,x)[1]=intensity.val[1]; 
        panoramic.ptr<unsigned char>(y,x)[2]=intensity.val[2]; 

        minDistanceCenter=distanceCenter; 
       } 
      } 
     } 

    } 
}