OpenCV球形投影:变形和变形 [英] OpenCV Spherical Projection: Warping and Unwarping

查看:646
本文介绍了OpenCV球形投影:变形和变形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to recreate the view of a camera from a spherical projection, so that the resulting image is orthographic (straight lines in reality equate to straight lines in the image space).

在成功之前,我已经使用了pheralWarper翘曲函数:

I have used the sphericalWarper warp function before with success:

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的片段):

But when I use the function warpBackward, it requires me to specify the destination Mat size. It seems like if its not a very specific size, it causes an error. I dug into the library files and found the assert which sends the error, and found this (snippet from 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 是受保护的函数,因此im

unfortunately detectResultRoi is a protected function so im a little stuck on how to find the correct size of the destination image.

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

Any help will be much appreciated, thanks!

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

====================================Edit==================================== The Src size can be calculated using the warpRoi function, which is public.

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

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

Above I defined my output size, then used warpRoi to find the Src size (or window size). Now you have the size you can cut a Mat of this size from the Src image (or resize it) and then use the warpBackward function without issue.

推荐答案

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

You can not access detectResultRoi directly, but you can inherit it and use as you want in your own class.

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

然后只需使用您的实现即可。

Then just use your implementation.

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

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

But I don't think that detectResultRoi will be usefull to detect the unprojected image size. Actually you need to do the opposite, as detectResultRoi calculates the spherical image region where the projected image will be.

您需要知道投影像素在球形图像中的位置。然后,您可以计算未投影图像的大小:取最右边&最左侧,最高&该区域(通常不是矩形)的所有边界像素中未投影像素的最低位置。可以通过 SphericalWarper :: projector_.mapBackward()获得该位置。 projector _ 成员也受保护,因此您需要使用与上述 detectResultRoi

You need to know where the projection pixels are in the spherical image. Then you can calculate the size of unprojected image: take difference between right-most & left-most, highest & lowest unprojected pixels' positions among all border pixels of that (usually not rectangular) region. This positions can be obtained with SphericalWarper::projector_.mapBackward(). projector_ member is protected too, so you need to use it the same way as described above for detectResultRoi.

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

This size is the same, as the size of the image you warp, if you want to warp backwards the result (or modified result, you can change pixel values, this does not change the mapping of pixel positions) of 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);

这篇关于OpenCV球形投影:变形和变形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆