MCPcopy Create free account
hub / github.com/colmap/colmap / BuildSphericalCameraModel

Function BuildSphericalCameraModel

src/colmap/ui/model_viewer_widget.cc:96–220  ·  view source on GitHub ↗

Builds a translucent + wireframe sphere centered at `center` with the given `radius`. Used to visualize omnidirectional (e.g. EQUIRECTANGULAR) cameras, which observe the full sphere and have no pinhole frustum. The triangle mesh provides the translucent fill and also makes the camera selectable (picking is done against triangles); the lines form the wireframe. The sphere is oriented by `world_from

Source from the content-addressed store, hash-verified

94// along the camera's forward axis (azimuth 0, elevation 0) marks the image
95// center.
96void BuildSphericalCameraModel(
97 const Eigen::Vector3f& center,
98 const float radius,
99 const Eigen::Matrix3f& world_from_cam_rot,
100 const RGBAColor& plane_color,
101 const RGBAColor& frame_color,
102 std::vector<TrianglePainter::Data>* triangle_data,
103 std::vector<LinePainter::Data>* line_data,
104 std::vector<LinePainter::Data>* axis_line_data) {
105 constexpr int kNumStacks = 6; // Latitude (elevation) divisions.
106 constexpr int kNumSlices = 12; // Longitude (azimuth) divisions.
107
108 // Sphere point at the given elevation/azimuth grid index, using the same
109 // equirectangular parametrization as the EQUIRECTANGULAR camera model so that
110 // the wireframe aligns with the image: stack 0..N maps elevation +pi/2..-pi/2
111 // (image top to bottom), slice 0..N maps azimuth -pi..pi (image left to
112 // right). The camera-frame bearing is rotated into world space.
113 const auto sphere_point = [&](const int stack,
114 const int slice) -> Eigen::Vector3f {
115 const double phi =
116 EIGEN_PI * (0.5 - static_cast<double>(stack) / kNumStacks);
117 const double theta =
118 2.0 * EIGEN_PI * (static_cast<double>(slice) / kNumSlices - 0.5);
119 const double cos_phi = std::cos(phi);
120 const Eigen::Vector3f ray_in_cam(
121 static_cast<float>(cos_phi * std::sin(theta)),
122 static_cast<float>(-std::sin(phi)),
123 static_cast<float>(cos_phi * std::cos(theta)));
124 return center + radius * (world_from_cam_rot * ray_in_cam);
125 };
126
127 if (triangle_data != nullptr) {
128 const auto add_triangle = [&](const Eigen::Vector3f& p1,
129 const Eigen::Vector3f& p2,
130 const Eigen::Vector3f& p3) {
131 triangle_data->emplace_back(PointPainter::Data(p1(0),
132 p1(1),
133 p1(2),
134 plane_color(0),
135 plane_color(1),
136 plane_color(2),
137 plane_color(3)),
138 PointPainter::Data(p2(0),
139 p2(1),
140 p2(2),
141 plane_color(0),
142 plane_color(1),
143 plane_color(2),
144 plane_color(3)),
145 PointPainter::Data(p3(0),
146 p3(1),
147 p3(2),
148 plane_color(0),
149 plane_color(1),
150 plane_color(2),
151 plane_color(3)));
152 };
153 for (int i = 0; i < kNumStacks; ++i) {

Callers 1

BuildCameraModelFunction · 0.85

Calls 1

DataClass · 0.70

Tested by

no test coverage detected