Added spherical and cylindrical warpers, which work in the portrait mode -- when poles are located NOT at (0, -1, 0) and (0, 1, 0) points, BUT at (1, 0, 0) and (-1, 0, 0) points.
This commit is contained in:
@@ -304,6 +304,45 @@ private:
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
struct SphericalPortraitProjector : ProjectorBase
|
||||||
|
{
|
||||||
|
void mapForward(float x, float y, float &u, float &v);
|
||||||
|
void mapBackward(float u, float v, float &x, float &y);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Projects image onto unit sphere with origin at (0, 0, 0).
|
||||||
|
// Poles are located NOT at (0, -1, 0) and (0, 1, 0) points, BUT at (1, 0, 0) and (-1, 0, 0) points.
|
||||||
|
class SphericalPortraitWarper : public RotationWarperBase<SphericalPortraitProjector>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SphericalPortraitWarper(float scale) { projector_.scale = scale; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CylindricalPortraitProjector : ProjectorBase
|
||||||
|
{
|
||||||
|
void mapForward(float x, float y, float &u, float &v);
|
||||||
|
void mapBackward(float u, float v, float &x, float &y);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class CylindricalPortraitWarper : public RotationWarperBase<CylindricalPortraitProjector>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CylindricalPortraitWarper(float scale) { projector_.scale = scale; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
|
||||||
|
{
|
||||||
|
RotationWarperBase<CylindricalPortraitProjector>::detectResultRoiByBorder(src_size, dst_tl, dst_br);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace cv
|
} // namespace cv
|
||||||
|
|
||||||
|
|||||||
@@ -298,6 +298,97 @@ void CylindricalProjector::mapBackward(float u, float v, float &x, float &y)
|
|||||||
else x = y = -1;
|
else x = y = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void SphericalPortraitProjector::mapForward(float x, float y, float &u0, float &v0)
|
||||||
|
{
|
||||||
|
float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
|
||||||
|
float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
|
||||||
|
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
|
||||||
|
|
||||||
|
float x_ = y0_;
|
||||||
|
float y_ = x0_;
|
||||||
|
float u, v;
|
||||||
|
|
||||||
|
u = scale * atan2f(x_, z_);
|
||||||
|
v = scale * (static_cast<float>(CV_PI) - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_)));
|
||||||
|
|
||||||
|
u0 = -u;//v;
|
||||||
|
v0 = v;//u;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline
|
||||||
|
void SphericalPortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
|
||||||
|
{
|
||||||
|
float u, v;
|
||||||
|
u = -u0;//v0;
|
||||||
|
v = v0;//u0;
|
||||||
|
|
||||||
|
u /= scale;
|
||||||
|
v /= scale;
|
||||||
|
|
||||||
|
float sinv = sinf(static_cast<float>(CV_PI) - v);
|
||||||
|
float x0_ = sinv * sinf(u);
|
||||||
|
float y0_ = cosf(static_cast<float>(CV_PI) - v);
|
||||||
|
float z_ = sinv * cosf(u);
|
||||||
|
|
||||||
|
float x_ = y0_;
|
||||||
|
float y_ = x0_;
|
||||||
|
|
||||||
|
float z;
|
||||||
|
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
|
||||||
|
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
|
||||||
|
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
|
||||||
|
|
||||||
|
if (z > 0) { x /= z; y /= z; }
|
||||||
|
else x = y = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void CylindricalPortraitProjector::mapForward(float x, float y, float &u0, float &v0)
|
||||||
|
{
|
||||||
|
float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
|
||||||
|
float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
|
||||||
|
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
|
||||||
|
|
||||||
|
float x_ = y0_;
|
||||||
|
float y_ = x0_;
|
||||||
|
float u, v;
|
||||||
|
|
||||||
|
u = scale * atan2f(x_, z_);
|
||||||
|
v = scale * y_ / sqrtf(x_ * x_ + z_ * z_);
|
||||||
|
|
||||||
|
u0 = -u;//v;
|
||||||
|
v0 = v;//u;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline
|
||||||
|
void CylindricalPortraitProjector::mapBackward(float u0, float v0, float &x, float &y)
|
||||||
|
{
|
||||||
|
float u, v;
|
||||||
|
u = -u0;//v0;
|
||||||
|
v = v0;//u0;
|
||||||
|
|
||||||
|
u /= scale;
|
||||||
|
v /= scale;
|
||||||
|
|
||||||
|
float x0_ = sinf(u);
|
||||||
|
float y0_ = v;
|
||||||
|
float z_ = cosf(u);
|
||||||
|
|
||||||
|
float x_ = y0_;
|
||||||
|
float y_ = x0_;
|
||||||
|
|
||||||
|
float z;
|
||||||
|
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
|
||||||
|
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
|
||||||
|
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
|
||||||
|
|
||||||
|
if (z > 0) { x /= z; y /= z; }
|
||||||
|
else x = y = -1;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace cv
|
} // namespace cv
|
||||||
|
|
||||||
|
|||||||
@@ -296,5 +296,48 @@ Point CylindricalWarperGpu::warp(const gpu::GpuMat &src, const Mat &K, const Mat
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void SphericalPortraitWarper::detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
|
||||||
|
{
|
||||||
|
detectResultRoiByBorder(src_size, dst_tl, dst_br);
|
||||||
|
|
||||||
|
float tl_uf = static_cast<float>(dst_tl.x);
|
||||||
|
float tl_vf = static_cast<float>(dst_tl.y);
|
||||||
|
float br_uf = static_cast<float>(dst_br.x);
|
||||||
|
float br_vf = static_cast<float>(dst_br.y);
|
||||||
|
|
||||||
|
float x = projector_.rinv[0];
|
||||||
|
float y = projector_.rinv[3];
|
||||||
|
float z = projector_.rinv[6];
|
||||||
|
if (y > 0.f)
|
||||||
|
{
|
||||||
|
float x_ = (projector_.k[0] * x + projector_.k[1] * y) / z + projector_.k[2];
|
||||||
|
float y_ = projector_.k[4] * y / z + projector_.k[5];
|
||||||
|
if (x_ > 0.f && x_ < src_size.width && y_ > 0.f && y_ < src_size.height)
|
||||||
|
{
|
||||||
|
tl_uf = min(tl_uf, 0.f); tl_vf = min(tl_vf, static_cast<float>(CV_PI * projector_.scale));
|
||||||
|
br_uf = max(br_uf, 0.f); br_vf = max(br_vf, static_cast<float>(CV_PI * projector_.scale));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
x = projector_.rinv[0];
|
||||||
|
y = -projector_.rinv[3];
|
||||||
|
z = projector_.rinv[6];
|
||||||
|
if (y > 0.f)
|
||||||
|
{
|
||||||
|
float x_ = (projector_.k[0] * x + projector_.k[1] * y) / z + projector_.k[2];
|
||||||
|
float y_ = projector_.k[4] * y / z + projector_.k[5];
|
||||||
|
if (x_ > 0.f && x_ < src_size.width && y_ > 0.f && y_ < src_size.height)
|
||||||
|
{
|
||||||
|
tl_uf = min(tl_uf, 0.f); tl_vf = min(tl_vf, static_cast<float>(0));
|
||||||
|
br_uf = max(br_uf, 0.f); br_vf = max(br_vf, static_cast<float>(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dst_tl.x = static_cast<int>(tl_uf);
|
||||||
|
dst_tl.y = static_cast<int>(tl_vf);
|
||||||
|
dst_br.x = static_cast<int>(br_uf);
|
||||||
|
dst_br.y = static_cast<int>(br_vf);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace cv
|
} // namespace cv
|
||||||
|
|||||||
Reference in New Issue
Block a user