c++ - OpenCV 球面投影 : Warping and Unwarping

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

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

我以前成功使用过 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 是一个 protected 函数,所以我对如何找到目标图像的正确大小有点困惑。

非常感谢任何帮助,谢谢!

====================================编辑========== ========================== 可以使用公开的 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 函数。

最佳答案

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

关于c++ - OpenCV 球面投影 : Warping and Unwarping,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56074645/

相关文章:

c++ - 如何在 Windows API 中指定与编码无关的字符串常量?

c++ - 一些库如何用多个返回类型覆盖 operator[]?

c++ - 为什么我的 C++ Qt UI 被翻译了,但程序中的 QString 却没有被翻译?

c++ - 如何在opencv中以 vector 数据类型存储点坐标?

python - 使用opencv识别OCR期间的元音字符

python - 使用Python消除视频中的冗余帧

python - 如何在Python中仅打开10%放大的jpeg图像?

c++ - 如何在 C++ 中编写自定义输入流

c - 如何读取指针式 watch 的时间?

python - OpenCV:从 RGB 图像中提取颜色 channel