Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,20 @@ Never modify the stubs. They are autogenerated, and your changes will just be ov

Keep comments minimal, only add comments when the code needs explaining why it's doing something.

# Control flow

Prefer early returns or early continues over nested conditionals when it keeps
the main path flatter and easier to read. Do not contort code just to avoid
nesting, but avoid pyramid-shaped control flow.

Do not use ternary expressions. Use explicit `if`/`else` statements instead.

# Frame transforms

Name pose/transform variables exactly with the `A_from_B` convention, where the
transform maps coordinates from frame B into frame A. Avoid vague names like
`pose` for transforms unless the code is generic over frames.

# Plots

Follow the color scheme of the existing plots in the plots.py file.
Expand Down
8 changes: 4 additions & 4 deletions cpp_src/calibrate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ py::dict calibrate_opencv(

py::dict get_matching_spline_distortion_model(
std::vector<double>& opencv_distortion_params,
PinholeSplinedConfig& model_config,
PinholeSplinedOptimizationConfig& model_config,
double image_bound_x,
double image_bound_y
);

py::dict fine_tune_pinhole_splined(
PinholeSplinedConfig& model_config,
PinholeSplinedOptimizationConfig& model_config,
PinholeSplinedIntrinsicsParameters& intrinsics_parameters,
std::vector<Vec6<double>>& cameras_from_target,
std::vector<Vec3<double>>& target_points,
Expand All @@ -42,9 +42,9 @@ py::dict fine_tune_pinhole_splined(
);

py::array_t<double> normalize_pinhole_splined_points(
PinholeSplinedConfig& config,
PinholeSplinedModelDefinition& config,
PinholeSplinedIntrinsicsParameters& intrinsics,
py::array_t<double, py::array::c_style | py::array::forcecast> pixel_coords
);

} // namespace lensboy
} // namespace lensboy
9 changes: 6 additions & 3 deletions cpp_src/cameramodels.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@
namespace py = pybind11;
namespace lensboy {

struct PinholeSplinedConfig {
struct PinholeSplinedModelDefinition {
uint32_t image_width;
uint32_t image_height;
double fov_deg_x;
double fov_deg_y;
uint32_t num_knots_x;
uint32_t num_knots_y;
};

struct PinholeSplinedOptimizationConfig : PinholeSplinedModelDefinition {
double smoothness_lambda;
};

Expand Down Expand Up @@ -313,7 +316,7 @@ struct SplineMap {
double y_scale = 0.0;

explicit SplineMap(
const PinholeSplinedConfig& cfg
const PinholeSplinedModelDefinition& cfg
) {
this->Nx = static_cast<int>(cfg.num_knots_x);
this->Ny = static_cast<int>(cfg.num_knots_y);
Expand Down Expand Up @@ -406,7 +409,7 @@ struct SplineMap {

template <typename T>
void project_pinhole_splined(
PinholeSplinedConfig* config,
PinholeSplinedModelDefinition* config,
const T* const pinhole_parameters, // fx, fy, cx, cy
const T* const dx_grid,
const T* const dy_grid,
Expand Down
2 changes: 1 addition & 1 deletion cpp_src/lut_max_cell_error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -844,7 +844,7 @@ inline void project_pinhole_splined_n(
}

py::array_t<double> max_cell_errors_pinhole_splined(
PinholeSplinedConfig& config,
PinholeSplinedModelDefinition& config,
PinholeSplinedIntrinsicsParameters& intrinsics,
py::array_t<double, py::array::c_style | py::array::forcecast> lut_xy_grid,
int image_width,
Expand Down
2 changes: 1 addition & 1 deletion cpp_src/lut_max_cell_error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace py = pybind11;
// interpolation_mode: 0=nearest, 1=bilinear, 2=bicubic.

py::array_t<double> max_cell_errors_pinhole_splined(
PinholeSplinedConfig& config,
PinholeSplinedModelDefinition& config,
PinholeSplinedIntrinsicsParameters& intrinsics,
py::array_t<double, py::array::c_style | py::array::forcecast> lut_xy_grid,
int image_width,
Expand Down
111 changes: 81 additions & 30 deletions cpp_src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,59 +23,110 @@ PYBIND11_MODULE(
) {
m.doc() = "lensboy for camera calibration";
spdlog::flush_on(spdlog::level::trace);
py::class_<lensboy::PinholeSplinedConfig>(m, "PinholeSplinedConfig")
py::class_<lensboy::PinholeSplinedModelDefinition>(
m,
"PinholeSplinedModelDefinition"
)
.def(
py::init<
uint32_t,
uint32_t,
double,
double,
uint32_t,
uint32_t,
double>(),
py::init<uint32_t, uint32_t, double, double, uint32_t, uint32_t>(),
py::arg("image_width"),
py::arg("image_height"),
py::arg("fov_deg_x"),
py::arg("fov_deg_y"),
py::arg("num_knots_x"),
py::arg("num_knots_y"),
py::arg("smoothness_lambda")
py::arg("num_knots_y")
)
.def_readwrite(
"image_width",
&lensboy::PinholeSplinedConfig::image_width
&lensboy::PinholeSplinedModelDefinition::image_width
)
.def_readwrite(
"image_height",
&lensboy::PinholeSplinedConfig::image_height
&lensboy::PinholeSplinedModelDefinition::image_height
)
.def_readwrite(
"fov_deg_x",
&lensboy::PinholeSplinedModelDefinition::fov_deg_x
)
.def_readwrite(
"fov_deg_y",
&lensboy::PinholeSplinedModelDefinition::fov_deg_y
)
.def_readwrite("fov_deg_x", &lensboy::PinholeSplinedConfig::fov_deg_x)
.def_readwrite("fov_deg_y", &lensboy::PinholeSplinedConfig::fov_deg_y)

.def_readwrite(
"num_knots_x",
&lensboy::PinholeSplinedConfig::num_knots_x
&lensboy::PinholeSplinedModelDefinition::num_knots_x
)
.def_readwrite(
"num_knots_y",
&lensboy::PinholeSplinedConfig::num_knots_y
&lensboy::PinholeSplinedModelDefinition::num_knots_y
)
.def(
"__repr__",
[](const lensboy::PinholeSplinedModelDefinition& self) {
std::ostringstream oss;
oss << "PinholeSplinedModelDefinition("
<< "image_width=" << self.image_width
<< ", image_height=" << self.image_height
<< ", fov_deg_x=" << self.fov_deg_x
<< ", fov_deg_y=" << self.fov_deg_y
<< ", num_knots_x=" << self.num_knots_x
<< ", num_knots_y=" << self.num_knots_y << ")";
return oss.str();
}
);

py::class_<
lensboy::PinholeSplinedOptimizationConfig,
lensboy::PinholeSplinedModelDefinition>(
m,
"PinholeSplinedOptimizationConfig"
)
.def(
py::init([](uint32_t image_width,
uint32_t image_height,
double fov_deg_x,
double fov_deg_y,
uint32_t num_knots_x,
uint32_t num_knots_y,
double smoothness_lambda) {
lensboy::PinholeSplinedOptimizationConfig config;
config.image_width = image_width;
config.image_height = image_height;
config.fov_deg_x = fov_deg_x;
config.fov_deg_y = fov_deg_y;
config.num_knots_x = num_knots_x;
config.num_knots_y = num_knots_y;
config.smoothness_lambda = smoothness_lambda;
return config;
}),
py::arg("image_width"),
py::arg("image_height"),
py::arg("fov_deg_x"),
py::arg("fov_deg_y"),
py::arg("num_knots_x"),
py::arg("num_knots_y"),
py::arg("smoothness_lambda")
)
.def_readwrite(
"smoothness_lambda",
&lensboy::PinholeSplinedConfig::smoothness_lambda
&lensboy::PinholeSplinedOptimizationConfig::smoothness_lambda
)
.def("__repr__", [](const lensboy::PinholeSplinedConfig& self) {
std::ostringstream oss;
oss << "PinholeSplinedConfig("
<< "image_width=" << self.image_width
<< ", image_height=" << self.image_height
<< ", fov_deg_x=" << self.fov_deg_x
<< ", fov_deg_y=" << self.fov_deg_y
<< ", num_knots_x=" << self.num_knots_x
<< ", num_knots_y=" << self.num_knots_y
<< ", smoothness_lambda=" << self.smoothness_lambda << ")";
return oss.str();
});
.def(
"__repr__",
[](const lensboy::PinholeSplinedOptimizationConfig& self) {
std::ostringstream oss;
oss << "PinholeSplinedOptimizationConfig("
<< "image_width=" << self.image_width
<< ", image_height=" << self.image_height
<< ", fov_deg_x=" << self.fov_deg_x
<< ", fov_deg_y=" << self.fov_deg_y
<< ", num_knots_x=" << self.num_knots_x
<< ", num_knots_y=" << self.num_knots_y
<< ", smoothness_lambda=" << self.smoothness_lambda << ")";
return oss.str();
}
);

py::class_<lensboy::PinholeSplinedIntrinsicsParameters>(
m,
Expand Down
4 changes: 2 additions & 2 deletions cpp_src/matching_spline_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ struct DistortionError {

py::dict get_matching_spline_distortion_model(
std::vector<double>& opencv_distortion_params,
PinholeSplinedConfig& model_config,
PinholeSplinedOptimizationConfig& model_config,
double image_bound_x,
double image_bound_y
) {
Expand Down Expand Up @@ -393,4 +393,4 @@ py::dict get_matching_spline_distortion_model(
return out;
}

} // namespace lensboy
} // namespace lensboy
2 changes: 1 addition & 1 deletion cpp_src/normalize_pinhole_splined.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ static Vec2<double> normalize_single_point(
}

py::array_t<double> normalize_pinhole_splined_points(
PinholeSplinedConfig& config,
PinholeSplinedModelDefinition& config,
PinholeSplinedIntrinsicsParameters& intrinsics,
py::array_t<double, py::array::c_style | py::array::forcecast> pixel_coords
) {
Expand Down
6 changes: 3 additions & 3 deletions cpp_src/pinhole_splined_fine_tune.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ static bool any_cell_changed(

static inline void BuildProblem(
ceres::Problem& problem,
const PinholeSplinedConfig& cfg,
const PinholeSplinedOptimizationConfig& cfg,
const SplineMap& map,
const double* pinhole_params,
double* dxp,
Expand Down Expand Up @@ -412,7 +412,7 @@ static inline void BuildProblem(
}

py::dict fine_tune_pinhole_splined(
lensboy::PinholeSplinedConfig& model_config,
lensboy::PinholeSplinedOptimizationConfig& model_config,
lensboy::PinholeSplinedIntrinsicsParameters& intrinsics_parameters,
std::vector<Vec6<double>>& cameras_from_target,
std::vector<Vec3<double>>& target_points,
Expand Down Expand Up @@ -546,4 +546,4 @@ py::dict fine_tune_pinhole_splined(
return out;
}

} // namespace lensboy
} // namespace lensboy
4 changes: 2 additions & 2 deletions cpp_src/python_camera_functions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace lensboy {

static py::array_t<double> project_pinhole_splined_pywrapper(
lensboy::PinholeSplinedConfig& model_config,
lensboy::PinholeSplinedModelDefinition& model_config,
lensboy::PinholeSplinedIntrinsicsParameters& intrinsics,
py::array_t<double, py::array::c_style | py::array::forcecast>
points_in_camera
Expand Down Expand Up @@ -71,7 +71,7 @@ static py::array_t<double> project_pinhole_splined_pywrapper(
}

static py::tuple make_undistortion_maps_pinhole_splined(
lensboy::PinholeSplinedConfig& model_config,
lensboy::PinholeSplinedModelDefinition& model_config,
lensboy::PinholeSplinedIntrinsicsParameters& intrinsics,
py::array_t<double, py::array::c_style | py::array::forcecast>
pinhole_parameters,
Expand Down
6 changes: 3 additions & 3 deletions cpp_src/seeded_normalize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ template <typename T>
static inline void forward_splined(
const T& normalized_x,
const T& normalized_y,
PinholeSplinedConfig* config,
PinholeSplinedModelDefinition* config,
const T* pinhole_params,
const T* dx_grid,
const T* dy_grid,
Expand Down Expand Up @@ -414,7 +414,7 @@ struct SplineConstants {
double fx, fy, cx, cy;

explicit SplineConstants(
PinholeSplinedConfig* config,
PinholeSplinedModelDefinition* config,
const double* pinhole_params
)
: num_knots_x((int)config->num_knots_x),
Expand Down Expand Up @@ -789,7 +789,7 @@ py::array_t<double> seeded_normalize_splined(
int seed_width,
int seed_height,
py::array_t<double, py::array::c_style | py::array::forcecast> query_pixels,
PinholeSplinedConfig& config,
PinholeSplinedModelDefinition& config,
PinholeSplinedIntrinsicsParameters& params
) {
auto seed_pixels_buffer = seed_pixels.request();
Expand Down
2 changes: 1 addition & 1 deletion cpp_src/seeded_normalize.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ py::array_t<double> seeded_normalize_splined(
int seed_width,
int seed_height,
py::array_t<double, py::array::c_style | py::array::forcecast> query_pixels,
PinholeSplinedConfig& config,
PinholeSplinedModelDefinition& config,
PinholeSplinedIntrinsicsParameters& params
);

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ build-backend = "scikit_build_core.build"

[project]
name = "lensboy"
version = "3.1.0"
version = "4.0.0"
description = "lensboy for camera calibrations"
authors = [{ name = "Robert Leo", email = "robert.leo.jonsson@gmail.com" }]

Expand Down
10 changes: 8 additions & 2 deletions src/lensboy/_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ def _set_cpp_log_level(level: str) -> None:


def _clamp(v: float, lo: float, hi: float) -> float:
return lo if v < lo else hi if v > hi else v
if v < lo:
return lo
if v > hi:
return hi
return v


def _fmt_int(n: int) -> str:
Expand Down Expand Up @@ -117,7 +121,9 @@ def set(self, n: int) -> None:
return
if n < 0:
raise ValueError("n must be >= 0")
self.n = n if self.total <= 0 else min(n, self.total)
self.n = n
if self.total > 0:
self.n = min(n, self.total)
self.draw(force=True)

def draw(self, *, force: bool = False) -> None:
Expand Down
Loading
Loading