使用 opencv 从 3d 点创建全景图像

Posted

技术标签:

【中文标题】使用 opencv 从 3d 点创建全景图像【英文标题】:Using opencv to create a panoramic image from 3d points 【发布时间】:2013-08-21 09:57:44 【问题描述】:

我有一台 PointGrey Ladybug3 相机。这是一个全景(多)相机(5 个相机进行 360º 和 1 个相机仰视)。 我已经完成了所有的校准和校正,所以我最终得到的是来自 6 个图像的所有像素,我知道它是一个全局框架的 3d 位置。 我现在要做的是将此 3d 点转换为全景图像。最常见的是径向(Equirectangular)投影,如下所示:

对于所有 3D 点(X、Y、Z),可以找到 theta 和 phi 坐标,如下所示:

我的问题是,是否可以使用 opencv 自动执行此操作?或者如果我手动执行此操作,将 theta,phi 坐标中的那一堆像素转换为图像的最佳方法是什么?

官方的瓢虫 SDK 使用 OpenGL 进行所有这些操作,但我想知道是否可以在 opencv 中执行此操作。

谢谢,

约瑟夫

【问题讨论】:

【参考方案1】:

我用来解决这个问题的方法如下:

    创建具有所需输出大小的空图像。 对于输出图像中的每个像素,找到 theta 和 phi 坐标。 (线性)Theta 从 -Pi 到 Pi 和 phi 从 0 到 Pi 设置投影半径 R 并从 theta、phi 和 R 中找到 3D 坐标。 查找 3D 点可见的摄像机数量以及对应的像素位置。 复制图像中离主点较近的像素。或任何其他有效标准...

我的代码如下:

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;
                
            
        

    

【讨论】:

以上是关于使用 opencv 从 3d 点创建全景图像的主要内容,如果未能解决你的问题,请参考以下文章

Opencv图像拼接或全景

OpenCV:如何将图像垂直拼接成长图像而不是全景图/水平

基于Python和openCV实现图像的全景拼接

Stone 3D教程:创建全景图云展览,只需要几分钟

Stone 3D教程:创建全景图云展览,只需要几分钟

Stone 3D教程:创建全景图云展览,只需要几分钟