Skip to content

WorldToCameraImageCoords

This document introduces two overloaded functions that project 3D world points into 2D camera image coordinates using a pinhole camera model.


Function Signatures

1. Explicit Look‑At Projection

Eigen::MatrixX2d WorldToCameraImageCoords(
    const Eigen::MatrixX3d& targetVertices,
    const Eigen::RowVector3d& cameraDirPoint,
    const Eigen::RowVector3d& cameraPosition,
    double FL
);

2. Centroid‑Based Projection

Eigen::MatrixX2d WorldToCameraImageCoords(
    const Eigen::MatrixX3d& targetVertices,
    const Eigen::RowVector3d& cameraPosition,
    double FL
);


Parameters

  • targetVertices: Eigen::MatrixX3d, where each row is a 3D point to project.
  • cameraDirPoint: Eigen::RowVector3d, specifying the point the camera looks at (only for overload 1).
  • cameraPosition: Eigen::RowVector3d, representing the camera’s position in world coordinates.
  • FL: double focal length of the pinhole camera.

Return Value

  • Eigen::MatrixX2d: A matrix of size (N×2), where each row is the projected 2D image coordinate (u, v) corresponding to an input vertex.

Example Usage

1. Prepare Input Data

Define a cuboid using eight corner points in world coordinates. Also specify the camera’s position, look‑at point, and focal length:

Eigen::Matrix<double,8,3> testTarget;
testTarget << 748793.66839939367, 2565000.6052587116, 48.909999999999997,
    748791.82177844818, 2565003.9931349289, 48.909999999999997,
    748795.20965466544, 2565005.8397558741, 48.909999999999997,
    748797.05627561093, 2565002.4518796569, 48.909999999999997,
    748793.66839939367, 2565000.6052587116, 50.909999999999997,
    748791.82177844818, 2565003.9931349289, 50.909999999999997,
    748795.20965466544, 2565005.8397558741, 50.909999999999997,
    748797.05627561093, 2565002.4518796569, 50.909999999999997;

Eigen::RowVector3d cameraPosition(748780.10705481586, 2565024.6238759784, 57.51);
Eigen::RowVector3d cameraDirPoint(748794.43902702956, 2565003.2225072929, 49.909999999999997);
double FL = 32.0;

2. Perform 3D-to-2D Projection

Eigen::Matrix<double, 8, 2> imagePoints = WorldToCameraImageCoords(testTarget, cameraDirPoint, cameraPosition, FL);

3. Result

The projected 2D image coordinates are visualized below:

The red rectangle in the image represents the assumed CMOS sensor area of the camera, with a physical size of 6.4 mm × 4.8 mm.

Complete Implementation

#include "LiteGeometry.h"

int main() {

    Eigen::Matrix<double,8,3> testTarget;
    testTarget << 748793.66839939367, 2565000.6052587116, 48.909999999999997,
        748791.82177844818, 2565003.9931349289, 48.909999999999997,
        748795.20965466544, 2565005.8397558741, 48.909999999999997,
        748797.05627561093, 2565002.4518796569, 48.909999999999997,
        748793.66839939367, 2565000.6052587116, 50.909999999999997,
        748791.82177844818, 2565003.9931349289, 50.909999999999997,
        748795.20965466544, 2565005.8397558741, 50.909999999999997,
        748797.05627561093, 2565002.4518796569, 50.909999999999997;

    Eigen::RowVector3d cameraPosition(748780.10705481586, 2565024.6238759784, 57.51);
    Eigen::RowVector3d cameraDirPoint(748794.43902702956, 2565003.2225072929, 49.909999999999997);
    double FL = 32.0;
    std::cout << "Camera Position: " << cameraPosition.format(Eigen::FullPrecision) << "\n";
    std::cout << "Camera Look-at Point: " << cameraDirPoint.format(Eigen::FullPrecision) << "\n";
    std::cout << "Focal Length: " << FL << "\n";

    Eigen::Matrix<double, 8, 2> imagePoints = WorldToCameraImageCoords(testTarget, cameraDirPoint, cameraPosition, FL);
    std::cout << "\nProjected Image Coordinates:\n";
    std::cout << imagePoints.format(Eigen::FullPrecision) << "\n";

    return 0;
}