【问题标题】:OpenCV Spherical Projection: Warping and UnwarpingOpenCV 球面投影:翘曲和反翘曲
【发布时间】:2019-09-28 04:31:37
【问题描述】:

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

我之前成功使用了sphericalWarper warp 函数:

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的sn-p):

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 是一个受保护的函数,所以我对如何找到目标图像的正确尺寸有点卡住了。

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

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

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

上面我定义了我的输出大小,然后使用 warpRoi 来查找 Src 大小(或窗口大小)。现在你已经有了可以从 Src 图像中剪下这个大小的 Mat 的大小(或调整它的大小),然后毫无问题地使用 warpBackward 函数。

【问题讨论】:

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


【解决方案1】:

你不能直接访问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);

【讨论】:

  • 感谢您的快速回复。这可能会有所帮助,但理想情况下,我想知道如何使用 warpbackward 命令而不会导致错误。
猜你喜欢
  • 2015-01-10
  • 2013-07-01
  • 1970-01-01
  • 2011-05-31
  • 2015-12-10
  • 2015-01-23
  • 2014-01-18
  • 2013-09-01
  • 1970-01-01
相关资源
最近更新 更多