OpenCV球形投影:变形和变形

时间:2019-05-10 09:29:03

标签: c++ opencv computer-vision opencv3.0

我正在尝试从球面投影重新创建摄像机的视图,以使生成的图像是正交的(实际上,直线等于图像空间中的直线)。

在成功使用之前,我已经使用了sphericalWarper变形函数:

detail::SphericalWarper Projection = detail::SphericalWarper(((360.0/PX2DEG)/PI)/2.0);
Mat SrcProj;
Projection.warp(Src, CameraIntrinsics, Rotation, INTER_LINEAR, 0,SrcProj);

但是当我使用函数warpBackward时,它要求我指定目标Mat大小。如果它的大小不是很特定,则可能会导致错误。我钻入了库文件,找到了发送错误的断言,然后找到了这个(来自warpers_inl.hpp的片段):

void RotationWarperBase<P>::warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, Size dst_size, OutputArray dst)
{
projector_.setCameraParams(K, R);
Point src_tl, src_br;
detectResultRoi(dst_size, src_tl, src_br);
Size size = src.size();
CV_Assert(src_br.x - src_tl.x + 1 == size.width && src_br.y - src_tl.y + 1 == size.height);

不幸的是,detectResultRoi是受保护的函数,因此对于如何找到目标图像的正确尺寸有些困惑。

任何帮助将不胜感激,谢谢!

===================================编辑========== ========================= 可以使用warpRoi函数(公开)计算Src大小。

Mat SrcProj=Mat(480,640,CV_8UC3,Scalar(0,0,0));
Rect WindowSize=Projection.warpRoi(SrcProj.size(),CameraIntrinsics,Rotation);

上面我定义了输出大小,然后使用warpRoi查找Src大小(或窗口大小)。现在您有了尺寸,您可以从Src图像中裁剪此尺寸的Mat(或调整其尺寸),然后使用warpBackward函数而不会出现问题。

1 个答案:

答案 0 :(得分:0)

您不能直接访问detectResultRoi,但可以继承它并在自己的类中随意使用。

class MySphericalWarper : private SphericalWarper
{
public:
    using SphericalWarper::warp;
    void unwarp( ... ) { 
         ...
        detectResultRoi( ... );
         ...
    }
     ...
};

然后只使用您的实现。

MySphericalWarper warper( ... );
Mat proj, unproj;
warper.warp(src, ... , proj);
// warp backward
warper.unwarp(proj, ... , unproj);

但是我认为detectResultRoi对检测未投影的图像尺寸不会有用。实际上,您需要做相反的事情,因为detectResultRoi计算投影图像所在的球形图像区域。

您需要知道投影像素在球形图像中的位置。然后,您可以计算未投影图像的大小:取该区域(通常不是矩形)的所有边界像素中最右边和最左边,最高和最低未投影像素位置之间的差。可以使用SphericalWarper::projector_.mapBackward()获取此位置。 projector_的成员也是protected,因此您需要使用与上述detectResultRoi相同的方式使用它。

此大小与warp的图像大小相同,如果要向后弯曲结果(或修改结果,可以更改像素值,这不会更改像素位置的映射) )的warp

detail::SphericalWarper projection(((360.0/PX2DEG)/PI)/2.0);
Mat proj, unproj;
projection.warp(src, CameraIntrinsics, Rotation, INTER_LINEAR, 0, proj);
// paint on proj or something ...
projection.warpBackward(proj, CameraIntrinsics, Rotation, INTER_LINEAR, 0, src.size(), unproj);