Skip to content

Commit

Permalink
Merge pull request opencv#1153 from atinfinity:fixed_aruco_tutorial
Browse files Browse the repository at this point in the history
  • Loading branch information
mshabunin committed May 11, 2017
2 parents 6bca9e8 + ebc255b commit fa94c16
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ The aruco module allows the use of Boards. The main class is the ```cv::aruco::B
class Board {
public:
std::vector<std::vector<cv::Point3f> > objPoints;
cv::aruco::Dictionary dictionary;
cv::Ptr<cv::aruco::Dictionary> dictionary;
std::vector<int> ids;
};
```
Expand All @@ -57,10 +57,10 @@ The aruco module provides a specific function, ```estimatePoseBoard()```, to per
cv::Mat cameraMatrix, distCoeffs;
readCameraParameters(cameraMatrix, distCoeffs);
// assume we have a function to create the board object
cv::aruco::Board board = createBoard();
cv::Ptr<cv::aruco::Board> board = cv::aruco::Board::create();
...
vector< int > markerIds;
vector< vector<Point2f> > markerCorners;
std::vector<int> markerIds;
std::vector<std::vector<cv::Point2f>> markerCorners;
cv::aruco::detectMarkers(inputImage, board.dictionary, markerCorners, markerIds);
// if at least one marker detected
if(markerIds.size() > 0) {
Expand Down Expand Up @@ -137,9 +137,9 @@ After creating a Grid Board, we probably want to print it and use it. A function
of a ```GridBoard``` is provided in ```cv::aruco::GridBoard::draw()```. For example:

``` c++
cv::aruco::GridBoard board = cv::aruco::GridBoard::create(5, 7, 0.04, 0.01, dictionary);
cv::Ptr<cv::aruco::GridBoard> board = cv::aruco::GridBoard::create(5, 7, 0.04, 0.01, dictionary);
cv::Mat boardImage;
board.draw( cv::Size(600, 500), boardImage, 10, 1 );
board->draw( cv::Size(600, 500), boardImage, 10, 1 );
```
- The first parameter is the size of the output image in pixels. In this case 600x500 pixels. If this is not proportional
Expand Down Expand Up @@ -170,8 +170,8 @@ Finally, a full example of board detection:
// camera parameters are read from somewhere
readCameraParameters(cameraMatrix, distCoeffs);

cv::aruco::Dictionary dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::aruco::GridBoard board = cv::aruco::GridBoard::create(5, 7, 0.04, 0.01, dictionary);
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::Ptr<cv::aruco::GridBoard> board = cv::aruco::GridBoard::create(5, 7, 0.04, 0.01, dictionary);

while (inputVideo.grab()) {
cv::Mat image, imageCopy;
Expand Down Expand Up @@ -256,10 +256,10 @@ internal bits are not analyzed at all and only the corner distances are evaluate
This is an example of using the ```refineDetectedMarkers()``` function:

``` c++
cv::aruco::Dictionary dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::aruco::GridBoard board = cv::aruco::GridBoard::create(5, 7, 0.04, 0.01, dictionary);
vector< int > markerIds;
vector< vector<Point2f> > markerCorners, rejectedCandidates;
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::Ptr<cv::aruco::GridBoard> board = cv::aruco::GridBoard::create(5, 7, 0.04, 0.01, dictionary);
std::vector<int> markerIds;
std::vector<std::vector<cv::Point2f>> markerCorners, rejectedCandidates;
cv::aruco::detectMarkers(inputImage, dictionary, markerCorners, markerIds, cv::aruco::DetectorParameters(), rejectedCandidates);

cv::aruco::refineDetectedMarkersinputImage, board, markerCorners, markerIds, rejectedCandidates);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,18 @@ visible in all the viewpoints.
The function to calibrate is ```calibrateCameraCharuco()```. Example:

``` c++
aruco::CharucoBoard board = ... // create charuco board
cv::Ptr<aruco::CharucoBoard> board = ... // create charuco board
cv::Size imgSize = ... // camera image size

std::vector< std::vector<cv::Point2f> > allCharucoCorners;
std::vector< std::vector<int> > allCharucoIds;
std::vector<std::vector<cv::Point2f>> allCharucoCorners;
std::vector<std::vector<int>> allCharucoIds;
// Detect charuco board from several viewpoints and fill allCharucoCorners and allCharucoIds
...
...

// After capturing in several viewpoints, start calibration
cv::Mat cameraMatrix, distCoeffs;
std::vector< Mat > rvecs, tvecs;
std::vector<cv::Mat> rvecs, tvecs;
int calibrationFlags = ... // Set calibration flags (same than in calibrateCamera() function)

double repError = cv::aruco::calibrateCameraCharuco(allCharucoCorners, allCharucoIds, board, imgSize, cameraMatrix, distCoeffs, rvecs, tvecs, calibrationFlags);
Expand Down Expand Up @@ -81,19 +81,19 @@ requires the detections of an ArUco board from different viewpoints.
Example of ```calibrateCameraAruco()``` use:
``` c++
aruco::Board board = ... // create aruco board
cv::Ptr<aruco::Board> board = ... // create aruco board
cv::Size imgSize = ... // camera image size
std::vector< std::vector< cv::Point2f > > allCornersConcatenated;
std::vector< int > allIdsConcatenated;
std::vector< int > markerCounterPerFrame;
std::vector<std::vector<cv::Point2f>> allCornersConcatenated;
std::vector<int> allIdsConcatenated;
std::vector<int> markerCounterPerFrame;
// Detect aruco board from several viewpoints and fill allCornersConcatenated, allIdsConcatenated and markerCounterPerFrame
...
...
// After capturing in several viewpoints, start calibration
cv::Mat cameraMatrix, distCoeffs;
std::vector< Mat > rvecs, tvecs;
std::vector<cv::Mat> rvecs, tvecs;
int calibrationFlags = ... // Set calibration flags (same than in calibrateCamera() function)
double repError = cv::aruco::calibrateCameraAruco(allCornersConcatenated, allIdsConcatenated, markerCounterPerFrame, board, imgSize, cameraMatrix, distCoeffs, rvecs, tvecs, calibrationFlags);
Expand Down
33 changes: 17 additions & 16 deletions modules/aruco/tutorials/aruco_detection/aruco_detection.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ a popular library for detection of square fiducial markers developed by Rafael M
The aruco functionalities are included in:
``` c++
\#include <opencv2/aruco.hpp>
#include <opencv2/aruco.hpp>
```


Expand Down Expand Up @@ -71,7 +71,7 @@ For example, lets analyze the following call:

``` c++
cv::Mat markerImage;
cv::aruco::Dictionary dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::aruco::drawMarker(dictionary, 23, 200, markerImage, 1);
```
Expand Down Expand Up @@ -156,10 +156,10 @@ An example of marker detection:
``` c++
cv::Mat inputImage;
...
vector< int > markerIds;
vector< vector<Point2f> > markerCorners, rejectedCandidates;
cv::aruco::DetectorParameters parameters;
cv::aruco::Dictionary dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
std::vector<int> markerIds;
std::vector<std::vector<cv::Point2f>> markerCorners, rejectedCandidates;
cv::Ptr<cv::aruco::DetectorParameters> parameters;
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::aruco::detectMarkers(inputImage, dictionary, markerCorners, markerIds, parameters, rejectedCandidates);
```
Expand Down Expand Up @@ -204,7 +204,7 @@ camera:
``` c++
cv::VideoCapture inputVideo;
inputVideo.open(0);
cv::aruco::Dictionary dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
while (inputVideo.grab()) {
cv::Mat image, imageCopy;
inputVideo.retrieve(image);
Expand Down Expand Up @@ -263,9 +263,9 @@ information).
The aruco module provides a function to estimate the poses of all the detected markers:

``` c++
Mat cameraMatrix, distCoeffs;
cv::Mat cameraMatrix, distCoeffs;
...
vector< Vec3d > rvecs, tvecs;
std::vector<cv::Vec3d> rvecs, tvecs;
cv::aruco::estimatePoseSingleMarkers(corners, 0.05, cameraMatrix, distCoeffs, rvecs, tvecs);
```
Expand Down Expand Up @@ -303,22 +303,22 @@ A basic full example for pose estimation from single markers:
// camera parameters are read from somewhere
readCameraParameters(cameraMatrix, distCoeffs);

cv::aruco::Dictionary dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);

while (inputVideo.grab()) {
cv::Mat image, imageCopy;
inputVideo.retrieve(image);
image.copyTo(imageCopy);

std::vector<int> ids;
std::vector<std::vector<cv::Point2f> > corners;
std::vector<std::vector<cv::Point2f>> corners;
cv::aruco::detectMarkers(image, dictionary, corners, ids);

// if at least one marker detected
if (ids.size() > 0) {
cv::aruco::drawDetectedMarkers(imageCopy, corners, ids);

vector< Mat > rvecs, tvecs;
std::vector<cv::Mat> rvecs, tvecs;
cv::aruco::estimatePoseSingleMarkers(corners, 0.05, cameraMatrix, distCoeffs, rvecs, tvecs);
// draw axis for each marker
for(int i=0; i<ids.size(); i++)
Expand Down Expand Up @@ -374,7 +374,7 @@ This is the easiest way to select a dictionary. The aruco module includes a set
of a variety of marker sizes and number of markers. For instance:

``` c++
cv::aruco::Dictionary dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
```

DICT_6X6_250 is an example of predefined dictionary of markers with 6x6 bits and a total of 250
Expand All @@ -390,7 +390,7 @@ The dictionary can be generated automatically to adjust to the desired number of
the inter-marker distance is optimized:

``` c++
cv::aruco::Dictionary dictionary = cv::aruco::generateCustomDictionary(36, 5);
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::generateCustomDictionary(36, 5);
```

This will generate a customized dictionary composed by 36 markers of 5x5 bits. The process can take several
Expand Down Expand Up @@ -432,18 +432,19 @@ Fortunately, a marker can be easily transformed to this form using the static me
For example:

``` c++
Dictionary dictionary;
cv::aruco::Dictionary dictionary;
// markers of 6x6 bits
dictionary.markerSize = 6;
// maximum number of bit corrections
dictionary.maxCorrectionBits = 3;

// lets create a dictionary of 100 markers
for(int i=0; i<100; i++)
{
// assume generateMarkerBits() generate a new marker in binary format, so that
// markerBits is a 6x6 matrix of CV_8UC1 type, only containing 0s and 1s
cv::Mat markerBits = generateMarkerBits();
cv::Mat markerCompressed = getByteListFromBits(markerBits);
cv::Mat markerCompressed = cv::aruco::Dictionary::getByteListFromBits(markerBits);
// add the marker as a new row
dictionary.bytesList.push_back(markerCompressed);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ The aruco module provides the ```cv::aruco::CharucoBoard``` class that represent
This class, as the rest of ChArUco functionalities, are defined in:

``` c++
\#include <opencv2/aruco/charuco.hpp>
#include <opencv2/aruco/charuco.hpp>
```

To define a ```CharucoBoard```, it is necesary:
Expand Down Expand Up @@ -60,9 +60,9 @@ Once we have our ```CharucoBoard``` object, we can create an image to print it.
```CharucoBoard::draw()``` method:

``` c++
cv::aruco::CharucoBoard board = cv::aruco::CharucoBoard::create(5, 7, 0.04, 0.02, dictionary);
cv::Ptr<cv::aruco::CharucoBoard> board = cv::aruco::CharucoBoard::create(5, 7, 0.04, 0.02, dictionary);
cv::Mat boardImage;
board.draw( cv::Size(600, 500), boardImage, 10, 1 );
board->draw( cv::Size(600, 500), boardImage, 10, 1 );
```
- The first parameter is the size of the output image in pixels. In this case 600x500 pixels. If this is not proportional
Expand Down Expand Up @@ -94,8 +94,8 @@ in the board.

So, a detected ChArUco board consists in:

- ```vector<Point2f> charucoCorners``` : list of image positions of the detected corners.
- ```vector <int> charucoIds``` : ids for each of the detected corners in ```charucoCorners```.
- ```std::vector<cv::Point2f> charucoCorners``` : list of image positions of the detected corners.
- ```std::vector<int> charucoIds``` : ids for each of the detected corners in ```charucoCorners```.

The detection of the ChArUco corners is based on the previous detected markers. So that, first markers are detected, and then
ChArUco corners are interpolated from markers.
Expand All @@ -107,11 +107,11 @@ The function that detect the ChArUco corners is ```cv::aruco::interpolateCorners
cv::Mat cameraMatrix, distCoeffs;
// camera parameters are read from somewhere
readCameraParameters(cameraMatrix, distCoeffs);
cv::aruco::Dictionary dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::aruco::CharucoBoard board = cv::aruco::CharucoBoard::create(5, 7, 0.04, 0.02, dictionary);
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.04, 0.02, dictionary);
...
vector< int > markerIds;
vector< vector<Point2f> > markerCorners;
std::vector<int> markerIds;
std::vector<std::vector<cv::Point2f>> markerCorners;
cv::aruco::detectMarkers(inputImage, board.dictionary, markerCorners, markerIds);

// if at least one marker detected
Expand All @@ -136,13 +136,13 @@ are optional. A similar example without these parameters would be:
``` c++
cv::Mat inputImage;
cv::aruco::Dictionary dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::aruco::CharucoBoard board = cv::aruco::CharucoBoard::create(5, 7, 0.04, 0.02, dictionary);
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.04, 0.02, dictionary);
...
vector< int > markerIds;
vector< vector<Point2f> > markerCorners;
DetectorParameters params;
params.doCornerRefinement = false;
std::vector<int> markerIds;
std::vector<std::vector<cv::Point2f>> markerCorners;
cv::Ptr<cv::aruco::DetectorParameters> params;
params->doCornerRefinement = false;
cv::aruco::detectMarkers(inputImage, board.dictionary, markerCorners, markerIds, params);
// if at least one marker detected
Expand Down Expand Up @@ -203,19 +203,19 @@ Finally, this is a full example of ChArUco detection (without using calibration
cv::VideoCapture inputVideo;
inputVideo.open(0);
cv::aruco::Dictionary dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::aruco::CharucoBoard board = cv::aruco::CharucoBoard::create(5, 7, 0.04, 0.02, dictionary);
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.04, 0.02, dictionary);
DetectorParameters params;
params.doCornerRefinement = false;
cv::Ptr<cv::aruco::DetectorParameters> params;
params->doCornerRefinement = false;
while (inputVideo.grab()) {
cv::Mat image, imageCopy;
inputVideo.retrieve(image);
image.copyTo(imageCopy);
std::vector<int> ids;
std::vector<std::vector<cv::Point2f> > corners;
std::vector<std::vector<cv::Point2f>> corners;
cv::aruco::detectMarkers(image, dictionary, corners, ids, params);
// if at least one marker detected
Expand Down Expand Up @@ -286,16 +286,16 @@ A full example of ChArUco detection with pose estimation:
// camera parameters are read from somewhere
readCameraParameters(cameraMatrix, distCoeffs);
cv::aruco::Dictionary dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::aruco::CharucoBoard board = cv::aruco::CharucoBoard::create(5, 7, 0.04, 0.02, dictionary);
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.04, 0.02, dictionary);
while (inputVideo.grab()) {
cv::Mat image, imageCopy;
inputVideo.retrieve(image);
image.copyTo(imageCopy);
std::vector<int> ids;
std::vector<std::vector<cv::Point2f> > corners;
std::vector<std::vector<cv::Point2f>> corners;
cv::aruco::detectMarkers(image, dictionary, corners, ids);
// if at least one marker detected
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ For instance:

``` c++
cv::Mat diamondImage;
cv::aruco::Dictionary dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::aruco::drawCharucoDiamond(dictionary, cv::Vec4i(45,68,28,74), 200, 120, markerImage);
```
Expand Down Expand Up @@ -78,14 +78,14 @@ After detecting markers, diamond are detected using the ```detectCharucoDiamond(
...


std::vector< int > markerIds;
std::vector< std::vector< cv::Point2f > > markerCorners;
std::vector<int> markerIds;
std::vector<std::vector< cv::Point2f>> markerCorners;

// detect ArUco markers
cv::aruco::detectMarkers(inputImage, dictionary, markerCorners, markerIds);

std::vector< cv::Vec4i > diamondIds;
std::vector< std::vector< cv::Point2f > > diamondCorners;
std::vector<cv::Vec4i> diamondIds;
std::vector<std::vector<cv::Point2f>> diamondCorners;

// detect diamon diamonds
cv::aruco::detectCharucoDiamond(inputImage, markerCorners, markerIds, squareLength / markerLength, diamondCorners, diamondIds);
Expand All @@ -107,8 +107,8 @@ corners and ids:
``` c++
...
std::vector< cv::Vec4i > diamondIds;
std::vector< std::vector< cv::Point2f > > diamondCorners;
std::vector<cv::Vec4i> diamondIds;
std::vector<std::vector<cv::Point2f>> diamondCorners;
cv::aruco::detectCharucoDiamond(inputImage, markerCorners, markerIds, squareLength / markerLength, diamondCorners, diamondIds);
cv::aruco::drawDetectedDiamonds(inputImage, diamondCorners, diamondIds);
Expand All @@ -134,8 +134,8 @@ i.e. using the ```estimatePoseSingleMarkers()``` function. For instance:
``` c++
...

std::vector< cv::Vec4i > diamondIds;
std::vector< std::vector< cv::Point2f > > diamondCorners;
std::vector<cv::Vec4i> diamondIds;
std::vector<std::vector<cv::Point2f>> diamondCorners;

// detect diamon diamonds
cv::aruco::detectCharucoDiamond(inputImage, markerCorners, markerIds, squareLength / markerLength, diamondCorners, diamondIds);
Expand Down

0 comments on commit fa94c16

Please sign in to comment.