使用OpenCV从3D点创建全景图像

8
我有一台PointGrey Ladybug3相机。它是一款全景(多)相机(5个相机实现360度和1个相机向上拍摄)。 我已经完成了所有的校准和矫正,因此从6张图像的所有像素中得到的是它们相对于全局坐标系的3D位置。 现在我要做的是将这些3D点转换为全景图像。最常见的是径向(等距)投影,如下所示: Radial Porjection 对于所有的3D点(X,Y,Z),可以找到theta和phi坐标,如下所示: Radial Picture Equation 我的问题是,是否可能使用opencv自动完成这个过程?或者如果我手动执行这个操作,将这堆像素转换为theta、phi坐标的最佳方法是什么? 官方的Ladybug SDK使用OpenGL进行所有这些操作,但我想知道是否可能在opencv中完成这些操作。
谢谢, Josep
1个回答

9
我用的解决这个问题的方法如下:
  1. 创建一个大小合适的空白图像。
  2. 对于输出图像中的每个像素,找到其所在的theta和phi坐标。 (线性)Theta从-Pi到Pi,而phi从0到Pi。
  3. 设置一个投影半径R,并根据theta、phi和R找到3D坐标。
  4. 找到该三维点在多少个相机中可见以及相应的像素位置。
  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;
                }
            }
        }

    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接