2013-08-21 16 views
5

Possiedo una fotocamera PointGrey Ladybug3. È una fotocamera panoramica (multipla) (5 fotocamera per fare una telecamera a 360º e 1 a guardare in alto). Ho eseguito tutte le calibrazioni e le correzioni, quindi quello che finisco è da tutti i pixel delle 6 immagini. So che si tratta di una posizione 3D su una cornice globale. Quello che vorrei fare ora è convertire questi punti 3d in un'immagine panoramica. Il più comune è una sporgenza radiale (equirettangolare) come la seguente: Radial PorjectionUtilizzo di opencv per creare un'immagine panoramica da punti 3d

Per tutti i punti 3D (X, Y, Z) è possibile trovare theta e phi coordinate come:

Radial Picture Equation

La mia domanda è, è possibile farlo automaticamente con opencv? O se lo faccio manualmente qual è il modo migliore per convertire quel mucchio di pixel in theta, coordinate Phi su un'immagine?

L'SDK ladybug ufficiale utilizza OpenGL per tutte queste operazioni, ma mi chiedevo se è possibile farlo in OpenCV.

Grazie,

Josep

risposta

4

L'approccio che usato per risolvere questo problema è stato il seguente:

  1. creare un'immagine vuota con il formato di uscita desiderato.
  2. Per ogni pixel nell'immagine di output, trovare le coordinate theta e phi. (Linearmente) Theta va da -Pi a Pi e phi da 0 a Pi
  3. Impostare un raggio R proiezione e la coordinata 3D da theta, phi e R.
  4. Trova per quante telecamere è il punto 3D visibile e corrispondente posizione dei pixel.
  5. Copia il pixel dell'immagine in cui il pixel è più vicino al punto principale. O qualsiasi altro criterio validi ...

mio codice è simile:

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

    } 
}