2013-08-21 36 views
5

Tôi có máy ảnh PointGrey Ladybug3. Đó là một máy ảnh toàn cảnh (đa) (5 camera để thực hiện máy ảnh 360º và 1 nhìn lên). Tôi đã thực hiện tất cả các hiệu chuẩn và chỉnh lưu vì vậy những gì tôi kết thúc là từ tất cả các điểm ảnh của 6 hình ảnh tôi biết đó là vị trí 3d wrt một khung toàn cầu. Điều tôi sẽ làm bây giờ là chuyển đổi điểm 3d này thành hình ảnh toàn cảnh. Phổ biến nhất là một hình tròn (Equirectangular) chiếu như một sau: Radial PorjectionSử dụng opencv để tạo hình ảnh toàn cảnh từ các điểm 3d

Đối với tất cả các điểm 3D (X, Y, Z) nó có thể tìm theta và Phi phối hợp như:

Radial Picture Equation

Câu hỏi của tôi là, Có thể thực hiện điều này tự động với opencv không? Hoặc nếu tôi làm điều này theo cách thủ công cách tốt nhất để chuyển đổi các bó pixel đó trong theta, phi tọa độ thành một hình ảnh là gì?

SDK bọ rùa chính thức sử dụng OpenGL cho tất cả các hoạt động này, nhưng tôi đã tự hỏi liệu có thể thực hiện điều này trong opencv hay không.

Cảm ơn,

Josep

Trả lời

4

Phương pháp tôi sử dụng để giải quyết vấn đề này là như sau:

  1. Tạo một hình ảnh trống rỗng với kích thước đầu ra mong muốn.
  2. Đối với mỗi điểm ảnh trong hình ảnh đầu ra, hãy tìm tọa độ theta và phi. (Tuyến tính) Theta chuyển từ -Pi sang Pi và phi từ 0 sang Pi
  3. Đặt bán kính chiếu R và tìm tọa độ 3D từ theta, phi và R.
  4. Tìm bao nhiêu máy ảnh là điểm 3D có thể nhìn thấy và vị trí pixel tương ứng.
  5. Sao chép pixel của hình ảnh nơi pixel gần điểm chính hơn. Hoặc bất kỳ tiêu chí hợp lệ khác ...

Mã của tôi trông giống như:

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

    } 
} 
Các vấn đề liên quan