Skip to content

Commit

Permalink
Expose camera intrinsic matrix API (#700)
Browse files Browse the repository at this point in the history
* Expose camera intrinsic matrix API

Signed-off-by: deepanshu <[email protected]>
Co-authored-by: Aditya Pande <[email protected]>
  • Loading branch information
deepanshubansal01 and adityapande-1995 authored Sep 7, 2022
1 parent 1694f3f commit 581aaab
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 0 deletions.
7 changes: 7 additions & 0 deletions include/gz/rendering/Camera.hh
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,13 @@ namespace gz
/// \return A pointer to the render window.
public: virtual RenderWindowPtr CreateRenderWindow() = 0;

/// \brief Get the camera intrinsic matrix.
/// This matrix is different than the matrix returned from
/// ProjectionMatrix() which is used by OpenGL internally.
/// The matrix returned contains the camera calibrated values.
/// \return intrinsic matrix
public: virtual math::Matrix3d CameraIntrinsicMatrix() const = 0;

/// \brief Get the projection matrix for this camera
/// \return Camera projection matrix
public: virtual math::Matrix4d ProjectionMatrix() const = 0;
Expand Down
23 changes: 23 additions & 0 deletions include/gz/rendering/base/BaseCamera.hh
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ namespace gz
public: virtual VisualPtr VisualAt(const gz::math::Vector2i
&_mousePos) override;

// Documentation inherited.
public: virtual math::Matrix3d CameraIntrinsicMatrix() const override;

// Documentation inherited.
public: virtual math::Matrix4d ProjectionMatrix() const override;

Expand Down Expand Up @@ -498,6 +501,26 @@ namespace gz
return RenderWindowPtr();
}

//////////////////////////////////////////////////
template <class T>
math::Matrix3d BaseCamera<T>::CameraIntrinsicMatrix() const
{
// Extracting the intrinsic matrix :
// https://ogrecave.github.io/ogre/api/13/class_ogre_1_1_math.html
const math::Matrix4d& projectionMat = this->ProjectionMatrix();

const double width = static_cast<double>(this->ImageWidth());
const double height = static_cast<double>(this->ImageHeight());
double fX = (projectionMat(0, 0) * width) / 2.0;
double fY = (projectionMat(1, 1) * height) / 2.0;
double cX = (-1.0 * width * (projectionMat(0, 2) - 1.0)) / 2.0;
double cY = height + (height * (projectionMat(1, 2) - 1)) / 2.0;

return math::Matrix3d(fX, 0, cX,
0, fY, cY,
0, 0, 1);
}

//////////////////////////////////////////////////
template <class T>
math::Matrix4d BaseCamera<T>::ProjectionMatrix() const
Expand Down
3 changes: 3 additions & 0 deletions ogre/include/gz/rendering/ogre/OgreCamera.hh
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ namespace gz
// Documentation inherited.
public: virtual RenderWindowPtr CreateRenderWindow() override;

// Documentation inherited.
public: virtual math::Matrix3d CameraIntrinsicMatrix() const override;

// Documentation inherited.
public: virtual math::Matrix4d ProjectionMatrix() const override;

Expand Down
6 changes: 6 additions & 0 deletions ogre/src/OgreCamera.cc
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,12 @@ RenderWindowPtr OgreCamera::CreateRenderWindow()
return base;
}

//////////////////////////////////////////////////
math::Matrix3d OgreCamera::CameraIntrinsicMatrix() const
{
return BaseCamera::CameraIntrinsicMatrix();
}

//////////////////////////////////////////////////
math::Matrix4d OgreCamera::ProjectionMatrix() const
{
Expand Down
3 changes: 3 additions & 0 deletions ogre2/include/gz/rendering/ogre2/Ogre2Camera.hh
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ namespace gz
// Documentation inherited.
public: virtual RenderWindowPtr CreateRenderWindow() override;

// Documentation inherited.
public: virtual math::Matrix3d CameraIntrinsicMatrix() const override;

// Documentation inherited.
public: virtual math::Matrix4d ProjectionMatrix() const override;

Expand Down
6 changes: 6 additions & 0 deletions ogre2/src/Ogre2Camera.cc
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,12 @@ RenderWindowPtr Ogre2Camera::CreateRenderWindow()
return RenderWindowPtr();
}

//////////////////////////////////////////////////
math::Matrix3d Ogre2Camera::CameraIntrinsicMatrix() const
{
return BaseCamera::CameraIntrinsicMatrix();
}

//////////////////////////////////////////////////
math::Matrix4d Ogre2Camera::ProjectionMatrix() const
{
Expand Down
57 changes: 57 additions & 0 deletions test/common_test/Camera_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -298,3 +298,60 @@ TEST_F(CameraTest, VisibilityMask)
// Clean up
engine->DestroyScene(scene);
}

TEST_F(CameraTest, IntrinsicMatrix)
{
ScenePtr scene = engine->CreateScene("scene");
ASSERT_NE(nullptr, scene);

CameraPtr camera = scene->CreateCamera();
EXPECT_TRUE(camera != nullptr);

unsigned int width = 320;
unsigned int height = 240;
double hfov = 1.047;

camera->SetImageHeight(height);
camera->SetImageWidth(width);
camera->SetHFOV(hfov);

double error = 1e-1;
EXPECT_EQ(camera->ImageHeight(), height);
EXPECT_EQ(camera->ImageWidth(), width);
EXPECT_NEAR(camera->HFOV().Radian(), hfov, error);

// Verify focal length and optical center from intrinsics
auto cameraIntrinsics = camera->CameraIntrinsicMatrix();
EXPECT_NEAR(cameraIntrinsics(0, 0), 277.1913, error);
EXPECT_NEAR(cameraIntrinsics(1, 1), 277.1913, error);
EXPECT_DOUBLE_EQ(cameraIntrinsics(0, 2), 160);
EXPECT_DOUBLE_EQ(cameraIntrinsics(1, 2), 120);
// Verify rest of the intrinsics
EXPECT_EQ(cameraIntrinsics(0, 1), 0);
EXPECT_EQ(cameraIntrinsics(1, 0), 0);
EXPECT_EQ(cameraIntrinsics(0, 1), 0);
EXPECT_EQ(cameraIntrinsics(2, 0), 0);
EXPECT_EQ(cameraIntrinsics(2, 1), 0);
EXPECT_EQ(cameraIntrinsics(2, 2), 1);

// Verify that changing camera size changes intrinsics
height = 1000;
width = 1000;
camera->SetImageHeight(height);
camera->SetImageWidth(width);
camera->SetHFOV(hfov);

EXPECT_EQ(camera->ImageHeight(), height);
EXPECT_EQ(camera->ImageWidth(), width);
EXPECT_NEAR(camera->HFOV().Radian(), hfov, error);

// Verify if intrinsics have changed
cameraIntrinsics = camera->CameraIntrinsicMatrix();
EXPECT_NEAR(cameraIntrinsics(0, 0), 866.223, error);
EXPECT_NEAR(cameraIntrinsics(1, 1), 866.223, error);
EXPECT_DOUBLE_EQ(cameraIntrinsics(0, 2), 500);
EXPECT_DOUBLE_EQ(cameraIntrinsics(1, 2), 500);

// Clean up
engine->DestroyScene(scene);
}

0 comments on commit 581aaab

Please sign in to comment.