mirror of
https://github.com/opencv/opencv_contrib.git
synced 2025-10-19 19:44:14 +08:00
151 lines
5.9 KiB
C++
151 lines
5.9 KiB
C++
//! [charucohdr]
|
|
#include <opencv2/aruco/charuco.hpp>
|
|
//! [charucohdr]
|
|
#include <opencv2/highgui.hpp>
|
|
#include <iostream>
|
|
#include <string>
|
|
#include "aruco_samples_utility.hpp"
|
|
|
|
namespace {
|
|
const char* about = "A tutorial code on charuco board creation and detection of charuco board with and without camera caliberation";
|
|
const char* keys = "{c | | Put value of c=1 to create charuco board;\nc=2 to detect charuco board without camera calibration;\nc=3 to detect charuco board with camera calibration and Pose Estimation}";
|
|
}
|
|
|
|
static inline void createBoard()
|
|
{
|
|
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
|
|
//! [createBoard]
|
|
cv::Ptr<cv::aruco::CharucoBoard> board = cv::aruco::CharucoBoard::create(5, 7, 0.04f, 0.02f, dictionary);
|
|
cv::Mat boardImage;
|
|
board->draw(cv::Size(600, 500), boardImage, 10, 1);
|
|
//! [createBoard]
|
|
cv::imwrite("BoardImage.jpg", boardImage);
|
|
}
|
|
|
|
//! [detwcp]
|
|
static inline void detectCharucoBoardWithCalibrationPose()
|
|
{
|
|
cv::VideoCapture inputVideo;
|
|
inputVideo.open(0);
|
|
//! [matdiscoff]
|
|
cv::Mat cameraMatrix, distCoeffs;
|
|
std::string filename = "calib.txt";
|
|
bool readOk = readCameraParameters(filename, cameraMatrix, distCoeffs);
|
|
//! [matdiscoff]
|
|
if (!readOk) {
|
|
std::cerr << "Invalid camera file" << std::endl;
|
|
} else {
|
|
//! [dictboard]
|
|
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
|
|
cv::Ptr<cv::aruco::CharucoBoard> board = cv::aruco::CharucoBoard::create(5, 7, 0.04f, 0.02f, dictionary);
|
|
cv::Ptr<cv::aruco::DetectorParameters> params = cv::aruco::DetectorParameters::create();
|
|
//! [dictboard]
|
|
while (inputVideo.grab()) {
|
|
//! [inputImg]
|
|
cv::Mat image;
|
|
//! [inputImg]
|
|
cv::Mat imageCopy;
|
|
inputVideo.retrieve(image);
|
|
image.copyTo(imageCopy);
|
|
//! [midcornerdet]
|
|
std::vector<int> markerIds;
|
|
std::vector<std::vector<cv::Point2f> > markerCorners;
|
|
cv::aruco::detectMarkers(image, board->dictionary, markerCorners, markerIds, params);
|
|
//! [midcornerdet]
|
|
// if at least one marker detected
|
|
if (markerIds.size() > 0) {
|
|
cv::aruco::drawDetectedMarkers(imageCopy, markerCorners, markerIds);
|
|
//! [charidcor]
|
|
std::vector<cv::Point2f> charucoCorners;
|
|
std::vector<int> charucoIds;
|
|
cv::aruco::interpolateCornersCharuco(markerCorners, markerIds, image, board, charucoCorners, charucoIds, cameraMatrix, distCoeffs);
|
|
//! [charidcor]
|
|
// if at least one charuco corner detected
|
|
if (charucoIds.size() > 0) {
|
|
cv::Scalar color = cv::Scalar(255, 0, 0);
|
|
//! [detcor]
|
|
cv::aruco::drawDetectedCornersCharuco(imageCopy, charucoCorners, charucoIds, color);
|
|
//! [detcor]
|
|
cv::Vec3d rvec, tvec;
|
|
//! [pose]
|
|
bool valid = cv::aruco::estimatePoseCharucoBoard(charucoCorners, charucoIds, board, cameraMatrix, distCoeffs, rvec, tvec);
|
|
//! [pose]
|
|
// if charuco pose is valid
|
|
if (valid)
|
|
cv::aruco::drawAxis(imageCopy, cameraMatrix, distCoeffs, rvec, tvec, 0.1f);
|
|
}
|
|
}
|
|
cv::imshow("out", imageCopy);
|
|
char key = (char)cv::waitKey(30);
|
|
if (key == 27)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//! [detwcp]
|
|
|
|
//! [detwc]
|
|
static inline void detectCharucoBoardWithoutCalibration()
|
|
{
|
|
cv::VideoCapture inputVideo;
|
|
inputVideo.open(0);
|
|
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
|
|
cv::Ptr<cv::aruco::CharucoBoard> board = cv::aruco::CharucoBoard::create(5, 7, 0.04f, 0.02f, dictionary);
|
|
|
|
cv::Ptr<cv::aruco::DetectorParameters> params = cv::aruco::DetectorParameters::create();
|
|
params->cornerRefinementMethod = cv::aruco::CORNER_REFINE_NONE;
|
|
while (inputVideo.grab()) {
|
|
cv::Mat image, imageCopy;
|
|
inputVideo.retrieve(image);
|
|
image.copyTo(imageCopy);
|
|
std::vector<int> markerIds;
|
|
std::vector<std::vector<cv::Point2f> > markerCorners;
|
|
cv::aruco::detectMarkers(image, board->dictionary, markerCorners, markerIds, params);
|
|
//or
|
|
//cv::aruco::detectMarkers(image, dictionary, markerCorners, markerIds, params);
|
|
// if at least one marker detected
|
|
if (markerIds.size() > 0) {
|
|
cv::aruco::drawDetectedMarkers(imageCopy, markerCorners, markerIds);
|
|
//! [charidcorwc]
|
|
std::vector<cv::Point2f> charucoCorners;
|
|
std::vector<int> charucoIds;
|
|
cv::aruco::interpolateCornersCharuco(markerCorners, markerIds, image, board, charucoCorners, charucoIds);
|
|
//! [charidcorwc]
|
|
// if at least one charuco corner detected
|
|
if (charucoIds.size() > 0)
|
|
cv::aruco::drawDetectedCornersCharuco(imageCopy, charucoCorners, charucoIds, cv::Scalar(255, 0, 0));
|
|
}
|
|
cv::imshow("out", imageCopy);
|
|
char key = (char)cv::waitKey(30);
|
|
if (key == 27)
|
|
break;
|
|
}
|
|
}
|
|
//! [detwc]
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
cv::CommandLineParser parser(argc, argv, keys);
|
|
parser.about(about);
|
|
if (argc < 2) {
|
|
parser.printMessage();
|
|
return 0;
|
|
}
|
|
int choose = parser.get<int>("c");
|
|
switch (choose) {
|
|
case 1:
|
|
createBoard();
|
|
std::cout << "An image named BoardImg.jpg is generated in folder containing this file" << std::endl;
|
|
break;
|
|
case 2:
|
|
detectCharucoBoardWithoutCalibration();
|
|
break;
|
|
case 3:
|
|
detectCharucoBoardWithCalibrationPose();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|