Skip to content

Commit

Permalink
Add support for OpenCV > v4.6.0 (#88)
Browse files Browse the repository at this point in the history
  • Loading branch information
BAILOOL authored Nov 14, 2024
1 parent 09a7a8c commit 0db0acf
Show file tree
Hide file tree
Showing 17 changed files with 384 additions and 116 deletions.
99 changes: 94 additions & 5 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ on:
workflow_dispatch:

env:
MC_CALIB_PROD_DOCKER_IMG: bailool/mc-calib-prod:opencv420
MC_CALIB_DEV_DOCKER_IMG: bailool/mc-calib-dev:opencv420
MC_CALIB_PROD_DOCKER_IMG: bailool/mc-calib-prod:opencv4100
MC_CALIB_DEV_DOCKER_IMG: bailool/mc-calib-dev:opencv4100

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
Expand Down Expand Up @@ -70,6 +70,34 @@ jobs:
run-clang-tidy

test-charuco-boards-generation:
runs-on: ubuntu-latest
needs:
- clang-format-lint
- cppcheck
- clang-tidy
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Run charuco boards generation app
uses: addnab/docker-run-action@v3
with:
image: ${{env.MC_CALIB_PROD_DOCKER_IMG}}
options: -v ${{ github.workspace }}:/home/MC-Calib:rw
run: |
mkdir MC-Calib/build && cd MC-Calib/build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j4
./apps/create_charuco_boards/generate_charuco ../tests/configs_for_end2end_tests/calib_param_synth_Scenario1.yml
- name: Archive results artifacts
uses: actions/upload-artifact@v4
with:
name: charuco_boards
path: ${{ github.workspace }}/build/charuco_boards


unit-tests-with-sanitizers:
if: ${{ false }} # TODO: disable for now until understand how to suppress leaks from external libraries like OpenCV
runs-on: ubuntu-latest
Expand Down Expand Up @@ -146,7 +174,7 @@ jobs:
./apps/calibrate/calibrate ../tests/configs_for_end2end_tests/calib_param_synth_Scenario1.yml
unit-tests-in-release-mode:
unit-tests-in-release-mode-opencv4100:
runs-on: ubuntu-latest
needs:
- clang-format-lint
Expand Down Expand Up @@ -208,6 +236,67 @@ jobs:
name: results_blender_sequences
path: ${{ github.workspace }}/data/Blender_Images/Results_Blender_Sequences

unit-tests-in-release-mode-opencv455:
runs-on: ubuntu-latest
needs:
- clang-format-lint
- cppcheck
- clang-tidy
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Checkout MC-Calib-data
uses: actions/checkout@v4
with:
repository: BAILOOL/MC-Calib-data
path: ${{ github.workspace }}/data
lfs: 'true'

- name: Unzip MC-Calib-data
run: tar xf ${{ github.workspace }}/data/Blender_Images.tar.gz -C ${{ github.workspace }}/data

- name: Run tests
uses: addnab/docker-run-action@v3
with:
image: bailool/mc-calib-prod:opencv455
options: -v ${{ github.workspace }}:/home/MC-Calib:rw
run: |
mkdir MC-Calib/build && cd MC-Calib/build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j4
./tests/boost_tests_run
unit-tests-in-release-mode-opencv420:
runs-on: ubuntu-latest
needs:
- clang-format-lint
- cppcheck
- clang-tidy
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Checkout MC-Calib-data
uses: actions/checkout@v4
with:
repository: BAILOOL/MC-Calib-data
path: ${{ github.workspace }}/data
lfs: 'true'

- name: Unzip MC-Calib-data
run: tar xf ${{ github.workspace }}/data/Blender_Images.tar.gz -C ${{ github.workspace }}/data

- name: Run tests
uses: addnab/docker-run-action@v3
with:
image: bailool/mc-calib-prod:opencv420
options: -v ${{ github.workspace }}:/home/MC-Calib:rw
run: |
mkdir MC-Calib/build && cd MC-Calib/build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j4
./tests/boost_tests_run
code-coverage-testing:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -262,7 +351,7 @@ jobs:
python-utils-linters:
runs-on: ubuntu-latest
needs:
- unit-tests-in-release-mode
- unit-tests-in-release-mode-opencv4100
steps:
- name: Checkout
uses: actions/checkout@v2
Expand All @@ -282,7 +371,7 @@ jobs:
runs-on: ubuntu-latest
needs:
- python-utils-linters
- unit-tests-in-release-mode
- unit-tests-in-release-mode-opencv4100
steps:
- name: Checkout
uses: actions/checkout@v2
Expand Down
5 changes: 3 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ if(ENABLE_COVERAGE)
# add coverage target
add_custom_target(coverage
# gather data
COMMAND ${LCOV} --directory . --capture --output-file coverage.info --exclude '/usr/*'
COMMAND ${LCOV} --directory . --capture --output-file coverage.info --exclude '/usr/*'
--ignore-errors mismatch,negative
# generate report
COMMAND ${GENHTML} --demangle-cpp -o coverage coverage.info
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
Expand Down Expand Up @@ -80,7 +81,7 @@ endif (DOXYGEN_FOUND)


##########################################################################
add_subdirectory(apps/create_charuco_boards)
add_subdirectory(McCalib)
add_subdirectory(apps/create_charuco_boards)
add_subdirectory(apps/calibrate)
add_subdirectory(tests)
16 changes: 8 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ubuntu:20.04 as prod
FROM ubuntu:24.04 as prod

ENV DEBIAN_FRONTEND noninteractive
RUN apt update && apt install -y --no-install-recommends apt-utils && \
Expand All @@ -15,14 +15,14 @@ WORKDIR /home
#------------------------------ #
# INSTALL OPENCV 4 #
#------------------------------ #
RUN wget -O opencv.zip https://github.com/opencv/opencv/archive/4.2.0.zip && \
wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/4.2.0.zip && \
RUN wget -O opencv.zip https://github.com/opencv/opencv/archive/4.10.0.zip && \
wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/4.10.0.zip && \
unzip opencv.zip && unzip opencv_contrib.zip && \
mkdir -p build && cd build && \
cmake -DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib-4.2.0/modules ../opencv-4.2.0 && \
cmake -DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib-4.10.0/modules ../opencv-4.10.0 && \
cmake --build . --target install -- -j4 && \
cd /home && rm opencv.zip && rm opencv_contrib.zip && \
rm -rf opencv-4.2.0 && rm -rf opencv_contrib-4.2.0 && rm -rf build && \
rm -rf opencv-4.10.0 && rm -rf opencv_contrib-4.10.0 && rm -rf build && \
rm -rf /var/lib/apt/lists/*

#------------------------------ #
Expand All @@ -49,8 +49,8 @@ RUN git clone --branch 2.2.0 --single-branch https://github.com/ceres-solver/cer

# Install python requirements for python_utils scripts
RUN --mount=type=bind,source=python_utils/requirements_prod.txt,target=/tmp/requirements.txt \
apt update && apt install -y libgl1 && \
python -m pip install --requirement /tmp/requirements.txt && \
apt update && apt install -y libgl1 libglib2.0-0 && \
python -m pip install --requirement /tmp/requirements.txt --break-system-packages && \
rm -rf /var/lib/apt/lists/*

FROM prod as dev
Expand All @@ -75,5 +75,5 @@ RUN apt update && apt install -y cppcheck clang-tidy valgrind lcov && \

# Install python requirements for python_utils scripts
RUN --mount=type=bind,source=python_utils/requirements_dev.txt,target=/tmp/requirements.txt \
python -m pip install --requirement /tmp/requirements.txt && \
python -m pip install --requirement /tmp/requirements.txt --break-system-packages && \
rm -rf /var/lib/apt/lists/*
2 changes: 1 addition & 1 deletion McCalib/include/Board.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class Board final {
std::map<int, std::weak_ptr<Frame>> frames_;

// Charuco board
cv::Ptr<cv::aruco::CharucoBoard> charuco_board_; // vector of charuco boards
cv::Ptr<cv::aruco::CharucoBoard> charuco_board_;

// Functions
Board() = delete;
Expand Down
11 changes: 11 additions & 0 deletions McCalib/include/McCalib.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,22 @@ class Calibration final {
public:
// Parameters
unsigned int nb_camera_, nb_board_;

#if (defined(CV_VERSION_MAJOR) && CV_VERSION_MAJOR <= 4 && \
defined(CV_VERSION_MINOR) && CV_VERSION_MINOR < 7)
cv::Ptr<cv::aruco::Dictionary> dict_ = cv::aruco::getPredefinedDictionary(
cv::aruco::DICT_6X6_1000); // load the dictionary that correspond to the
// charuco board
cv::Ptr<cv::aruco::DetectorParameters> charuco_params_ =
cv::aruco::DetectorParameters::create(); // parameters for detection
#else
cv::aruco::Dictionary dict_ = cv::aruco::getPredefinedDictionary(
cv::aruco::DICT_6X6_1000); // load the dictionary that correspond to the
// charuco board
cv::aruco::DetectorParameters charuco_params_ =
cv::aruco::DetectorParameters(); // parameters for detection
#endif

float min_perc_pts_;

// images path
Expand Down
25 changes: 14 additions & 11 deletions McCalib/include/point_refinement.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#include "opencv2/core/core.hpp"
#include <cmath>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <stdio.h>

#include "opencv2/core/core.hpp"
#include <opencv2/opencv.hpp>

namespace McCalib {

/****** ******/

float step_threshold = 0.001;
double step_threshold = 0.001;

/**
* @struct SaddlePoint
Expand Down Expand Up @@ -36,7 +38,7 @@ void initSaddlePointRefinement(const int half_kernel_size,
int cnt = 0;
for (int y = -half_kernel_size; y <= half_kernel_size; y++)
for (int x = -half_kernel_size; x <= half_kernel_size; x++) {
*w = maxVal - sqrt(x * x + y * y);
*w = maxVal - std::sqrt(x * x + y * y);
if (*w > 0)
cnt++;
else
Expand Down Expand Up @@ -138,22 +140,23 @@ void saddleSubpixelRefinement(const cv::Mat &smooth_input,
pt.det; // k3 * k1 - 2 * k5 * k2
pt.x += dx;
pt.y += dy;
dx = fabs(dx);
dy = fabs(dy);
dx = std::fabs(dx);
dy = std::fabs(dy);
// iterations++;

if (it == max_iterations ||
(step_threshold > dx && step_threshold > dy)) {
// converged
double k4mk5 = r[1] - r[0];
pt.s = sqrt(r[2] * r[2] + k4mk5 * k4mk5);
pt.a1 = atan2(-r[2], k4mk5) / 2.0;
pt.a2 = acos((r[1] + r[0]) / pt.s) / 2.0;
pt.s = std::sqrt(r[2] * r[2] + k4mk5 * k4mk5);
pt.a1 = std::atan2(-r[2], k4mk5) / 2.0;
pt.a2 = std::acos((r[1] + r[0]) / pt.s) / 2.0;
break;
} else {
// check for divergence
if (pt.det > 0 || fabs(pt.x - initial[idx].x) > window_half_size ||
fabs(pt.y - initial[idx].y) > window_half_size) {
if (pt.det > 0 ||
std::fabs(pt.x - initial[idx].x) > window_half_size ||
std::fabs(pt.y - initial[idx].y) > window_half_size) {
pt.x = pt.y = std::numeric_limits<double>::infinity();
// diverged++;
break;
Expand Down
30 changes: 30 additions & 0 deletions McCalib/include/utilities.hpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,42 @@

#include <filesystem>
#include <map>
#include <string>
#include <vector>

#include <opencv2/aruco/charuco.hpp>
#include <opencv2/opencv.hpp>

namespace McCalib {

std::filesystem::path convertStrToPath(const std::string &item_name);
std::vector<std::filesystem::path>
convertVecStrToVecPath(const std::vector<std::string> &input);

#if (defined(CV_VERSION_MAJOR) && CV_VERSION_MAJOR <= 4 && \
defined(CV_VERSION_MINOR) && CV_VERSION_MINOR < 7)

std::map<int, cv::Ptr<cv::aruco::CharucoBoard>>
createCharucoBoards(const unsigned int num_board,
const std::vector<int> &number_x_square_per_board,
const std::vector<int> &number_y_square_per_board,
const float length_square, const float length_marker,
const cv::Ptr<cv::aruco::Dictionary> dict);
#else
std::map<int, cv::Ptr<cv::aruco::CharucoBoard>>
createCharucoBoards(const unsigned int num_board,
const std::vector<int> &number_x_square_per_board,
const std::vector<int> &number_y_square_per_board,
const float length_square, const float length_marker,
const cv::aruco::Dictionary &dict);
#endif

std::vector<cv::Mat>
createCharucoBoardsImages(const unsigned int num_board,
const std::vector<int> &number_x_square_per_board,
const std::vector<int> &number_y_square_per_board,
const float length_square, const float length_marker,
const std::vector<int> &resolution_x_per_board,
const std::vector<int> &resolution_y_per_board);

} // namespace McCalib
11 changes: 8 additions & 3 deletions McCalib/src/Camera.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
#include "opencv2/core/core.hpp"
#include <algorithm>
#include <iostream>
#include <random>
#include <stdio.h>

#include "opencv2/core/core.hpp"
#include <opencv2/aruco/charuco.hpp>
#include <opencv2/opencv.hpp>
#include <stdio.h>

#include "Camera.hpp"
#include "OptimizationCeres.h"
Expand Down Expand Up @@ -169,7 +172,9 @@ void Camera::initializeCalibration() {
std::srand(unsigned(std::time(0)));
std::vector<int> shuffled_board_ind(indbv.size());
std::iota(shuffled_board_ind.begin(), shuffled_board_ind.end(), 0);
random_shuffle(shuffled_board_ind.begin(), shuffled_board_ind.end());
std::random_device rd;
std::mt19937 g(rd());
std::shuffle(shuffled_board_ind.begin(), shuffled_board_ind.end(), g);

// nb of boards used for the initial estimation of intrinsic parameters
//(at least 50 boards for perspective)
Expand Down
Loading

0 comments on commit 0db0acf

Please sign in to comment.