diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 059a627..496211d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,7 +21,6 @@ jobs: arch-name: linuxx86-64 - os: ubuntu-24.04-arm arch-name: linuxarm64 - extra-flags: -DARM64_BUILD=ON - os: windows-latest arch-name: windowsx86-64 extra-flags: -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_C_COMPILER=clang-cl diff --git a/CMakeLists.txt b/CMakeLists.txt index 9504c71..685e1d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,7 +89,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") if(NOT APPLE) set(BLA_VENDOR OpenBLAS) - if(ARM64_BUILD) + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") # ---------------------------------------------------------------- # Variables for subdirectory builds must be set in the parent cache # BEFORE FetchContent_MakeAvailable. @@ -117,10 +117,6 @@ if(NOT APPLE) set(DYNAMIC_ARCH OFF CACHE BOOL "" FORCE) set(DYNAMIC_OLDER OFF CACHE BOOL "" FORCE) - # Lock the compiler to ARMv8-A baseline. This prevents the compiler - # from emitting SVE intrinsics even if OpenBLAS assembly kernels - # happen to include SVE .S files guarded by preprocessor. - set(CMAKE_C_FLAGS_OPENBLAS "-march=armv8-a" CACHE STRING "" FORCE) set(COMMON_OPT "-march=armv8-a" CACHE STRING "" FORCE) # Explicitly set ARCH so OpenBLAS does not re-detect it. diff --git a/src/mrcal_wrapper.cpp b/src/mrcal_wrapper.cpp index 8c84304..0037e22 100644 --- a/src/mrcal_wrapper.cpp +++ b/src/mrcal_wrapper.cpp @@ -19,10 +19,9 @@ #include #include -#include #include -#include #include +#include #include #include #include @@ -167,9 +166,6 @@ static std::unique_ptr mrcal_calibrate( // in int *c_imagersizes = imagersize; - auto point_min_range = -1.0, point_max_range = -1.0; - mrcal_problem_constants_t problem_constants = { - .point_min_range = point_min_range, .point_max_range = point_max_range}; int verbose = 0; auto stats = mrcal_optimize( @@ -179,9 +175,8 @@ static std::unique_ptr mrcal_calibrate( c_observations_board, c_observations_point, Nobservations_board, Nobservations_point, NULL, -1, // We don't use these, so pass nulls c_observations_board_pool, c_observations_point_pool, &mrcal_lensmodel, - c_imagersizes, problem_selections, &problem_constants, - calibration_object_spacing, calibration_object_width_n, - calibration_object_height_n, verbose, false); + c_imagersizes, problem_selections, NULL, calibration_object_spacing, + calibration_object_width_n, calibration_object_height_n, verbose, false); std::vector residuals = {c_x_final, c_x_final + Nmeasurements}; return std::make_unique( @@ -283,7 +278,7 @@ mrcal_pose_t getSeedPose(const mrcal_point3_t *c_observations_board_pool, double cy = (imagerSize.height / 2.0) - 0.5; vector objectPoints; - vector imagePoints; + vector mrcal_imagepts; // Fill in object/image points for (int i = 0; i < boardSize.height; i++) { @@ -291,26 +286,23 @@ mrcal_pose_t getSeedPose(const mrcal_point3_t *c_observations_board_pool, auto &corner = c_observations_board_pool[i * boardSize.width + j]; // weight<0 means ignored -- filter these out if (corner.z >= 0) { - imagePoints.emplace_back(corner.x, corner.y); - objectPoints.push_back(Point3f(j * squareSize, i * squareSize, 0)); + mrcal_imagepts.emplace_back( + mrcal_point2_t{.x = corner.x, .y = corner.y}); + objectPoints.emplace_back(j * squareSize, i * squareSize, 0); } } } + vector imagePoints(mrcal_imagepts.size()); { // convert from stereographic to pinhole to match python - std::vector mrcal_imagepts(imagePoints.size()); - std::transform( - imagePoints.begin(), imagePoints.end(), mrcal_imagepts.begin(), - [](const auto &pt) { return mrcal_point2_t{.x = pt.x, .y = pt.y}; }); - mrcal_lensmodel_t model{.type = MRCAL_LENSMODEL_STEREOGRAPHIC}; - std::vector out(imagePoints.size()); + std::vector out(mrcal_imagepts.size()); const double intrinsics[] = {fx, fy, cx, cy}; bool ret = mrcal_unproject(out.data(), mrcal_imagepts.data(), mrcal_imagepts.size(), &model, intrinsics); if (!ret) { - std::cerr << "couldn't unproject!" << std::endl; + BARF("couldn't unproject!"); } model = {.type = MRCAL_LENSMODEL_PINHOLE}; mrcal_project(mrcal_imagepts.data(), NULL, NULL, out.data(), out.size(), @@ -322,23 +314,18 @@ mrcal_pose_t getSeedPose(const mrcal_point3_t *c_observations_board_pool, } // Initial guess at intrinsics - Mat cameraMatrix = (Mat_(3, 3) << fx, 0, cx, 0, fy, cy, 0, 0, 1); + Mat cameraMatrix{{3, 3}, {fx, 0.0, cx, 0.0, fy, cy, 0.0, 0.0, 1.0}}; Mat distCoeffs = Mat(4, 1, CV_64FC1, Scalar(0)); Mat_ rvec, tvec; - vector objectPoints3; - for (auto a : objectPoints) - objectPoints3.push_back(Point3f(a.x, a.y, 0)); - solvePnP(objectPoints3, imagePoints, cameraMatrix, distCoeffs, rvec, tvec, + solvePnP(objectPoints, imagePoints, cameraMatrix, distCoeffs, rvec, tvec, false, SOLVEPNP_ITERATIVE); return mrcal_pose_t{.r = {.x = rvec(0), .y = rvec(1), .z = rvec(2)}, .t = {.x = tvec(0), .y = tvec(1), .z = tvec(2)}}; } -mrcal_result::~mrcal_result() { return; } - // Code taken from mrcal, license: // Copyright (c) 2017-2023 California Institute of Technology ("Caltech"). U.S. // Government sponsorship acknowledged. All rights reserved. @@ -367,7 +354,7 @@ std::unique_ptr mrcal_main( std::vector intrinsics = {focal_length_guess, focal_length_guess, cx, cy}; - std::cout << "Initial solve (geometry only)" << std::endl; + std::printf("Initial solve (geometry only)\n"); mrcal_problem_selections_t options = construct_problem_selections( {.do_optimize_intrinsics_core = false, @@ -389,9 +376,8 @@ std::unique_ptr mrcal_main( } { - std::cout - << "Initial solve (geometry and LENSMODEL_STEREOGRAPHIC core only)" - << std::endl; + std::printf( + "Initial solve (geometry and LENSMODEL_STEREOGRAPHIC core only)\n"); mrcal_problem_selections_t options = construct_problem_selections( {.do_optimize_intrinsics_core = true, .do_optimize_intrinsics_distortions = true, @@ -443,9 +429,8 @@ std::unique_ptr mrcal_main( std::copy(seedDistortions.begin(), seedDistortions.end(), intrinsics.begin() + result->intrinsics.size()); - std::cout - << "Optimizing everything except board warp from seeded intrinsics" - << std::endl; + std::printf( + "Optimizing everything except board warp from seeded intrinsics\n"); mrcal_problem_selections_t options = construct_problem_selections( {.do_optimize_intrinsics_core = true, .do_optimize_intrinsics_distortions = true, @@ -462,7 +447,7 @@ std::unique_ptr mrcal_main( } { - std::cout << "Final, full solve" << std::endl; + std::printf("Final, full solve\n"); mrcal_problem_selections_t options = construct_problem_selections( {.do_optimize_intrinsics_core = true, .do_optimize_intrinsics_distortions = true, @@ -515,20 +500,20 @@ bool undistort_mrcal(cv::Mat *dst, const cv::Mat *cameraMat, mrcal_lensmodel.LENSMODEL_SPLINED_STEREOGRAPHIC__config.Ny = Ny; break; default: - std::cerr << "Unknown lensmodel\n"; + BARF("Unknown lensmodel\n"); return false; } - if (!(dst->cols == 2)) { - std::cerr << "Bad input array size\n"; + if (dst->cols != 2) { + BARF("Bad input array size\n"); return false; } - if (!(dst->type() == CV_64FC2)) { - std::cerr << "Bad input type -- need CV_64F\n"; + if (dst->type() != CV_64FC2) { + BARF("Bad input type -- need CV_64F\n"); return false; } - if (!(dst->isContinuous())) { - std::cerr << "Bad input array -- need continuous\n"; + if (!dst->isContinuous()) { + BARF("Bad input array -- need continuous\n"); return false; } diff --git a/src/mrcal_wrapper.h b/src/mrcal_wrapper.h index e9bf7fc..e595869 100644 --- a/src/mrcal_wrapper.h +++ b/src/mrcal_wrapper.h @@ -15,14 +15,11 @@ #pragma once -extern "C" { -// Seems to be missing C++ guards #include -} // extern "C" - #include -#include +#include +#include #include #include #include @@ -44,9 +41,18 @@ struct mrcal_result { rms_error{rms_error_}, residuals{std::move(residuals_)}, calobject_warp{calobject_warp_}, Noutliers_board{Noutliers_board_} {} mrcal_result(mrcal_result &&) = delete; - ~mrcal_result(); + ~mrcal_result() = default; }; +/** + * Gets the seed pose for a board. + * + * @param c_observations_board_pool The corners in image space. + * @param boardSize The size of the corner grid. + * @param imagerSize The size of the image in pixels. + * @param squareSize The size of the squares in a physical distance unit. + * @param focal_len_guess A focal length guess in pixels. + */ mrcal_pose_t getSeedPose(const mrcal_point3_t *c_observations_board_pool, cv::Size boardSize, cv::Size imagerSize, double squareSize, double focal_len_guess);