Skip to content

Commit

Permalink
Create charuco boards with any opencv version
Browse files Browse the repository at this point in the history
  • Loading branch information
BAILOOL committed Nov 6, 2024
1 parent a46c087 commit 5e9a97a
Showing 1 changed file with 117 additions and 39 deletions.
156 changes: 117 additions & 39 deletions apps/create_charuco_boards/src/create_charuco_boards.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,121 @@
#include <filesystem>
#include <iomanip>
#include <numeric>
#include <stdio.h>

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

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

std::vector<cv::Mat>
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 std::vector<int> &resolution_x_per_board,
const std::vector<int> &resolution_y_per_board) {
std::vector<cv::Mat> charuco_boards_images;
charuco_boards_images.reserve(num_board);
cv::Ptr<cv::aruco::Dictionary> dict =
cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_1000);
std::vector<cv::Ptr<cv::aruco::CharucoBoard>> charuco_boards;
charuco_boards.reserve(num_board);
int offset_count = 0;
for (std::size_t i = 0; i < num_board; i++) {
// declare the board
cv::Ptr<cv::aruco::CharucoBoard> charuco = cv::aruco::CharucoBoard::create(
number_x_square_per_board[i], number_y_square_per_board[i],
length_square, length_marker, dict);
// If it is the first board then just use the standard idx
if (i != 0) {
int id_offset = charuco_boards[i - 1]->ids.size() + offset_count;
offset_count = id_offset;
for (auto &id : charuco->ids) {
id += id_offset;
}
}
charuco_boards.push_back(charuco);

// create the charuco board image
cv::Mat board_image;
charuco_boards[i]->draw(
cv::Size(resolution_x_per_board[i], resolution_y_per_board[i]),
board_image, 10, 1);

charuco_boards_images.push_back(board_image);
}
return charuco_boards_images;
}

#else

std::vector<cv::Mat>
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 std::vector<int> &resolution_x_per_board,
const std::vector<int> &resolution_y_per_board) {
std::vector<cv::Mat> charuco_boards_images;
charuco_boards_images.reserve(num_board);
const cv::aruco::Dictionary dict =
cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_1000);
std::vector<cv::aruco::CharucoBoard> charuco_boards;
charuco_boards.reserve(num_board);
int offset_count = 0;
for (std::size_t i = 0; i < num_board; i++) {
if (i == 0) {
// if it is the first board then just use the standard idx
cv::aruco::CharucoBoard charuco = cv::aruco::CharucoBoard(
cv::Size(number_x_square_per_board[i], number_y_square_per_board[i]),
length_square, length_marker, dict);

charuco_boards.push_back(charuco);
} else {
int id_offset = charuco_boards[i - 1].getIds().size() + offset_count;
offset_count = id_offset;

const std::size_t num_idxs = charuco_boards[i - 1].getIds().size();
std::vector<int> cur_ids(num_idxs);
std::iota(cur_ids.begin(), cur_ids.end(), id_offset);

cv::aruco::CharucoBoard charuco = cv::aruco::CharucoBoard(
cv::Size(number_x_square_per_board[i], number_y_square_per_board[i]),
length_square, length_marker, dict, cur_ids);

charuco_boards.push_back(charuco);
}

// create the charuco board image
cv::Mat board_image;
charuco_boards[i].generateImage(
cv::Size(resolution_x_per_board[i], resolution_y_per_board[i]),
board_image, 10, 1);

charuco_boards_images.push_back(board_image);
}

return charuco_boards_images;
}
#endif

void saveBoards(const std::vector<cv::Mat> boards) {
for (std::size_t board_idx = 0u; board_idx < boards.size(); ++board_idx) {
// Save the markers
std::ostringstream ss;
ss << std::setw(3) << std::setfill('0') << board_idx;
std::string s1 = ss.str();
std::string charname = "charuco_board_";
std::string extname = ".bmp";
std::string savename = charname + s1;
savename += extname;
std::cout << "save_name " << savename << std::endl;
cv::imwrite(savename, boards[board_idx]);
}
}

int main(int argc, char *argv[]) {

if (argc != 2) {
Expand Down Expand Up @@ -39,7 +150,7 @@ int main(int argc, char *argv[]) {

fs["number_board"] >> NbBoard;
assert(NbBoard > 0);
unsigned int num_board = static_cast<int>(NbBoard);
const unsigned int num_board = static_cast<int>(NbBoard);

fs["square_size_per_board"] >> square_size_per_board;
fs["number_x_square_per_board"] >> number_x_square_per_board;
Expand All @@ -59,44 +170,11 @@ int main(int argc, char *argv[]) {
}
}

// Create the charuco
cv::Ptr<cv::aruco::Dictionary> dict =
cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_1000);
std::vector<cv::Ptr<cv::aruco::CharucoBoard>> charucoBoards;
int offset_count = 0;
for (std::size_t i = 0; i < num_board; i++) {
// declare the board
cv::Ptr<cv::aruco::CharucoBoard> charuco = cv::aruco::CharucoBoard::create(
number_x_square_per_board[i], number_y_square_per_board[i],
length_square, length_marker, dict);
// If it is the first board then just use the standard idx
if (i != 0) {
int id_offset = charucoBoards[i - 1]->ids.size() + offset_count;
offset_count = id_offset;
for (auto &id : charuco->ids) {
id += id_offset;
}
}
// create the charuco board
charucoBoards.push_back(charuco);
cv::Mat boardImage;
charucoBoards[i]->draw(
cv::Size(resolution_x_per_board[i], resolution_y_per_board[i]),
boardImage, 10, 1);
// Display marker
// cv::imshow("My Charuco", boardImage);
// cv::waitKey(1);
// Save the marker
std::ostringstream ss;
ss << std::setw(3) << std::setfill('0') << i;
std::string s1 = ss.str();
std::string charname = "charuco_board_";
std::string extname = ".bmp";
std::string savename = charname + s1;
savename += extname;
std::cout << "save_name " << savename << std::endl;
cv::imwrite(savename, boardImage);
}
const std::vector<cv::Mat> charuco_boards_images = createCharucoBoards(
num_board, number_x_square_per_board, number_y_square_per_board,
length_square, length_marker, resolution_x_per_board,
resolution_y_per_board);
saveBoards(charuco_boards_images);

return 0;
}

0 comments on commit 5e9a97a

Please sign in to comment.