Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv_contrib
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv_contrib
Commits
063c191d
Commit
063c191d
authored
Dec 19, 2015
by
folz
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
aruco: Use shared Ptrs to support exporting
parent
9b06bb28
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
710 additions
and
539 deletions
+710
-539
aruco.hpp
modules/aruco/include/opencv2/aruco.hpp
+60
-49
charuco.hpp
modules/aruco/include/opencv2/aruco/charuco.hpp
+26
-25
dictionary.hpp
modules/aruco/include/opencv2/aruco/dictionary.hpp
+52
-9
calibrate_camera.cpp
modules/aruco/samples/calibrate_camera.cpp
+26
-25
calibrate_camera_charuco.cpp
modules/aruco/samples/calibrate_camera_charuco.cpp
+29
-28
create_board.cpp
modules/aruco/samples/create_board.cpp
+3
-3
create_board_charuco.cpp
modules/aruco/samples/create_board_charuco.cpp
+3
-3
create_diamond.cpp
modules/aruco/samples/create_diamond.cpp
+1
-1
create_marker.cpp
modules/aruco/samples/create_marker.cpp
+1
-1
detect_board.cpp
modules/aruco/samples/detect_board.cpp
+26
-25
detect_board_charuco.cpp
modules/aruco/samples/detect_board_charuco.cpp
+27
-26
detect_diamonds.cpp
modules/aruco/samples/detect_diamonds.cpp
+23
-23
detect_markers.cpp
modules/aruco/samples/detect_markers.cpp
+24
-24
aruco.cpp
modules/aruco/src/aruco.cpp
+175
-118
charuco.cpp
modules/aruco/src/charuco.cpp
+68
-65
dictionary.cpp
modules/aruco/src/dictionary.cpp
+83
-36
test_arucodetection.cpp
modules/aruco/test/test_arucodetection.cpp
+29
-26
test_boarddetection.cpp
modules/aruco/test/test_boarddetection.cpp
+26
-24
test_charucodetection.cpp
modules/aruco/test/test_charucodetection.cpp
+28
-28
No files found.
modules/aruco/include/opencv2/aruco.hpp
View file @
063c191d
...
...
@@ -121,30 +121,32 @@ namespace aruco {
* - errorCorrectionRate error correction rate respect to the maximun error correction capability
* for each dictionary. (default 0.6).
*/
struct
CV_EXPORTS
DetectorParameters
{
struct
CV_EXPORTS
_W
DetectorParameters
{
DetectorParameters
();
int
adaptiveThreshWinSizeMin
;
int
adaptiveThreshWinSizeMax
;
int
adaptiveThreshWinSizeStep
;
double
adaptiveThreshConstant
;
double
minMarkerPerimeterRate
;
double
maxMarkerPerimeterRate
;
double
polygonalApproxAccuracyRate
;
double
minCornerDistanceRate
;
int
minDistanceToBorder
;
double
minMarkerDistanceRate
;
bool
doCornerRefinement
;
int
cornerRefinementWinSize
;
int
cornerRefinementMaxIterations
;
double
cornerRefinementMinAccuracy
;
int
markerBorderBits
;
int
perspectiveRemovePixelPerCell
;
double
perspectiveRemoveIgnoredMarginPerCell
;
double
maxErroneousBitsInBorderRate
;
double
minOtsuStdDev
;
double
errorCorrectionRate
;
CV_WRAP
static
Ptr
<
DetectorParameters
>
create
();
CV_PROP_RW
int
adaptiveThreshWinSizeMin
;
CV_PROP_RW
int
adaptiveThreshWinSizeMax
;
CV_PROP_RW
int
adaptiveThreshWinSizeStep
;
CV_PROP_RW
double
adaptiveThreshConstant
;
CV_PROP_RW
double
minMarkerPerimeterRate
;
CV_PROP_RW
double
maxMarkerPerimeterRate
;
CV_PROP_RW
double
polygonalApproxAccuracyRate
;
CV_PROP_RW
double
minCornerDistanceRate
;
CV_PROP_RW
int
minDistanceToBorder
;
CV_PROP_RW
double
minMarkerDistanceRate
;
CV_PROP_RW
bool
doCornerRefinement
;
CV_PROP_RW
int
cornerRefinementWinSize
;
CV_PROP_RW
int
cornerRefinementMaxIterations
;
CV_PROP_RW
double
cornerRefinementMinAccuracy
;
CV_PROP_RW
int
markerBorderBits
;
CV_PROP_RW
int
perspectiveRemovePixelPerCell
;
CV_PROP_RW
double
perspectiveRemoveIgnoredMarginPerCell
;
CV_PROP_RW
double
maxErroneousBitsInBorderRate
;
CV_PROP_RW
double
minOtsuStdDev
;
CV_PROP_RW
double
errorCorrectionRate
;
};
...
...
@@ -171,9 +173,9 @@ struct CV_EXPORTS DetectorParameters {
* @sa estimatePoseSingleMarkers, estimatePoseBoard
*
*/
CV_EXPORTS
void
detectMarkers
(
InputArray
image
,
Dictionary
dictionary
,
OutputArrayOfArrays
corners
,
OutputArray
ids
,
DetectorParameters
parameters
=
DetectorParameters
(),
OutputArrayOfArrays
rejectedImgPoints
=
noArray
());
CV_EXPORTS
_W
void
detectMarkers
(
InputArray
image
,
Ptr
<
Dictionary
>
&
dictionary
,
OutputArrayOfArrays
corners
,
OutputArray
ids
,
const
Ptr
<
DetectorParameters
>
&
parameters
=
DetectorParameters
::
create
(),
OutputArrayOfArrays
rejectedImgPoints
=
noArray
());
...
...
@@ -205,9 +207,9 @@ CV_EXPORTS void detectMarkers(InputArray image, Dictionary dictionary, OutputArr
* (-markerLength/2, markerLength/2, 0), (markerLength/2, markerLength/2, 0),
* (markerLength/2, -markerLength/2, 0), (-markerLength/2, -markerLength/2, 0)
*/
CV_EXPORTS
void
estimatePoseSingleMarkers
(
InputArrayOfArrays
corners
,
float
markerLength
,
InputArray
cameraMatrix
,
InputArray
distCoeffs
,
OutputArrayOfArrays
rvecs
,
OutputArrayOfArrays
tvecs
);
CV_EXPORTS
_W
void
estimatePoseSingleMarkers
(
InputArrayOfArrays
corners
,
float
markerLength
,
InputArray
cameraMatrix
,
InputArray
distCoeffs
,
OutputArrayOfArrays
rvecs
,
OutputArrayOfArrays
tvecs
);
...
...
@@ -221,7 +223,7 @@ CV_EXPORTS void estimatePoseSingleMarkers(InputArrayOfArrays corners, float mark
* - The dictionary which indicates the type of markers of the board
* - The identifier of all the markers in the board.
*/
class
CV_EXPORTS
Board
{
class
CV_EXPORTS
_W
Board
{
public
:
// array of object points of all the marker corners in the board
...
...
@@ -229,7 +231,7 @@ class CV_EXPORTS Board {
std
::
vector
<
std
::
vector
<
Point3f
>
>
objPoints
;
// the dictionary of markers employed for this board
Dictionary
dictionary
;
Ptr
<
Dictionary
>
dictionary
;
// vector of the identifiers of the markers in the board (same size than objPoints)
// The identifiers refers to the board dictionary
...
...
@@ -243,7 +245,7 @@ class CV_EXPORTS Board {
* More common type of board. All markers are placed in the same plane in a grid arrangment.
* The board can be drawn using drawPlanarBoard() function (@sa drawPlanarBoard)
*/
class
CV_EXPORTS
GridBoard
:
public
Board
{
class
CV_EXPORTS
_W
GridBoard
:
public
Board
{
public
:
/**
...
...
@@ -274,8 +276,8 @@ class CV_EXPORTS GridBoard : public Board {
* This functions creates a GridBoard object given the number of markers in each direction and
* the marker size and marker separation.
*/
static
GridBoard
create
(
int
markersX
,
int
markersY
,
float
markerLength
,
float
markerSeparation
,
Dictionary
dictionary
);
CV_WRAP
static
Ptr
<
GridBoard
>
create
(
int
markersX
,
int
markersY
,
float
markerLength
,
float
markerSeparation
,
Ptr
<
Dictionary
>
&
dictionary
);
/**
*
...
...
@@ -332,9 +334,9 @@ class CV_EXPORTS GridBoard : public Board {
* The function returns the number of markers from the input employed for the board pose estimation.
* Note that returning a 0 means the pose has not been estimated.
*/
CV_EXPORTS
int
estimatePoseBoard
(
InputArrayOfArrays
corners
,
InputArray
ids
,
const
Board
&
board
,
InputArray
cameraMatrix
,
InputArray
distCoeffs
,
OutputArray
rvec
,
OutputArray
tvec
);
CV_EXPORTS
_W
int
estimatePoseBoard
(
InputArrayOfArrays
corners
,
InputArray
ids
,
Ptr
<
Board
>
&
board
,
InputArray
cameraMatrix
,
InputArray
distCoeffs
,
OutputArray
rvec
,
OutputArray
tvec
);
...
...
@@ -370,12 +372,12 @@ CV_EXPORTS int estimatePoseBoard(InputArrayOfArrays corners, InputArray ids, con
* using projectPoint function. If not, missing marker projections are interpolated using global
* homography, and all the marker corners in the board must have the same Z coordinate.
*/
CV_EXPORTS
void
refineDetectedMarkers
(
InputArray
image
,
const
Board
&
board
,
InputOutputArrayOfArrays
detectedCorners
,
CV_EXPORTS
_W
void
refineDetectedMarkers
(
InputArray
image
,
Ptr
<
Board
>
&
board
,
InputOutputArrayOfArrays
detectedCorners
,
InputOutputArray
detectedIds
,
InputOutputArray
rejectedCorners
,
InputArray
cameraMatrix
=
noArray
(),
InputArray
distCoeffs
=
noArray
(),
float
minRepDistance
=
10.
f
,
float
errorCorrectionRate
=
3.
f
,
bool
checkAllOrders
=
true
,
OutputArray
recoveredIdxs
=
noArray
(),
DetectorParameters
parameters
=
DetectorParameters
());
OutputArray
recoveredIdxs
=
noArray
(),
const
Ptr
<
DetectorParameters
>
&
parameters
=
DetectorParameters
::
create
());
...
...
@@ -396,9 +398,9 @@ CV_EXPORTS void refineDetectedMarkers(
* the markers in the image. The marker borders are painted and the markers identifiers if provided.
* Useful for debugging purposes.
*/
CV_EXPORTS
void
drawDetectedMarkers
(
InputOutputArray
image
,
InputArrayOfArrays
corners
,
InputArray
ids
=
noArray
(),
Scalar
borderColor
=
Scalar
(
0
,
255
,
0
));
CV_EXPORTS
_W
void
drawDetectedMarkers
(
InputOutputArray
image
,
InputArrayOfArrays
corners
,
InputArray
ids
=
noArray
(),
Scalar
borderColor
=
Scalar
(
0
,
255
,
0
));
...
...
@@ -418,8 +420,8 @@ CV_EXPORTS void drawDetectedMarkers(InputOutputArray image, InputArrayOfArrays c
* Given the pose estimation of a marker or board, this function draws the axis of the world
* coordinate system, i.e. the system centered on the marker/board. Useful for debugging purposes.
*/
CV_EXPORTS
void
drawAxis
(
InputOutputArray
image
,
InputArray
cameraMatrix
,
InputArray
distCoeffs
,
InputArray
rvec
,
InputArray
tvec
,
float
length
);
CV_EXPORTS
_W
void
drawAxis
(
InputOutputArray
image
,
InputArray
cameraMatrix
,
InputArray
distCoeffs
,
InputArray
rvec
,
InputArray
tvec
,
float
length
);
...
...
@@ -435,13 +437,14 @@ CV_EXPORTS void drawAxis(InputOutputArray image, InputArray cameraMatrix, InputA
*
* This function returns a marker image in its canonical form (i.e. ready to be printed)
*/
CV_EXPORTS
void
drawMarker
(
Dictionary
dictionary
,
int
id
,
int
sidePixels
,
OutputArray
img
,
int
borderBits
=
1
);
CV_EXPORTS
_W
void
drawMarker
(
Ptr
<
Dictionary
>
&
dictionary
,
int
id
,
int
sidePixels
,
OutputArray
img
,
int
borderBits
=
1
);
/**
* @brief Draw a planar board
* @sa _drawPlanarBoardImpl
*
* @param board layout of the board that will be drawn. The board should be planar,
* z coordinate is ignored
...
...
@@ -454,8 +457,16 @@ CV_EXPORTS void drawMarker(Dictionary dictionary, int id, int sidePixels, Output
* This function return the image of a planar board, ready to be printed. It assumes
* the Board layout specified is planar by ignoring the z coordinates of the object points.
*/
CV_EXPORTS
void
drawPlanarBoard
(
const
Board
&
board
,
Size
outSize
,
OutputArray
img
,
int
marginSize
=
0
,
int
borderBits
=
1
);
CV_EXPORTS_W
void
drawPlanarBoard
(
Ptr
<
Board
>
&
board
,
Size
outSize
,
OutputArray
img
,
int
marginSize
=
0
,
int
borderBits
=
1
);
/**
* @brief Implementation of drawPlanarBoard that accepts a raw Board pointer.
*/
void
_drawPlanarBoardImpl
(
Board
*
board
,
Size
outSize
,
OutputArray
img
,
int
marginSize
=
0
,
int
borderBits
=
1
);
...
...
@@ -487,8 +498,8 @@ CV_EXPORTS void drawPlanarBoard(const Board &board, Size outSize, OutputArray im
* detected markers from several views of the Board. The process is similar to the chessboard
* calibration in calibrateCamera(). The function returns the final re-projection error.
*/
CV_EXPORTS
double
calibrateCameraAruco
(
InputArrayOfArrays
corners
,
InputArray
ids
,
InputArray
counter
,
const
Board
&
board
,
CV_EXPORTS
_W
double
calibrateCameraAruco
(
InputArrayOfArrays
corners
,
InputArray
ids
,
InputArray
counter
,
Ptr
<
Board
>
&
board
,
Size
imageSize
,
InputOutputArray
cameraMatrix
,
InputOutputArray
distCoeffs
,
OutputArrayOfArrays
rvecs
=
noArray
(),
OutputArrayOfArrays
tvecs
=
noArray
(),
int
flags
=
0
,
TermCriteria
criteria
=
TermCriteria
(
TermCriteria
::
COUNT
+
TermCriteria
::
EPS
,
30
,
DBL_EPSILON
));
...
...
modules/aruco/include/opencv2/aruco/charuco.hpp
View file @
063c191d
...
...
@@ -59,7 +59,7 @@ namespace aruco {
* calibration and pose estimation.
* This class also allows the easy creation and drawing of ChArUco boards.
*/
class
CV_EXPORTS
CharucoBoard
:
public
Board
{
class
CV_EXPORTS
_W
CharucoBoard
:
public
Board
{
public
:
// vector of chessboard 3D corners precalculated
...
...
@@ -97,8 +97,8 @@ class CV_EXPORTS CharucoBoard : public Board {
* This functions creates a CharucoBoard object given the number of squares in each direction
* and the size of the markers and chessboard squares.
*/
static
CharucoBoard
create
(
int
squaresX
,
int
squaresY
,
float
squareLength
,
float
marker
Length
,
Dictionary
dictionary
);
CV_WRAP
static
Ptr
<
CharucoBoard
>
create
(
int
squaresX
,
int
squaresY
,
float
square
Length
,
float
markerLength
,
Ptr
<
Dictionary
>
&
dictionary
);
/**
*
...
...
@@ -154,11 +154,11 @@ class CV_EXPORTS CharucoBoard : public Board {
* also returned in charucoIds.
* The function returns the number of interpolated corners.
*/
CV_EXPORTS
int
interpolateCornersCharuco
(
InputArrayOfArrays
markerCorners
,
InputArray
markerIds
,
InputArray
image
,
const
CharucoBoard
&
board
,
OutputArray
charucoCorners
,
OutputArray
charucoIds
,
InputArray
cameraMatrix
=
noArray
(),
InputArray
distCoeffs
=
noArray
());
CV_EXPORTS
_W
int
interpolateCornersCharuco
(
InputArrayOfArrays
markerCorners
,
InputArray
markerIds
,
InputArray
image
,
Ptr
<
CharucoBoard
>
&
board
,
OutputArray
charucoCorners
,
OutputArray
charucoIds
,
InputArray
cameraMatrix
=
noArray
(),
InputArray
distCoeffs
=
noArray
());
...
...
@@ -180,9 +180,9 @@ CV_EXPORTS int interpolateCornersCharuco(InputArrayOfArrays markerCorners, Input
* The function checks if the input corners are enough and valid to perform pose estimation.
* If pose estimation is valid, returns true, else returns false.
*/
CV_EXPORTS
bool
estimatePoseCharucoBoard
(
InputArray
charucoCorners
,
InputArray
charucoIds
,
CharucoBoard
&
board
,
InputArray
cameraMatrix
,
InputArray
distCoeffs
,
OutputArray
rvec
,
OutputArray
tvec
);
CV_EXPORTS
_W
bool
estimatePoseCharucoBoard
(
InputArray
charucoCorners
,
InputArray
charucoIds
,
Ptr
<
CharucoBoard
>
&
board
,
InputArray
cameraMatrix
,
InputArray
distCoeffs
,
OutputArray
rvec
,
OutputArray
tvec
);
...
...
@@ -198,9 +198,9 @@ CV_EXPORTS bool estimatePoseCharucoBoard(InputArray charucoCorners, InputArray c
* This function draws a set of detected Charuco corners. If identifiers vector is provided, it also
* draws the id of each corner.
*/
CV_EXPORTS
void
drawDetectedCornersCharuco
(
InputOutputArray
image
,
InputArray
charucoCorners
,
InputArray
charucoIds
=
noArray
(),
Scalar
cornerColor
=
Scalar
(
255
,
0
,
0
));
CV_EXPORTS
_W
void
drawDetectedCornersCharuco
(
InputOutputArray
image
,
InputArray
charucoCorners
,
InputArray
charucoIds
=
noArray
(),
Scalar
cornerColor
=
Scalar
(
255
,
0
,
0
));
...
...
@@ -230,8 +230,8 @@ CV_EXPORTS void drawDetectedCornersCharuco(InputOutputArray image, InputArray ch
* receives a list of detected corners and its identifiers from several views of the Board.
* The function returns the final re-projection error.
*/
CV_EXPORTS
double
calibrateCameraCharuco
(
InputArrayOfArrays
charucoCorners
,
InputArrayOfArrays
charucoIds
,
const
CharucoBoard
&
board
,
CV_EXPORTS
_W
double
calibrateCameraCharuco
(
InputArrayOfArrays
charucoCorners
,
InputArrayOfArrays
charucoIds
,
Ptr
<
CharucoBoard
>
&
board
,
Size
imageSize
,
InputOutputArray
cameraMatrix
,
InputOutputArray
distCoeffs
,
OutputArrayOfArrays
rvecs
=
noArray
(),
OutputArrayOfArrays
tvecs
=
noArray
(),
int
flags
=
0
,
TermCriteria
criteria
=
TermCriteria
(
TermCriteria
::
COUNT
+
TermCriteria
::
EPS
,
30
,
DBL_EPSILON
));
...
...
@@ -261,11 +261,11 @@ CV_EXPORTS double calibrateCameraCharuco(
* are provided, the diamond search is based on reprojection. If not, diamond search is based on
* homography. Homography is faster than reprojection but can slightly reduce the detection rate.
*/
CV_EXPORTS
void
detectCharucoDiamond
(
InputArray
image
,
InputArrayOfArrays
markerCorners
,
InputArray
markerIds
,
float
squareMarkerLengthRate
,
OutputArrayOfArrays
diamondCorners
,
OutputArray
diamondIds
,
InputArray
cameraMatrix
=
noArray
(),
InputArray
distCoeffs
=
noArray
());
CV_EXPORTS
_W
void
detectCharucoDiamond
(
InputArray
image
,
InputArrayOfArrays
markerCorners
,
InputArray
markerIds
,
float
squareMarkerLengthRate
,
OutputArrayOfArrays
diamondCorners
,
OutputArray
diamondIds
,
InputArray
cameraMatrix
=
noArray
(),
InputArray
distCoeffs
=
noArray
());
...
...
@@ -287,9 +287,9 @@ CV_EXPORTS void detectCharucoDiamond(InputArray image, InputArrayOfArrays marker
* are painted and the markers identifiers if provided.
* Useful for debugging purposes.
*/
CV_EXPORTS
void
drawDetectedDiamonds
(
InputOutputArray
image
,
InputArrayOfArrays
diamondCorners
,
InputArray
diamondIds
=
noArray
(),
Scalar
borderColor
=
Scalar
(
0
,
0
,
255
));
CV_EXPORTS
_W
void
drawDetectedDiamonds
(
InputOutputArray
image
,
InputArrayOfArrays
diamondCorners
,
InputArray
diamondIds
=
noArray
(),
Scalar
borderColor
=
Scalar
(
0
,
0
,
255
));
...
...
@@ -308,7 +308,8 @@ CV_EXPORTS void drawDetectedDiamonds(InputOutputArray image, InputArrayOfArrays
*
* This function return the image of a ChArUco marker, ready to be printed.
*/
CV_EXPORTS
void
drawCharucoDiamond
(
Dictionary
dictionary
,
Vec4i
ids
,
int
squareLength
,
// TODO cannot be exported yet; conversion from/to Vec4i is not wrapped in core
CV_EXPORTS
void
drawCharucoDiamond
(
Ptr
<
Dictionary
>
&
dictionary
,
Vec4i
ids
,
int
squareLength
,
int
markerLength
,
OutputArray
img
,
int
marginSize
=
0
,
int
borderBits
=
1
);
...
...
modules/aruco/include/opencv2/aruco/dictionary.hpp
View file @
063c191d
...
...
@@ -58,12 +58,12 @@ namespace aruco {
*
* `bytesList.ptr(i)[k*nbytes + j]` is then the j-th byte of i-th marker, in its k-th rotation.
*/
class
CV_EXPORTS
Dictionary
{
class
CV_EXPORTS
_W
Dictionary
{
public
:
Mat
bytesList
;
// marker code information
int
markerSize
;
// number of bits per dimension
int
maxCorrectionBits
;
// maximum number of bits that can be corrected
CV_PROP_RW
Mat
bytesList
;
// marker code information
CV_PROP_RW
int
markerSize
;
// number of bits per dimension
CV_PROP_RW
int
maxCorrectionBits
;
// maximum number of bits that can be corrected
/**
...
...
@@ -71,6 +71,32 @@ class CV_EXPORTS Dictionary {
Dictionary
(
const
Mat
&
_bytesList
=
Mat
(),
int
_markerSize
=
0
,
int
_maxcorr
=
0
);
/**
Dictionary(const Dictionary &_dictionary);
*/
/**
*/
Dictionary
(
const
Ptr
<
Dictionary
>
&
_dictionary
);
/**
* @see generateCustomDictionary
*/
CV_WRAP_AS
(
create
)
static
Ptr
<
Dictionary
>
create
(
int
nMarkers
,
int
markerSize
);
/**
* @see generateCustomDictionary
*/
CV_WRAP_AS
(
create_from
)
static
Ptr
<
Dictionary
>
create
(
int
nMarkers
,
int
markerSize
,
Ptr
<
Dictionary
>
&
baseDictionary
);
/**
* @see getPredefinedDictionary
*/
CV_WRAP
static
Ptr
<
Dictionary
>
get
(
int
dict
);
/**
* @brief Given a matrix of bits. Returns whether if marker is identified or not.
...
...
@@ -109,9 +135,10 @@ class CV_EXPORTS Dictionary {
/**
* @brief Predefined markers dictionaries/sets
* Each dictionary indicates the number of bits and the number of markers contained
* - DICT_ARUCO: standard ArUco Library Markers. 1024 markers, 5x5 bits, 0 minimum distance
* - DICT_ARUCO_ORIGINAL: standard ArUco Library Markers. 1024 markers, 5x5 bits, 0 minimum
distance
*/
enum
PREDEFINED_DICTIONARY_NAME
{
enum
CV_EXPORTS_W_SIMPLE
PREDEFINED_DICTIONARY_NAME
{
DICT_4X4_50
=
0
,
DICT_4X4_100
,
DICT_4X4_250
,
...
...
@@ -135,7 +162,21 @@ enum PREDEFINED_DICTIONARY_NAME {
/**
* @brief Returns one of the predefined dictionaries defined in PREDEFINED_DICTIONARY_NAME
*/
CV_EXPORTS
const
Dictionary
&
getPredefinedDictionary
(
PREDEFINED_DICTIONARY_NAME
name
);
CV_EXPORTS
Ptr
<
Dictionary
>
getPredefinedDictionary
(
PREDEFINED_DICTIONARY_NAME
name
);
/**
* @brief Returns one of the predefined dictionaries referenced by DICT_*.
*/
CV_EXPORTS_W
Ptr
<
Dictionary
>
getPredefinedDictionary
(
int
dict
);
/**
* @see generateCustomDictionary
*/
CV_EXPORTS_AS
(
custom_dictionary
)
Ptr
<
Dictionary
>
generateCustomDictionary
(
int
nMarkers
,
int
markerSize
);
/**
...
...
@@ -150,8 +191,10 @@ CV_EXPORTS const Dictionary &getPredefinedDictionary(PREDEFINED_DICTIONARY_NAME
* included and the rest are generated based on them. If the size of baseDictionary is higher
* than nMarkers, only the first nMarkers in baseDictionary are taken and no new marker is added.
*/
CV_EXPORTS
Dictionary
generateCustomDictionary
(
int
nMarkers
,
int
markerSize
,
const
Dictionary
&
baseDictionary
=
Dictionary
());
CV_EXPORTS_AS
(
custom_dictionary_from
)
Ptr
<
Dictionary
>
generateCustomDictionary
(
int
nMarkers
,
int
markerSize
,
Ptr
<
Dictionary
>
&
baseDictionary
);
...
...
modules/aruco/samples/calibrate_camera.cpp
View file @
063c191d
...
...
@@ -76,30 +76,30 @@ const char* keys =
/**
*/
static
bool
readDetectorParameters
(
string
filename
,
aruco
::
DetectorParameters
&
params
)
{
static
bool
readDetectorParameters
(
string
filename
,
Ptr
<
aruco
::
DetectorParameters
>
&
params
)
{
FileStorage
fs
(
filename
,
FileStorage
::
READ
);
if
(
!
fs
.
isOpened
())
return
false
;
fs
[
"adaptiveThreshWinSizeMin"
]
>>
params
.
adaptiveThreshWinSizeMin
;
fs
[
"adaptiveThreshWinSizeMax"
]
>>
params
.
adaptiveThreshWinSizeMax
;
fs
[
"adaptiveThreshWinSizeStep"
]
>>
params
.
adaptiveThreshWinSizeStep
;
fs
[
"adaptiveThreshConstant"
]
>>
params
.
adaptiveThreshConstant
;
fs
[
"minMarkerPerimeterRate"
]
>>
params
.
minMarkerPerimeterRate
;
fs
[
"maxMarkerPerimeterRate"
]
>>
params
.
maxMarkerPerimeterRate
;
fs
[
"polygonalApproxAccuracyRate"
]
>>
params
.
polygonalApproxAccuracyRate
;
fs
[
"minCornerDistanceRate"
]
>>
params
.
minCornerDistanceRate
;
fs
[
"minDistanceToBorder"
]
>>
params
.
minDistanceToBorder
;
fs
[
"minMarkerDistanceRate"
]
>>
params
.
minMarkerDistanceRate
;
fs
[
"doCornerRefinement"
]
>>
params
.
doCornerRefinement
;
fs
[
"cornerRefinementWinSize"
]
>>
params
.
cornerRefinementWinSize
;
fs
[
"cornerRefinementMaxIterations"
]
>>
params
.
cornerRefinementMaxIterations
;
fs
[
"cornerRefinementMinAccuracy"
]
>>
params
.
cornerRefinementMinAccuracy
;
fs
[
"markerBorderBits"
]
>>
params
.
markerBorderBits
;
fs
[
"perspectiveRemovePixelPerCell"
]
>>
params
.
perspectiveRemovePixelPerCell
;
fs
[
"perspectiveRemoveIgnoredMarginPerCell"
]
>>
params
.
perspectiveRemoveIgnoredMarginPerCell
;
fs
[
"maxErroneousBitsInBorderRate"
]
>>
params
.
maxErroneousBitsInBorderRate
;
fs
[
"minOtsuStdDev"
]
>>
params
.
minOtsuStdDev
;
fs
[
"errorCorrectionRate"
]
>>
params
.
errorCorrectionRate
;
fs
[
"adaptiveThreshWinSizeMin"
]
>>
params
->
adaptiveThreshWinSizeMin
;
fs
[
"adaptiveThreshWinSizeMax"
]
>>
params
->
adaptiveThreshWinSizeMax
;
fs
[
"adaptiveThreshWinSizeStep"
]
>>
params
->
adaptiveThreshWinSizeStep
;
fs
[
"adaptiveThreshConstant"
]
>>
params
->
adaptiveThreshConstant
;
fs
[
"minMarkerPerimeterRate"
]
>>
params
->
minMarkerPerimeterRate
;
fs
[
"maxMarkerPerimeterRate"
]
>>
params
->
maxMarkerPerimeterRate
;
fs
[
"polygonalApproxAccuracyRate"
]
>>
params
->
polygonalApproxAccuracyRate
;
fs
[
"minCornerDistanceRate"
]
>>
params
->
minCornerDistanceRate
;
fs
[
"minDistanceToBorder"
]
>>
params
->
minDistanceToBorder
;
fs
[
"minMarkerDistanceRate"
]
>>
params
->
minMarkerDistanceRate
;
fs
[
"doCornerRefinement"
]
>>
params
->
doCornerRefinement
;
fs
[
"cornerRefinementWinSize"
]
>>
params
->
cornerRefinementWinSize
;
fs
[
"cornerRefinementMaxIterations"
]
>>
params
->
cornerRefinementMaxIterations
;
fs
[
"cornerRefinementMinAccuracy"
]
>>
params
->
cornerRefinementMinAccuracy
;
fs
[
"markerBorderBits"
]
>>
params
->
markerBorderBits
;
fs
[
"perspectiveRemovePixelPerCell"
]
>>
params
->
perspectiveRemovePixelPerCell
;
fs
[
"perspectiveRemoveIgnoredMarginPerCell"
]
>>
params
->
perspectiveRemoveIgnoredMarginPerCell
;
fs
[
"maxErroneousBitsInBorderRate"
]
>>
params
->
maxErroneousBitsInBorderRate
;
fs
[
"minOtsuStdDev"
]
>>
params
->
minOtsuStdDev
;
fs
[
"errorCorrectionRate"
]
>>
params
->
errorCorrectionRate
;
return
true
;
}
...
...
@@ -173,7 +173,7 @@ int main(int argc, char *argv[]) {
if
(
parser
.
get
<
bool
>
(
"zt"
))
calibrationFlags
|=
CALIB_ZERO_TANGENT_DIST
;
if
(
parser
.
get
<
bool
>
(
"pc"
))
calibrationFlags
|=
CALIB_FIX_PRINCIPAL_POINT
;
aruco
::
DetectorParameters
detectorParams
;
Ptr
<
aruco
::
DetectorParameters
>
detectorParams
=
aruco
::
DetectorParameters
::
create
()
;
if
(
parser
.
has
(
"dp"
))
{
bool
readOk
=
readDetectorParameters
(
parser
.
get
<
string
>
(
"dp"
),
detectorParams
);
if
(
!
readOk
)
{
...
...
@@ -205,12 +205,13 @@ int main(int argc, char *argv[]) {
waitTime
=
10
;
}
aruco
::
Dictionary
dictionary
=
Ptr
<
aruco
::
Dictionary
>
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
PREDEFINED_DICTIONARY_NAME
(
dictionaryId
));
// create board object
aruco
::
GridBoard
board
=
aruco
::
GridBoard
::
create
(
markersX
,
markersY
,
markerLength
,
markerSeparation
,
dictionary
);
Ptr
<
aruco
::
GridBoard
>
gridboard
=
aruco
::
GridBoard
::
create
(
markersX
,
markersY
,
markerLength
,
markerSeparation
,
dictionary
);
Ptr
<
aruco
::
Board
>
board
=
gridboard
.
staticCast
<
aruco
::
Board
>
();
// collected frames for calibration
vector
<
vector
<
vector
<
Point2f
>
>
>
allCorners
;
...
...
modules/aruco/samples/calibrate_camera_charuco.cpp
View file @
063c191d
...
...
@@ -76,30 +76,30 @@ const char* keys =
/**
*/
static
bool
readDetectorParameters
(
string
filename
,
aruco
::
DetectorParameters
&
params
)
{
static
bool
readDetectorParameters
(
string
filename
,
Ptr
<
aruco
::
DetectorParameters
>
&
params
)
{
FileStorage
fs
(
filename
,
FileStorage
::
READ
);
if
(
!
fs
.
isOpened
())
return
false
;
fs
[
"adaptiveThreshWinSizeMin"
]
>>
params
.
adaptiveThreshWinSizeMin
;
fs
[
"adaptiveThreshWinSizeMax"
]
>>
params
.
adaptiveThreshWinSizeMax
;
fs
[
"adaptiveThreshWinSizeStep"
]
>>
params
.
adaptiveThreshWinSizeStep
;
fs
[
"adaptiveThreshConstant"
]
>>
params
.
adaptiveThreshConstant
;
fs
[
"minMarkerPerimeterRate"
]
>>
params
.
minMarkerPerimeterRate
;
fs
[
"maxMarkerPerimeterRate"
]
>>
params
.
maxMarkerPerimeterRate
;
fs
[
"polygonalApproxAccuracyRate"
]
>>
params
.
polygonalApproxAccuracyRate
;
fs
[
"minCornerDistanceRate"
]
>>
params
.
minCornerDistanceRate
;
fs
[
"minDistanceToBorder"
]
>>
params
.
minDistanceToBorder
;
fs
[
"minMarkerDistanceRate"
]
>>
params
.
minMarkerDistanceRate
;
fs
[
"doCornerRefinement"
]
>>
params
.
doCornerRefinement
;
fs
[
"cornerRefinementWinSize"
]
>>
params
.
cornerRefinementWinSize
;
fs
[
"cornerRefinementMaxIterations"
]
>>
params
.
cornerRefinementMaxIterations
;
fs
[
"cornerRefinementMinAccuracy"
]
>>
params
.
cornerRefinementMinAccuracy
;
fs
[
"markerBorderBits"
]
>>
params
.
markerBorderBits
;
fs
[
"perspectiveRemovePixelPerCell"
]
>>
params
.
perspectiveRemovePixelPerCell
;
fs
[
"perspectiveRemoveIgnoredMarginPerCell"
]
>>
params
.
perspectiveRemoveIgnoredMarginPerCell
;
fs
[
"maxErroneousBitsInBorderRate"
]
>>
params
.
maxErroneousBitsInBorderRate
;
fs
[
"minOtsuStdDev"
]
>>
params
.
minOtsuStdDev
;
fs
[
"errorCorrectionRate"
]
>>
params
.
errorCorrectionRate
;
fs
[
"adaptiveThreshWinSizeMin"
]
>>
params
->
adaptiveThreshWinSizeMin
;
fs
[
"adaptiveThreshWinSizeMax"
]
>>
params
->
adaptiveThreshWinSizeMax
;
fs
[
"adaptiveThreshWinSizeStep"
]
>>
params
->
adaptiveThreshWinSizeStep
;
fs
[
"adaptiveThreshConstant"
]
>>
params
->
adaptiveThreshConstant
;
fs
[
"minMarkerPerimeterRate"
]
>>
params
->
minMarkerPerimeterRate
;
fs
[
"maxMarkerPerimeterRate"
]
>>
params
->
maxMarkerPerimeterRate
;
fs
[
"polygonalApproxAccuracyRate"
]
>>
params
->
polygonalApproxAccuracyRate
;
fs
[
"minCornerDistanceRate"
]
>>
params
->
minCornerDistanceRate
;
fs
[
"minDistanceToBorder"
]
>>
params
->
minDistanceToBorder
;
fs
[
"minMarkerDistanceRate"
]
>>
params
->
minMarkerDistanceRate
;
fs
[
"doCornerRefinement"
]
>>
params
->
doCornerRefinement
;
fs
[
"cornerRefinementWinSize"
]
>>
params
->
cornerRefinementWinSize
;
fs
[
"cornerRefinementMaxIterations"
]
>>
params
->
cornerRefinementMaxIterations
;
fs
[
"cornerRefinementMinAccuracy"
]
>>
params
->
cornerRefinementMinAccuracy
;
fs
[
"markerBorderBits"
]
>>
params
->
markerBorderBits
;
fs
[
"perspectiveRemovePixelPerCell"
]
>>
params
->
perspectiveRemovePixelPerCell
;
fs
[
"perspectiveRemoveIgnoredMarginPerCell"
]
>>
params
->
perspectiveRemoveIgnoredMarginPerCell
;
fs
[
"maxErroneousBitsInBorderRate"
]
>>
params
->
maxErroneousBitsInBorderRate
;
fs
[
"minOtsuStdDev"
]
>>
params
->
minOtsuStdDev
;
fs
[
"errorCorrectionRate"
]
>>
params
->
errorCorrectionRate
;
return
true
;
}
...
...
@@ -175,7 +175,7 @@ int main(int argc, char *argv[]) {
if
(
parser
.
get
<
bool
>
(
"zt"
))
calibrationFlags
|=
CALIB_ZERO_TANGENT_DIST
;
if
(
parser
.
get
<
bool
>
(
"pc"
))
calibrationFlags
|=
CALIB_FIX_PRINCIPAL_POINT
;
aruco
::
DetectorParameters
detectorParams
;
Ptr
<
aruco
::
DetectorParameters
>
detectorParams
=
aruco
::
DetectorParameters
::
create
()
;
if
(
parser
.
has
(
"dp"
))
{
bool
readOk
=
readDetectorParameters
(
parser
.
get
<
string
>
(
"dp"
),
detectorParams
);
if
(
!
readOk
)
{
...
...
@@ -207,12 +207,13 @@ int main(int argc, char *argv[]) {
waitTime
=
10
;
}
aruco
::
Dictionary
dictionary
=
Ptr
<
aruco
::
Dictionary
>
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
PREDEFINED_DICTIONARY_NAME
(
dictionaryId
));
// create charuco board object
aruco
::
CharucoBoard
board
=
aruco
::
CharucoBoard
::
create
(
squaresX
,
squaresY
,
squareLength
,
markerLength
,
dictionary
);
Ptr
<
aruco
::
CharucoBoard
>
charucoboard
=
aruco
::
CharucoBoard
::
create
(
squaresX
,
squaresY
,
squareLength
,
markerLength
,
dictionary
);
Ptr
<
aruco
::
Board
>
board
=
charucoboard
.
staticCast
<
aruco
::
Board
>
();
// collect data from each frame
vector
<
vector
<
vector
<
Point2f
>
>
>
allCorners
;
...
...
@@ -236,7 +237,7 @@ int main(int argc, char *argv[]) {
// interpolate charuco corners
Mat
currentCharucoCorners
,
currentCharucoIds
;
if
(
ids
.
size
()
>
0
)
aruco
::
interpolateCornersCharuco
(
corners
,
ids
,
image
,
board
,
currentCharucoCorners
,
aruco
::
interpolateCornersCharuco
(
corners
,
ids
,
image
,
charuco
board
,
currentCharucoCorners
,
currentCharucoIds
);
// draw results
...
...
@@ -305,7 +306,7 @@ int main(int argc, char *argv[]) {
for
(
int
i
=
0
;
i
<
nFrames
;
i
++
)
{
// interpolate using camera parameters
Mat
currentCharucoCorners
,
currentCharucoIds
;
aruco
::
interpolateCornersCharuco
(
allCorners
[
i
],
allIds
[
i
],
allImgs
[
i
],
board
,
aruco
::
interpolateCornersCharuco
(
allCorners
[
i
],
allIds
[
i
],
allImgs
[
i
],
charuco
board
,
currentCharucoCorners
,
currentCharucoIds
,
cameraMatrix
,
distCoeffs
);
...
...
@@ -321,7 +322,7 @@ int main(int argc, char *argv[]) {
// calibrate camera using charuco
repError
=
aruco
::
calibrateCameraCharuco
(
allCharucoCorners
,
allCharucoIds
,
board
,
imgSize
,
aruco
::
calibrateCameraCharuco
(
allCharucoCorners
,
allCharucoIds
,
charuco
board
,
imgSize
,
cameraMatrix
,
distCoeffs
,
rvecs
,
tvecs
,
calibrationFlags
);
bool
saveOk
=
saveCameraParams
(
outputFile
,
imgSize
,
aspectRatio
,
calibrationFlags
,
...
...
modules/aruco/samples/create_board.cpp
View file @
063c191d
...
...
@@ -93,15 +93,15 @@ int main(int argc, char *argv[]) {
imageSize
.
height
=
markersY
*
(
markerLength
+
markerSeparation
)
-
markerSeparation
+
2
*
margins
;
aruco
::
Dictionary
dictionary
=
Ptr
<
aruco
::
Dictionary
>
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
PREDEFINED_DICTIONARY_NAME
(
dictionaryId
));
aruco
::
GridBoard
board
=
aruco
::
GridBoard
::
create
(
markersX
,
markersY
,
float
(
markerLength
),
Ptr
<
aruco
::
GridBoard
>
board
=
aruco
::
GridBoard
::
create
(
markersX
,
markersY
,
float
(
markerLength
),
float
(
markerSeparation
),
dictionary
);
// show created board
Mat
boardImage
;
board
.
draw
(
imageSize
,
boardImage
,
margins
,
borderBits
);
board
->
draw
(
imageSize
,
boardImage
,
margins
,
borderBits
);
if
(
showImage
)
{
imshow
(
"board"
,
boardImage
);
...
...
modules/aruco/samples/create_board_charuco.cpp
View file @
063c191d
...
...
@@ -88,19 +88,19 @@ int main(int argc, char *argv[]) {
return
0
;
}
aruco
::
Dictionary
dictionary
=
Ptr
<
aruco
::
Dictionary
>
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
PREDEFINED_DICTIONARY_NAME
(
dictionaryId
));
Size
imageSize
;
imageSize
.
width
=
squaresX
*
squareLength
+
2
*
margins
;
imageSize
.
height
=
squaresY
*
squareLength
+
2
*
margins
;
aruco
::
CharucoBoard
board
=
aruco
::
CharucoBoard
::
create
(
squaresX
,
squaresY
,
(
float
)
squareLength
,
Ptr
<
aruco
::
CharucoBoard
>
board
=
aruco
::
CharucoBoard
::
create
(
squaresX
,
squaresY
,
(
float
)
squareLength
,
(
float
)
markerLength
,
dictionary
);
// show created board
Mat
boardImage
;
board
.
draw
(
imageSize
,
boardImage
,
margins
,
borderBits
);
board
->
draw
(
imageSize
,
boardImage
,
margins
,
borderBits
);
if
(
showImage
)
{
imshow
(
"board"
,
boardImage
);
...
...
modules/aruco/samples/create_diamond.cpp
View file @
063c191d
...
...
@@ -86,7 +86,7 @@ int main(int argc, char *argv[]) {
return
0
;
}
aruco
::
Dictionary
dictionary
=
Ptr
<
aruco
::
Dictionary
>
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
PREDEFINED_DICTIONARY_NAME
(
dictionaryId
));
istringstream
ss
(
idsString
);
...
...
modules/aruco/samples/create_marker.cpp
View file @
063c191d
...
...
@@ -79,7 +79,7 @@ int main(int argc, char *argv[]) {
return
0
;
}
aruco
::
Dictionary
dictionary
=
Ptr
<
aruco
::
Dictionary
>
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
PREDEFINED_DICTIONARY_NAME
(
dictionaryId
));
Mat
markerImg
;
...
...
modules/aruco/samples/detect_board.cpp
View file @
063c191d
...
...
@@ -79,30 +79,30 @@ static bool readCameraParameters(string filename, Mat &camMatrix, Mat &distCoeff
/**
*/
static
bool
readDetectorParameters
(
string
filename
,
aruco
::
DetectorParameters
&
params
)
{
static
bool
readDetectorParameters
(
string
filename
,
Ptr
<
aruco
::
DetectorParameters
>
&
params
)
{
FileStorage
fs
(
filename
,
FileStorage
::
READ
);
if
(
!
fs
.
isOpened
())
return
false
;
fs
[
"adaptiveThreshWinSizeMin"
]
>>
params
.
adaptiveThreshWinSizeMin
;
fs
[
"adaptiveThreshWinSizeMax"
]
>>
params
.
adaptiveThreshWinSizeMax
;
fs
[
"adaptiveThreshWinSizeStep"
]
>>
params
.
adaptiveThreshWinSizeStep
;
fs
[
"adaptiveThreshConstant"
]
>>
params
.
adaptiveThreshConstant
;
fs
[
"minMarkerPerimeterRate"
]
>>
params
.
minMarkerPerimeterRate
;
fs
[
"maxMarkerPerimeterRate"
]
>>
params
.
maxMarkerPerimeterRate
;
fs
[
"polygonalApproxAccuracyRate"
]
>>
params
.
polygonalApproxAccuracyRate
;
fs
[
"minCornerDistanceRate"
]
>>
params
.
minCornerDistanceRate
;
fs
[
"minDistanceToBorder"
]
>>
params
.
minDistanceToBorder
;
fs
[
"minMarkerDistanceRate"
]
>>
params
.
minMarkerDistanceRate
;
fs
[
"doCornerRefinement"
]
>>
params
.
doCornerRefinement
;
fs
[
"cornerRefinementWinSize"
]
>>
params
.
cornerRefinementWinSize
;
fs
[
"cornerRefinementMaxIterations"
]
>>
params
.
cornerRefinementMaxIterations
;
fs
[
"cornerRefinementMinAccuracy"
]
>>
params
.
cornerRefinementMinAccuracy
;
fs
[
"markerBorderBits"
]
>>
params
.
markerBorderBits
;
fs
[
"perspectiveRemovePixelPerCell"
]
>>
params
.
perspectiveRemovePixelPerCell
;
fs
[
"perspectiveRemoveIgnoredMarginPerCell"
]
>>
params
.
perspectiveRemoveIgnoredMarginPerCell
;
fs
[
"maxErroneousBitsInBorderRate"
]
>>
params
.
maxErroneousBitsInBorderRate
;
fs
[
"minOtsuStdDev"
]
>>
params
.
minOtsuStdDev
;
fs
[
"errorCorrectionRate"
]
>>
params
.
errorCorrectionRate
;
fs
[
"adaptiveThreshWinSizeMin"
]
>>
params
->
adaptiveThreshWinSizeMin
;
fs
[
"adaptiveThreshWinSizeMax"
]
>>
params
->
adaptiveThreshWinSizeMax
;
fs
[
"adaptiveThreshWinSizeStep"
]
>>
params
->
adaptiveThreshWinSizeStep
;
fs
[
"adaptiveThreshConstant"
]
>>
params
->
adaptiveThreshConstant
;
fs
[
"minMarkerPerimeterRate"
]
>>
params
->
minMarkerPerimeterRate
;
fs
[
"maxMarkerPerimeterRate"
]
>>
params
->
maxMarkerPerimeterRate
;
fs
[
"polygonalApproxAccuracyRate"
]
>>
params
->
polygonalApproxAccuracyRate
;
fs
[
"minCornerDistanceRate"
]
>>
params
->
minCornerDistanceRate
;
fs
[
"minDistanceToBorder"
]
>>
params
->
minDistanceToBorder
;
fs
[
"minMarkerDistanceRate"
]
>>
params
->
minMarkerDistanceRate
;
fs
[
"doCornerRefinement"
]
>>
params
->
doCornerRefinement
;
fs
[
"cornerRefinementWinSize"
]
>>
params
->
cornerRefinementWinSize
;
fs
[
"cornerRefinementMaxIterations"
]
>>
params
->
cornerRefinementMaxIterations
;
fs
[
"cornerRefinementMinAccuracy"
]
>>
params
->
cornerRefinementMinAccuracy
;
fs
[
"markerBorderBits"
]
>>
params
->
markerBorderBits
;
fs
[
"perspectiveRemovePixelPerCell"
]
>>
params
->
perspectiveRemovePixelPerCell
;
fs
[
"perspectiveRemoveIgnoredMarginPerCell"
]
>>
params
->
perspectiveRemoveIgnoredMarginPerCell
;
fs
[
"maxErroneousBitsInBorderRate"
]
>>
params
->
maxErroneousBitsInBorderRate
;
fs
[
"minOtsuStdDev"
]
>>
params
->
minOtsuStdDev
;
fs
[
"errorCorrectionRate"
]
>>
params
->
errorCorrectionRate
;
return
true
;
}
...
...
@@ -137,7 +137,7 @@ int main(int argc, char *argv[]) {
}
}
aruco
::
DetectorParameters
detectorParams
;
Ptr
<
aruco
::
DetectorParameters
>
detectorParams
=
aruco
::
DetectorParameters
::
create
()
;
if
(
parser
.
has
(
"dp"
))
{
bool
readOk
=
readDetectorParameters
(
parser
.
get
<
string
>
(
"dp"
),
detectorParams
);
if
(
!
readOk
)
{
...
...
@@ -145,7 +145,7 @@ int main(int argc, char *argv[]) {
return
0
;
}
}
detectorParams
.
doCornerRefinement
=
true
;
// do corner refinement in markers
detectorParams
->
doCornerRefinement
=
true
;
// do corner refinement in markers
String
video
;
if
(
parser
.
has
(
"v"
))
{
...
...
@@ -157,7 +157,7 @@ int main(int argc, char *argv[]) {
return
0
;
}
aruco
::
Dictionary
dictionary
=
Ptr
<
aruco
::
Dictionary
>
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
PREDEFINED_DICTIONARY_NAME
(
dictionaryId
));
VideoCapture
inputVideo
;
...
...
@@ -174,8 +174,9 @@ int main(int argc, char *argv[]) {
markerSeparation
);
// create board object
aruco
::
GridBoard
board
=
Ptr
<
aruco
::
GridBoard
>
grid
board
=
aruco
::
GridBoard
::
create
(
markersX
,
markersY
,
markerLength
,
markerSeparation
,
dictionary
);
Ptr
<
aruco
::
Board
>
board
=
gridboard
.
staticCast
<
aruco
::
Board
>
();
double
totalTime
=
0
;
int
totalIterations
=
0
;
...
...
modules/aruco/samples/detect_board_charuco.cpp
View file @
063c191d
...
...
@@ -79,30 +79,30 @@ static bool readCameraParameters(string filename, Mat &camMatrix, Mat &distCoeff
/**
*/
static
bool
readDetectorParameters
(
string
filename
,
aruco
::
DetectorParameters
&
params
)
{
static
bool
readDetectorParameters
(
string
filename
,
Ptr
<
aruco
::
DetectorParameters
>
&
params
)
{
FileStorage
fs
(
filename
,
FileStorage
::
READ
);
if
(
!
fs
.
isOpened
())
return
false
;
fs
[
"adaptiveThreshWinSizeMin"
]
>>
params
.
adaptiveThreshWinSizeMin
;
fs
[
"adaptiveThreshWinSizeMax"
]
>>
params
.
adaptiveThreshWinSizeMax
;
fs
[
"adaptiveThreshWinSizeStep"
]
>>
params
.
adaptiveThreshWinSizeStep
;
fs
[
"adaptiveThreshConstant"
]
>>
params
.
adaptiveThreshConstant
;
fs
[
"minMarkerPerimeterRate"
]
>>
params
.
minMarkerPerimeterRate
;
fs
[
"maxMarkerPerimeterRate"
]
>>
params
.
maxMarkerPerimeterRate
;
fs
[
"polygonalApproxAccuracyRate"
]
>>
params
.
polygonalApproxAccuracyRate
;
fs
[
"minCornerDistanceRate"
]
>>
params
.
minCornerDistanceRate
;
fs
[
"minDistanceToBorder"
]
>>
params
.
minDistanceToBorder
;
fs
[
"minMarkerDistanceRate"
]
>>
params
.
minMarkerDistanceRate
;
fs
[
"doCornerRefinement"
]
>>
params
.
doCornerRefinement
;
fs
[
"cornerRefinementWinSize"
]
>>
params
.
cornerRefinementWinSize
;
fs
[
"cornerRefinementMaxIterations"
]
>>
params
.
cornerRefinementMaxIterations
;
fs
[
"cornerRefinementMinAccuracy"
]
>>
params
.
cornerRefinementMinAccuracy
;
fs
[
"markerBorderBits"
]
>>
params
.
markerBorderBits
;
fs
[
"perspectiveRemovePixelPerCell"
]
>>
params
.
perspectiveRemovePixelPerCell
;
fs
[
"perspectiveRemoveIgnoredMarginPerCell"
]
>>
params
.
perspectiveRemoveIgnoredMarginPerCell
;
fs
[
"maxErroneousBitsInBorderRate"
]
>>
params
.
maxErroneousBitsInBorderRate
;
fs
[
"minOtsuStdDev"
]
>>
params
.
minOtsuStdDev
;
fs
[
"errorCorrectionRate"
]
>>
params
.
errorCorrectionRate
;
fs
[
"adaptiveThreshWinSizeMin"
]
>>
params
->
adaptiveThreshWinSizeMin
;
fs
[
"adaptiveThreshWinSizeMax"
]
>>
params
->
adaptiveThreshWinSizeMax
;
fs
[
"adaptiveThreshWinSizeStep"
]
>>
params
->
adaptiveThreshWinSizeStep
;
fs
[
"adaptiveThreshConstant"
]
>>
params
->
adaptiveThreshConstant
;
fs
[
"minMarkerPerimeterRate"
]
>>
params
->
minMarkerPerimeterRate
;
fs
[
"maxMarkerPerimeterRate"
]
>>
params
->
maxMarkerPerimeterRate
;
fs
[
"polygonalApproxAccuracyRate"
]
>>
params
->
polygonalApproxAccuracyRate
;
fs
[
"minCornerDistanceRate"
]
>>
params
->
minCornerDistanceRate
;
fs
[
"minDistanceToBorder"
]
>>
params
->
minDistanceToBorder
;
fs
[
"minMarkerDistanceRate"
]
>>
params
->
minMarkerDistanceRate
;
fs
[
"doCornerRefinement"
]
>>
params
->
doCornerRefinement
;
fs
[
"cornerRefinementWinSize"
]
>>
params
->
cornerRefinementWinSize
;
fs
[
"cornerRefinementMaxIterations"
]
>>
params
->
cornerRefinementMaxIterations
;
fs
[
"cornerRefinementMinAccuracy"
]
>>
params
->
cornerRefinementMinAccuracy
;
fs
[
"markerBorderBits"
]
>>
params
->
markerBorderBits
;
fs
[
"perspectiveRemovePixelPerCell"
]
>>
params
->
perspectiveRemovePixelPerCell
;
fs
[
"perspectiveRemoveIgnoredMarginPerCell"
]
>>
params
->
perspectiveRemoveIgnoredMarginPerCell
;
fs
[
"maxErroneousBitsInBorderRate"
]
>>
params
->
maxErroneousBitsInBorderRate
;
fs
[
"minOtsuStdDev"
]
>>
params
->
minOtsuStdDev
;
fs
[
"errorCorrectionRate"
]
>>
params
->
errorCorrectionRate
;
return
true
;
}
...
...
@@ -141,7 +141,7 @@ int main(int argc, char *argv[]) {
}
}
aruco
::
DetectorParameters
detectorParams
;
Ptr
<
aruco
::
DetectorParameters
>
detectorParams
=
aruco
::
DetectorParameters
::
create
()
;
if
(
parser
.
has
(
"dp"
))
{
bool
readOk
=
readDetectorParameters
(
parser
.
get
<
string
>
(
"dp"
),
detectorParams
);
if
(
!
readOk
)
{
...
...
@@ -155,7 +155,7 @@ int main(int argc, char *argv[]) {
return
0
;
}
aruco
::
Dictionary
dictionary
=
Ptr
<
aruco
::
Dictionary
>
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
PREDEFINED_DICTIONARY_NAME
(
dictionaryId
));
VideoCapture
inputVideo
;
...
...
@@ -171,8 +171,9 @@ int main(int argc, char *argv[]) {
float
axisLength
=
0.5
f
*
((
float
)
min
(
squaresX
,
squaresY
)
*
(
squareLength
));
// create charuco board object
aruco
::
CharucoBoard
board
=
Ptr
<
aruco
::
CharucoBoard
>
charuco
board
=
aruco
::
CharucoBoard
::
create
(
squaresX
,
squaresY
,
squareLength
,
markerLength
,
dictionary
);
Ptr
<
aruco
::
Board
>
board
=
charucoboard
.
staticCast
<
aruco
::
Board
>
();
double
totalTime
=
0
;
int
totalIterations
=
0
;
...
...
@@ -201,13 +202,13 @@ int main(int argc, char *argv[]) {
int
interpolatedCorners
=
0
;
if
(
markerIds
.
size
()
>
0
)
interpolatedCorners
=
aruco
::
interpolateCornersCharuco
(
markerCorners
,
markerIds
,
image
,
board
,
aruco
::
interpolateCornersCharuco
(
markerCorners
,
markerIds
,
image
,
charuco
board
,
charucoCorners
,
charucoIds
,
camMatrix
,
distCoeffs
);
// estimate charuco board pose
bool
validPose
=
false
;
if
(
camMatrix
.
total
()
!=
0
)
validPose
=
aruco
::
estimatePoseCharucoBoard
(
charucoCorners
,
charucoIds
,
board
,
validPose
=
aruco
::
estimatePoseCharucoBoard
(
charucoCorners
,
charucoIds
,
charuco
board
,
camMatrix
,
distCoeffs
,
rvec
,
tvec
);
...
...
modules/aruco/samples/detect_diamonds.cpp
View file @
063c191d
...
...
@@ -80,30 +80,30 @@ static bool readCameraParameters(string filename, Mat &camMatrix, Mat &distCoeff
/**
*/
static
bool
readDetectorParameters
(
string
filename
,
aruco
::
DetectorParameters
&
params
)
{
static
bool
readDetectorParameters
(
string
filename
,
Ptr
<
aruco
::
DetectorParameters
>
&
params
)
{
FileStorage
fs
(
filename
,
FileStorage
::
READ
);
if
(
!
fs
.
isOpened
())
return
false
;
fs
[
"adaptiveThreshWinSizeMin"
]
>>
params
.
adaptiveThreshWinSizeMin
;
fs
[
"adaptiveThreshWinSizeMax"
]
>>
params
.
adaptiveThreshWinSizeMax
;
fs
[
"adaptiveThreshWinSizeStep"
]
>>
params
.
adaptiveThreshWinSizeStep
;
fs
[
"adaptiveThreshConstant"
]
>>
params
.
adaptiveThreshConstant
;
fs
[
"minMarkerPerimeterRate"
]
>>
params
.
minMarkerPerimeterRate
;
fs
[
"maxMarkerPerimeterRate"
]
>>
params
.
maxMarkerPerimeterRate
;
fs
[
"polygonalApproxAccuracyRate"
]
>>
params
.
polygonalApproxAccuracyRate
;
fs
[
"minCornerDistanceRate"
]
>>
params
.
minCornerDistanceRate
;
fs
[
"minDistanceToBorder"
]
>>
params
.
minDistanceToBorder
;
fs
[
"minMarkerDistanceRate"
]
>>
params
.
minMarkerDistanceRate
;
fs
[
"doCornerRefinement"
]
>>
params
.
doCornerRefinement
;
fs
[
"cornerRefinementWinSize"
]
>>
params
.
cornerRefinementWinSize
;
fs
[
"cornerRefinementMaxIterations"
]
>>
params
.
cornerRefinementMaxIterations
;
fs
[
"cornerRefinementMinAccuracy"
]
>>
params
.
cornerRefinementMinAccuracy
;
fs
[
"markerBorderBits"
]
>>
params
.
markerBorderBits
;
fs
[
"perspectiveRemovePixelPerCell"
]
>>
params
.
perspectiveRemovePixelPerCell
;
fs
[
"perspectiveRemoveIgnoredMarginPerCell"
]
>>
params
.
perspectiveRemoveIgnoredMarginPerCell
;
fs
[
"maxErroneousBitsInBorderRate"
]
>>
params
.
maxErroneousBitsInBorderRate
;
fs
[
"minOtsuStdDev"
]
>>
params
.
minOtsuStdDev
;
fs
[
"errorCorrectionRate"
]
>>
params
.
errorCorrectionRate
;
fs
[
"adaptiveThreshWinSizeMin"
]
>>
params
->
adaptiveThreshWinSizeMin
;
fs
[
"adaptiveThreshWinSizeMax"
]
>>
params
->
adaptiveThreshWinSizeMax
;
fs
[
"adaptiveThreshWinSizeStep"
]
>>
params
->
adaptiveThreshWinSizeStep
;
fs
[
"adaptiveThreshConstant"
]
>>
params
->
adaptiveThreshConstant
;
fs
[
"minMarkerPerimeterRate"
]
>>
params
->
minMarkerPerimeterRate
;
fs
[
"maxMarkerPerimeterRate"
]
>>
params
->
maxMarkerPerimeterRate
;
fs
[
"polygonalApproxAccuracyRate"
]
>>
params
->
polygonalApproxAccuracyRate
;
fs
[
"minCornerDistanceRate"
]
>>
params
->
minCornerDistanceRate
;
fs
[
"minDistanceToBorder"
]
>>
params
->
minDistanceToBorder
;
fs
[
"minMarkerDistanceRate"
]
>>
params
->
minMarkerDistanceRate
;
fs
[
"doCornerRefinement"
]
>>
params
->
doCornerRefinement
;
fs
[
"cornerRefinementWinSize"
]
>>
params
->
cornerRefinementWinSize
;
fs
[
"cornerRefinementMaxIterations"
]
>>
params
->
cornerRefinementMaxIterations
;
fs
[
"cornerRefinementMinAccuracy"
]
>>
params
->
cornerRefinementMinAccuracy
;
fs
[
"markerBorderBits"
]
>>
params
->
markerBorderBits
;
fs
[
"perspectiveRemovePixelPerCell"
]
>>
params
->
perspectiveRemovePixelPerCell
;
fs
[
"perspectiveRemoveIgnoredMarginPerCell"
]
>>
params
->
perspectiveRemoveIgnoredMarginPerCell
;
fs
[
"maxErroneousBitsInBorderRate"
]
>>
params
->
maxErroneousBitsInBorderRate
;
fs
[
"minOtsuStdDev"
]
>>
params
->
minOtsuStdDev
;
fs
[
"errorCorrectionRate"
]
>>
params
->
errorCorrectionRate
;
return
true
;
}
...
...
@@ -127,7 +127,7 @@ int main(int argc, char *argv[]) {
bool
autoScale
=
parser
.
has
(
"as"
);
float
autoScaleFactor
=
autoScale
?
parser
.
get
<
float
>
(
"as"
)
:
1.
f
;
aruco
::
DetectorParameters
detectorParams
;
Ptr
<
aruco
::
DetectorParameters
>
detectorParams
=
aruco
::
DetectorParameters
::
create
()
;
if
(
parser
.
has
(
"dp"
))
{
bool
readOk
=
readDetectorParameters
(
parser
.
get
<
string
>
(
"dp"
),
detectorParams
);
if
(
!
readOk
)
{
...
...
@@ -148,7 +148,7 @@ int main(int argc, char *argv[]) {
return
0
;
}
aruco
::
Dictionary
dictionary
=
Ptr
<
aruco
::
Dictionary
>
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
PREDEFINED_DICTIONARY_NAME
(
dictionaryId
));
Mat
camMatrix
,
distCoeffs
;
...
...
modules/aruco/samples/detect_markers.cpp
View file @
063c191d
...
...
@@ -74,30 +74,30 @@ static bool readCameraParameters(string filename, Mat &camMatrix, Mat &distCoeff
/**
*/
static
bool
readDetectorParameters
(
string
filename
,
aruco
::
DetectorParameters
&
params
)
{
static
bool
readDetectorParameters
(
string
filename
,
Ptr
<
aruco
::
DetectorParameters
>
&
params
)
{
FileStorage
fs
(
filename
,
FileStorage
::
READ
);
if
(
!
fs
.
isOpened
())
return
false
;
fs
[
"adaptiveThreshWinSizeMin"
]
>>
params
.
adaptiveThreshWinSizeMin
;
fs
[
"adaptiveThreshWinSizeMax"
]
>>
params
.
adaptiveThreshWinSizeMax
;
fs
[
"adaptiveThreshWinSizeStep"
]
>>
params
.
adaptiveThreshWinSizeStep
;
fs
[
"adaptiveThreshConstant"
]
>>
params
.
adaptiveThreshConstant
;
fs
[
"minMarkerPerimeterRate"
]
>>
params
.
minMarkerPerimeterRate
;
fs
[
"maxMarkerPerimeterRate"
]
>>
params
.
maxMarkerPerimeterRate
;
fs
[
"polygonalApproxAccuracyRate"
]
>>
params
.
polygonalApproxAccuracyRate
;
fs
[
"minCornerDistanceRate"
]
>>
params
.
minCornerDistanceRate
;
fs
[
"minDistanceToBorder"
]
>>
params
.
minDistanceToBorder
;
fs
[
"minMarkerDistanceRate"
]
>>
params
.
minMarkerDistanceRate
;
fs
[
"doCornerRefinement"
]
>>
params
.
doCornerRefinement
;
fs
[
"cornerRefinementWinSize"
]
>>
params
.
cornerRefinementWinSize
;
fs
[
"cornerRefinementMaxIterations"
]
>>
params
.
cornerRefinementMaxIterations
;
fs
[
"cornerRefinementMinAccuracy"
]
>>
params
.
cornerRefinementMinAccuracy
;
fs
[
"markerBorderBits"
]
>>
params
.
markerBorderBits
;
fs
[
"perspectiveRemovePixelPerCell"
]
>>
params
.
perspectiveRemovePixelPerCell
;
fs
[
"perspectiveRemoveIgnoredMarginPerCell"
]
>>
params
.
perspectiveRemoveIgnoredMarginPerCell
;
fs
[
"maxErroneousBitsInBorderRate"
]
>>
params
.
maxErroneousBitsInBorderRate
;
fs
[
"minOtsuStdDev"
]
>>
params
.
minOtsuStdDev
;
fs
[
"errorCorrectionRate"
]
>>
params
.
errorCorrectionRate
;
fs
[
"adaptiveThreshWinSizeMin"
]
>>
params
->
adaptiveThreshWinSizeMin
;
fs
[
"adaptiveThreshWinSizeMax"
]
>>
params
->
adaptiveThreshWinSizeMax
;
fs
[
"adaptiveThreshWinSizeStep"
]
>>
params
->
adaptiveThreshWinSizeStep
;
fs
[
"adaptiveThreshConstant"
]
>>
params
->
adaptiveThreshConstant
;
fs
[
"minMarkerPerimeterRate"
]
>>
params
->
minMarkerPerimeterRate
;
fs
[
"maxMarkerPerimeterRate"
]
>>
params
->
maxMarkerPerimeterRate
;
fs
[
"polygonalApproxAccuracyRate"
]
>>
params
->
polygonalApproxAccuracyRate
;
fs
[
"minCornerDistanceRate"
]
>>
params
->
minCornerDistanceRate
;
fs
[
"minDistanceToBorder"
]
>>
params
->
minDistanceToBorder
;
fs
[
"minMarkerDistanceRate"
]
>>
params
->
minMarkerDistanceRate
;
fs
[
"doCornerRefinement"
]
>>
params
->
doCornerRefinement
;
fs
[
"cornerRefinementWinSize"
]
>>
params
->
cornerRefinementWinSize
;
fs
[
"cornerRefinementMaxIterations"
]
>>
params
->
cornerRefinementMaxIterations
;
fs
[
"cornerRefinementMinAccuracy"
]
>>
params
->
cornerRefinementMinAccuracy
;
fs
[
"markerBorderBits"
]
>>
params
->
markerBorderBits
;
fs
[
"perspectiveRemovePixelPerCell"
]
>>
params
->
perspectiveRemovePixelPerCell
;
fs
[
"perspectiveRemoveIgnoredMarginPerCell"
]
>>
params
->
perspectiveRemoveIgnoredMarginPerCell
;
fs
[
"maxErroneousBitsInBorderRate"
]
>>
params
->
maxErroneousBitsInBorderRate
;
fs
[
"minOtsuStdDev"
]
>>
params
->
minOtsuStdDev
;
fs
[
"errorCorrectionRate"
]
>>
params
->
errorCorrectionRate
;
return
true
;
}
...
...
@@ -119,7 +119,7 @@ int main(int argc, char *argv[]) {
bool
estimatePose
=
parser
.
has
(
"c"
);
float
markerLength
=
parser
.
get
<
float
>
(
"l"
);
aruco
::
DetectorParameters
detectorParams
;
Ptr
<
aruco
::
DetectorParameters
>
detectorParams
=
aruco
::
DetectorParameters
::
create
()
;
if
(
parser
.
has
(
"dp"
))
{
bool
readOk
=
readDetectorParameters
(
parser
.
get
<
string
>
(
"dp"
),
detectorParams
);
if
(
!
readOk
)
{
...
...
@@ -127,7 +127,7 @@ int main(int argc, char *argv[]) {
return
0
;
}
}
detectorParams
.
doCornerRefinement
=
true
;
// do corner refinement in markers
detectorParams
->
doCornerRefinement
=
true
;
// do corner refinement in markers
int
camId
=
parser
.
get
<
int
>
(
"ci"
);
...
...
@@ -141,7 +141,7 @@ int main(int argc, char *argv[]) {
return
0
;
}
aruco
::
Dictionary
dictionary
=
Ptr
<
aruco
::
Dictionary
>
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
PREDEFINED_DICTIONARY_NAME
(
dictionaryId
));
Mat
camMatrix
,
distCoeffs
;
...
...
modules/aruco/src/aruco.cpp
View file @
063c191d
...
...
@@ -76,6 +76,15 @@ DetectorParameters::DetectorParameters()
errorCorrectionRate
(
0.6
)
{}
/**
* @brief Create a new set of DetectorParameters with default values.
*/
Ptr
<
DetectorParameters
>
DetectorParameters
::
create
()
{
Ptr
<
DetectorParameters
>
params
=
makePtr
<
DetectorParameters
>
();
return
params
;
}
/**
* @brief Convert input image to gray if it is a 3-channels image
*/
...
...
@@ -267,7 +276,7 @@ class DetectInitialCandidatesParallel : public ParallelLoopBody {
DetectInitialCandidatesParallel
(
const
Mat
*
_grey
,
vector
<
vector
<
vector
<
Point2f
>
>
>
*
_candidatesArrays
,
vector
<
vector
<
vector
<
Point
>
>
>
*
_contoursArrays
,
DetectorParameters
*
_params
)
const
Ptr
<
DetectorParameters
>
&
_params
)
:
grey
(
_grey
),
candidatesArrays
(
_candidatesArrays
),
contoursArrays
(
_contoursArrays
),
params
(
_params
)
{}
...
...
@@ -296,7 +305,7 @@ class DetectInitialCandidatesParallel : public ParallelLoopBody {
const
Mat
*
grey
;
vector
<
vector
<
vector
<
Point2f
>
>
>
*
candidatesArrays
;
vector
<
vector
<
vector
<
Point
>
>
>
*
contoursArrays
;
DetectorParameters
*
params
;
const
Ptr
<
DetectorParameters
>
&
params
;
};
...
...
@@ -305,15 +314,15 @@ class DetectInitialCandidatesParallel : public ParallelLoopBody {
*/
static
void
_detectInitialCandidates
(
const
Mat
&
grey
,
vector
<
vector
<
Point2f
>
>
&
candidates
,
vector
<
vector
<
Point
>
>
&
contours
,
DetectorParameters
params
)
{
const
Ptr
<
DetectorParameters
>
&
params
)
{
CV_Assert
(
params
.
adaptiveThreshWinSizeMin
>=
3
&&
params
.
adaptiveThreshWinSizeMax
>=
3
);
CV_Assert
(
params
.
adaptiveThreshWinSizeMax
>=
params
.
adaptiveThreshWinSizeMin
);
CV_Assert
(
params
.
adaptiveThreshWinSizeStep
>
0
);
CV_Assert
(
params
->
adaptiveThreshWinSizeMin
>=
3
&&
params
->
adaptiveThreshWinSizeMax
>=
3
);
CV_Assert
(
params
->
adaptiveThreshWinSizeMax
>=
params
->
adaptiveThreshWinSizeMin
);
CV_Assert
(
params
->
adaptiveThreshWinSizeStep
>
0
);
// number of window sizes (scales) to apply adaptive thresholding
int
nScales
=
(
params
.
adaptiveThreshWinSizeMax
-
params
.
adaptiveThreshWinSizeMin
)
/
params
.
adaptiveThreshWinSizeStep
+
1
;
int
nScales
=
(
params
->
adaptiveThreshWinSizeMax
-
params
->
adaptiveThreshWinSizeMin
)
/
params
->
adaptiveThreshWinSizeStep
+
1
;
vector
<
vector
<
vector
<
Point2f
>
>
>
candidatesArrays
((
size_t
)
nScales
);
vector
<
vector
<
vector
<
Point
>
>
>
contoursArrays
((
size_t
)
nScales
);
...
...
@@ -333,7 +342,7 @@ static void _detectInitialCandidates(const Mat &grey, vector< vector< Point2f >
// this is the parallel call for the previous commented loop (result is equivalent)
parallel_for_
(
Range
(
0
,
nScales
),
DetectInitialCandidatesParallel
(
&
grey
,
&
candidatesArrays
,
&
contoursArrays
,
&
params
));
&
contoursArrays
,
params
));
// join candidates
for
(
int
i
=
0
;
i
<
nScales
;
i
++
)
{
...
...
@@ -349,7 +358,7 @@ static void _detectInitialCandidates(const Mat &grey, vector< vector< Point2f >
* @brief Detect square candidates in the input image
*/
static
void
_detectCandidates
(
InputArray
_image
,
OutputArrayOfArrays
_candidates
,
OutputArrayOfArrays
_contours
,
DetectorParameters
params
)
{
OutputArrayOfArrays
_contours
,
const
Ptr
<
DetectorParameters
>
&
_
params
)
{
Mat
image
=
_image
.
getMat
();
CV_Assert
(
image
.
total
()
!=
0
);
...
...
@@ -361,7 +370,7 @@ static void _detectCandidates(InputArray _image, OutputArrayOfArrays _candidates
vector
<
vector
<
Point2f
>
>
candidates
;
vector
<
vector
<
Point
>
>
contours
;
/// 2. DETECT FIRST SET OF CANDIDATES
_detectInitialCandidates
(
grey
,
candidates
,
contours
,
params
);
_detectInitialCandidates
(
grey
,
candidates
,
contours
,
_
params
);
/// 3. SORT CORNERS
_reorderCandidatesCorners
(
candidates
);
...
...
@@ -370,7 +379,7 @@ static void _detectCandidates(InputArray _image, OutputArrayOfArrays _candidates
vector
<
vector
<
Point2f
>
>
candidatesOut
;
vector
<
vector
<
Point
>
>
contoursOut
;
_filterTooCloseCandidates
(
candidates
,
candidatesOut
,
contours
,
contoursOut
,
params
.
minMarkerDistanceRate
);
_params
->
minMarkerDistanceRate
);
// parse output
_candidates
.
create
((
int
)
candidatesOut
.
size
(),
1
,
CV_32FC2
);
...
...
@@ -489,35 +498,35 @@ static int _getBorderErrors(const Mat &bits, int markerSize, int borderSize) {
/**
* @brief Tries to identify one candidate given the dictionary
*/
static
bool
_identifyOneCandidate
(
const
Dictionary
&
dictionary
,
InputArray
_image
,
InputOutputArray
_corners
,
int
&
idx
,
DetectorParameters
params
)
{
static
bool
_identifyOneCandidate
(
Ptr
<
Dictionary
>
&
dictionary
,
InputArray
_image
,
InputOutputArray
_corners
,
int
&
idx
,
const
Ptr
<
DetectorParameters
>
&
params
)
{
CV_Assert
(
_corners
.
total
()
==
4
);
CV_Assert
(
_image
.
getMat
().
total
()
!=
0
);
CV_Assert
(
params
.
markerBorderBits
>
0
);
CV_Assert
(
params
->
markerBorderBits
>
0
);
// get bits
Mat
candidateBits
=
_extractBits
(
_image
,
_corners
,
dictionary
.
markerSize
,
params
.
markerBorderBits
,
params
.
perspectiveRemovePixelPerCell
,
params
.
perspectiveRemoveIgnoredMarginPerCell
,
params
.
minOtsuStdDev
);
_extractBits
(
_image
,
_corners
,
dictionary
->
markerSize
,
params
->
markerBorderBits
,
params
->
perspectiveRemovePixelPerCell
,
params
->
perspectiveRemoveIgnoredMarginPerCell
,
params
->
minOtsuStdDev
);
// analyze border bits
int
maximumErrorsInBorder
=
int
(
dictionary
.
markerSize
*
dictionary
.
markerSize
*
params
.
maxErroneousBitsInBorderRate
);
int
(
dictionary
->
markerSize
*
dictionary
->
markerSize
*
params
->
maxErroneousBitsInBorderRate
);
int
borderErrors
=
_getBorderErrors
(
candidateBits
,
dictionary
.
markerSize
,
params
.
markerBorderBits
);
_getBorderErrors
(
candidateBits
,
dictionary
->
markerSize
,
params
->
markerBorderBits
);
if
(
borderErrors
>
maximumErrorsInBorder
)
return
false
;
// border is wrong
// take only inner bits
Mat
onlyBits
=
candidateBits
.
rowRange
(
params
.
markerBorderBits
,
candidateBits
.
rows
-
params
.
markerBorderBits
)
.
colRange
(
params
.
markerBorderBits
,
candidateBits
.
rows
-
params
.
markerBorderBits
);
candidateBits
.
rowRange
(
params
->
markerBorderBits
,
candidateBits
.
rows
-
params
->
markerBorderBits
)
.
colRange
(
params
->
markerBorderBits
,
candidateBits
.
rows
-
params
->
markerBorderBits
);
// try to indentify the marker
int
rotation
;
if
(
!
dictionary
.
identify
(
onlyBits
,
idx
,
rotation
,
params
.
errorCorrectionRate
))
if
(
!
dictionary
->
identify
(
onlyBits
,
idx
,
rotation
,
params
->
errorCorrectionRate
))
return
false
;
else
{
// shift corner positions to the correct rotation
...
...
@@ -539,9 +548,9 @@ static bool _identifyOneCandidate(const Dictionary &dictionary, InputArray _imag
class
IdentifyCandidatesParallel
:
public
ParallelLoopBody
{
public
:
IdentifyCandidatesParallel
(
const
Mat
*
_grey
,
InputArrayOfArrays
_candidates
,
InputArrayOfArrays
_contours
,
const
Dictionary
*
_dictionary
,
InputArrayOfArrays
_contours
,
Ptr
<
Dictionary
>
&
_dictionary
,
vector
<
int
>
*
_idsTmp
,
vector
<
char
>
*
_validCandidates
,
DetectorParameters
*
_params
)
const
Ptr
<
DetectorParameters
>
&
_params
)
:
grey
(
_grey
),
candidates
(
_candidates
),
contours
(
_contours
),
dictionary
(
_dictionary
),
idsTmp
(
_idsTmp
),
validCandidates
(
_validCandidates
),
params
(
_params
)
{}
...
...
@@ -552,7 +561,7 @@ class IdentifyCandidatesParallel : public ParallelLoopBody {
for
(
int
i
=
begin
;
i
<
end
;
i
++
)
{
int
currId
;
Mat
currentCandidate
=
candidates
.
getMat
(
i
);
if
(
_identifyOneCandidate
(
*
dictionary
,
*
grey
,
currentCandidate
,
currId
,
*
params
))
{
if
(
_identifyOneCandidate
(
dictionary
,
*
grey
,
currentCandidate
,
currId
,
params
))
{
(
*
validCandidates
)[
i
]
=
1
;
(
*
idsTmp
)[
i
]
=
currId
;
}
...
...
@@ -564,21 +573,65 @@ class IdentifyCandidatesParallel : public ParallelLoopBody {
const
Mat
*
grey
;
InputArrayOfArrays
candidates
,
contours
;
const
Dictionary
*
dictionary
;
Ptr
<
Dictionary
>
&
dictionary
;
vector
<
int
>
*
idsTmp
;
vector
<
char
>
*
validCandidates
;
DetectorParameters
*
params
;
const
Ptr
<
DetectorParameters
>
&
params
;
};
/**
* @brief Copy the contents of a Mat vector to an OutputArray, settings its size.
*/
void
_copyVector2Output
(
vector
<
Mat
>
&
vec
,
OutputArrayOfArrays
out
);
/**
*
*/
void
_copyVector2Output
(
vector
<
Mat
>
&
vec
,
OutputArrayOfArrays
out
)
{
out
.
release
();
out
.
create
((
int
)
vec
.
size
(),
1
,
CV_32FC2
);
if
(
out
.
isMatVector
())
{
for
(
unsigned
int
i
=
0
;
i
<
vec
.
size
();
i
++
)
{
out
.
create
(
4
,
1
,
CV_32FC2
,
i
,
true
);
Mat
&
m
=
out
.
getMatRef
(
i
);
vec
[
i
].
copyTo
(
m
);
}
}
else
if
(
out
.
isUMatVector
())
{
for
(
unsigned
int
i
=
0
;
i
<
vec
.
size
();
i
++
)
{
out
.
create
(
4
,
1
,
CV_32FC2
,
i
,
true
);
UMat
&
m
=
out
.
getUMatRef
(
i
);
vec
[
i
].
copyTo
(
m
);
}
}
else
if
(
out
.
kind
()
==
_OutputArray
::
STD_VECTOR_VECTOR
){
for
(
unsigned
int
i
=
0
;
i
<
vec
.
size
();
i
++
)
{
out
.
create
(
4
,
1
,
CV_32FC2
,
i
,
true
);
Mat
m
=
out
.
getMat
(
i
);
vec
[
i
].
copyTo
(
m
);
}
}
else
{
CV_Error
(
cv
::
Error
::
StsNotImplemented
,
"Only Mat vector, UMat vector, and vector<vector> OutputArrays are currently supported."
);
}
}
/**
* @brief Identify square candidates according to a marker dictionary
*/
static
void
_identifyCandidates
(
InputArray
_image
,
InputArrayOfArrays
_candidates
,
InputArrayOfArrays
_contours
,
const
Dictionary
&
dictionary
,
InputArrayOfArrays
_contours
,
Ptr
<
Dictionary
>
&
_
dictionary
,
OutputArrayOfArrays
_accepted
,
OutputArray
_ids
,
DetectorParameters
params
,
const
Ptr
<
DetectorParameters
>
&
params
,
OutputArrayOfArrays
_rejected
=
noArray
())
{
int
ncandidates
=
(
int
)
_candidates
.
total
();
...
...
@@ -607,8 +660,8 @@ static void _identifyCandidates(InputArray _image, InputArrayOfArrays _candidate
// this is the parallel call for the previous commented loop (result is equivalent)
parallel_for_
(
Range
(
0
,
ncandidates
),
IdentifyCandidatesParallel
(
&
grey
,
_candidates
,
_contours
,
&
dictionary
,
&
idsTmp
,
&
validCandidates
,
&
params
));
IdentifyCandidatesParallel
(
&
grey
,
_candidates
,
_contours
,
_
dictionary
,
&
idsTmp
,
&
validCandidates
,
params
));
for
(
int
i
=
0
;
i
<
ncandidates
;
i
++
)
{
if
(
validCandidates
[
i
]
==
1
)
{
...
...
@@ -620,24 +673,14 @@ static void _identifyCandidates(InputArray _image, InputArrayOfArrays _candidate
}
// parse output
_accepted
.
create
((
int
)
accepted
.
size
(),
1
,
CV_32FC2
);
for
(
unsigned
int
i
=
0
;
i
<
accepted
.
size
();
i
++
)
{
_accepted
.
create
(
4
,
1
,
CV_32FC2
,
i
,
true
);
Mat
m
=
_accepted
.
getMat
(
i
);
accepted
[
i
].
copyTo
(
m
);
}
_copyVector2Output
(
accepted
,
_accepted
);
_ids
.
create
((
int
)
ids
.
size
(),
1
,
CV_32SC1
);
for
(
unsigned
int
i
=
0
;
i
<
ids
.
size
();
i
++
)
_ids
.
getMat
().
ptr
<
int
>
(
0
)[
i
]
=
ids
[
i
];
if
(
_rejected
.
needed
())
{
_rejected
.
create
((
int
)
rejected
.
size
(),
1
,
CV_32FC2
);
for
(
unsigned
int
i
=
0
;
i
<
rejected
.
size
();
i
++
)
{
_rejected
.
create
(
4
,
1
,
CV_32FC2
,
i
,
true
);
Mat
m
=
_rejected
.
getMat
(
i
);
rejected
[
i
].
copyTo
(
m
);
}
_copyVector2Output
(
rejected
,
_rejected
);
}
}
...
...
@@ -744,7 +787,7 @@ static void _getSingleMarkerObjectPoints(float markerLength, OutputArray _objPoi
class
MarkerSubpixelParallel
:
public
ParallelLoopBody
{
public
:
MarkerSubpixelParallel
(
const
Mat
*
_grey
,
OutputArrayOfArrays
_corners
,
DetectorParameters
*
_params
)
const
Ptr
<
DetectorParameters
>
&
_params
)
:
grey
(
_grey
),
corners
(
_corners
),
params
(
_params
)
{}
void
operator
()(
const
Range
&
range
)
const
{
...
...
@@ -765,15 +808,15 @@ class MarkerSubpixelParallel : public ParallelLoopBody {
const
Mat
*
grey
;
OutputArrayOfArrays
corners
;
DetectorParameters
*
params
;
const
Ptr
<
DetectorParameters
>
&
params
;
};
/**
*/
void
detectMarkers
(
InputArray
_image
,
Dictionary
dictionary
,
OutputArrayOfArrays
_corners
,
OutputArray
_ids
,
DetectorParameters
params
,
void
detectMarkers
(
InputArray
_image
,
Ptr
<
Dictionary
>
&
_
dictionary
,
OutputArrayOfArrays
_corners
,
OutputArray
_ids
,
const
Ptr
<
DetectorParameters
>
&
_
params
,
OutputArrayOfArrays
_rejectedImgPoints
)
{
CV_Assert
(
_image
.
getMat
().
total
()
!=
0
);
...
...
@@ -784,19 +827,19 @@ void detectMarkers(InputArray _image, Dictionary dictionary, OutputArrayOfArrays
/// STEP 1: Detect marker candidates
vector
<
vector
<
Point2f
>
>
candidates
;
vector
<
vector
<
Point
>
>
contours
;
_detectCandidates
(
grey
,
candidates
,
contours
,
params
);
_detectCandidates
(
grey
,
candidates
,
contours
,
_
params
);
/// STEP 2: Check candidate codification (identify markers)
_identifyCandidates
(
grey
,
candidates
,
contours
,
dictionary
,
_corners
,
_ids
,
params
,
_identifyCandidates
(
grey
,
candidates
,
contours
,
_dictionary
,
_corners
,
_ids
,
_
params
,
_rejectedImgPoints
);
/// STEP 3: Filter detected markers;
_filterDetectedMarkers
(
_corners
,
_ids
,
_corners
,
_ids
);
/// STEP 4: Corner refinement
if
(
params
.
doCornerRefinement
)
{
CV_Assert
(
params
.
cornerRefinementWinSize
>
0
&&
params
.
cornerRefinementMaxIterations
>
0
&&
params
.
cornerRefinementMinAccuracy
>
0
);
if
(
_params
->
doCornerRefinement
)
{
CV_Assert
(
_params
->
cornerRefinementWinSize
>
0
&&
_params
->
cornerRefinementMaxIterations
>
0
&&
_params
->
cornerRefinementMinAccuracy
>
0
);
//// do corner refinement for each of the detected markers
// for (unsigned int i = 0; i < _corners.total(); i++) {
...
...
@@ -809,7 +852,7 @@ void detectMarkers(InputArray _image, Dictionary dictionary, OutputArrayOfArrays
// this is the parallel call for the previous commented loop (result is equivalent)
parallel_for_
(
Range
(
0
,
(
int
)
_corners
.
total
()),
MarkerSubpixelParallel
(
&
grey
,
_corners
,
&
params
));
MarkerSubpixelParallel
(
&
grey
,
_corners
,
_
params
));
}
}
...
...
@@ -883,11 +926,11 @@ void estimatePoseSingleMarkers(InputArrayOfArrays _corners, float markerLength,
* @brief Given a board configuration and a set of detected markers, returns the corresponding
* image points and object points to call solvePnP
*/
static
void
_getBoardObjectAndImagePoints
(
const
Board
&
board
,
InputArray
_detectedIds
,
static
void
_getBoardObjectAndImagePoints
(
Ptr
<
Board
>
&
_
board
,
InputArray
_detectedIds
,
InputArrayOfArrays
_detectedCorners
,
OutputArray
_imgPoints
,
OutputArray
_objPoints
)
{
CV_Assert
(
board
.
ids
.
size
()
==
board
.
objPoints
.
size
());
CV_Assert
(
_board
->
ids
.
size
()
==
_board
->
objPoints
.
size
());
CV_Assert
(
_detectedIds
.
total
()
==
_detectedCorners
.
total
());
size_t
nDetectedMarkers
=
_detectedIds
.
total
();
...
...
@@ -901,10 +944,10 @@ static void _getBoardObjectAndImagePoints(const Board &board, InputArray _detect
// look for detected markers that belong to the board and get their information
for
(
unsigned
int
i
=
0
;
i
<
nDetectedMarkers
;
i
++
)
{
int
currentId
=
_detectedIds
.
getMat
().
ptr
<
int
>
(
0
)[
i
];
for
(
unsigned
int
j
=
0
;
j
<
board
.
ids
.
size
();
j
++
)
{
if
(
currentId
==
board
.
ids
[
j
])
{
for
(
unsigned
int
j
=
0
;
j
<
_board
->
ids
.
size
();
j
++
)
{
if
(
currentId
==
_board
->
ids
[
j
])
{
for
(
int
p
=
0
;
p
<
4
;
p
++
)
{
objPnts
.
push_back
(
board
.
objPoints
[
j
][
p
]);
objPnts
.
push_back
(
_board
->
objPoints
[
j
][
p
]);
imgPnts
.
push_back
(
_detectedCorners
.
getMat
(
i
).
ptr
<
Point2f
>
(
0
)[
p
]);
}
}
...
...
@@ -926,7 +969,7 @@ static void _getBoardObjectAndImagePoints(const Board &board, InputArray _detect
/**
* Project board markers that are not included in the list of detected markers
*/
static
void
_projectUndetectedMarkers
(
const
Board
&
board
,
InputOutputArrayOfArrays
_detectedCorners
,
static
void
_projectUndetectedMarkers
(
Ptr
<
Board
>
&
_
board
,
InputOutputArrayOfArrays
_detectedCorners
,
InputOutputArray
_detectedIds
,
InputArray
_cameraMatrix
,
InputArray
_distCoeffs
,
OutputArrayOfArrays
_undetectedMarkersProjectedCorners
,
...
...
@@ -935,7 +978,7 @@ static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArra
// first estimate board pose with the current avaible markers
Mat
rvec
,
tvec
;
int
boardDetectedMarkers
;
boardDetectedMarkers
=
aruco
::
estimatePoseBoard
(
_detectedCorners
,
_detectedIds
,
board
,
boardDetectedMarkers
=
aruco
::
estimatePoseBoard
(
_detectedCorners
,
_detectedIds
,
_
board
,
_cameraMatrix
,
_distCoeffs
,
rvec
,
tvec
);
// at least one marker from board so rvec and tvec are valid
...
...
@@ -944,10 +987,10 @@ static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArra
// search undetected markers and project them using the previous pose
vector
<
vector
<
Point2f
>
>
undetectedCorners
;
vector
<
int
>
undetectedIds
;
for
(
unsigned
int
i
=
0
;
i
<
board
.
ids
.
size
();
i
++
)
{
for
(
unsigned
int
i
=
0
;
i
<
_board
->
ids
.
size
();
i
++
)
{
int
foundIdx
=
-
1
;
for
(
unsigned
int
j
=
0
;
j
<
_detectedIds
.
total
();
j
++
)
{
if
(
board
.
ids
[
i
]
==
_detectedIds
.
getMat
().
ptr
<
int
>
()[
j
])
{
if
(
_board
->
ids
[
i
]
==
_detectedIds
.
getMat
().
ptr
<
int
>
()[
j
])
{
foundIdx
=
j
;
break
;
}
...
...
@@ -956,8 +999,8 @@ static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArra
// not detected
if
(
foundIdx
==
-
1
)
{
undetectedCorners
.
push_back
(
vector
<
Point2f
>
());
undetectedIds
.
push_back
(
board
.
ids
[
i
]);
projectPoints
(
board
.
objPoints
[
i
],
rvec
,
tvec
,
_cameraMatrix
,
_distCoeffs
,
undetectedIds
.
push_back
(
_board
->
ids
[
i
]);
projectPoints
(
_board
->
objPoints
[
i
],
rvec
,
tvec
,
_cameraMatrix
,
_distCoeffs
,
undetectedCorners
.
back
());
}
}
...
...
@@ -984,19 +1027,19 @@ static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArra
* Interpolate board markers that are not included in the list of detected markers using
* global homography
*/
static
void
_projectUndetectedMarkers
(
const
Board
&
board
,
InputOutputArrayOfArrays
_detectedCorners
,
static
void
_projectUndetectedMarkers
(
Ptr
<
Board
>
&
_
board
,
InputOutputArrayOfArrays
_detectedCorners
,
InputOutputArray
_detectedIds
,
OutputArrayOfArrays
_undetectedMarkersProjectedCorners
,
OutputArray
_undetectedMarkersIds
)
{
// check board points are in the same plane, if not, global homography cannot be applied
CV_Assert
(
board
.
objPoints
.
size
()
>
0
);
CV_Assert
(
board
.
objPoints
[
0
].
size
()
>
0
);
float
boardZ
=
board
.
objPoints
[
0
][
0
].
z
;
for
(
unsigned
int
i
=
0
;
i
<
board
.
objPoints
.
size
();
i
++
)
{
for
(
unsigned
int
j
=
0
;
j
<
board
.
objPoints
[
i
].
size
();
j
++
)
{
CV_Assert
(
boardZ
==
board
.
objPoints
[
i
][
j
].
z
);
CV_Assert
(
_board
->
objPoints
.
size
()
>
0
);
CV_Assert
(
_board
->
objPoints
[
0
].
size
()
>
0
);
float
boardZ
=
_board
->
objPoints
[
0
][
0
].
z
;
for
(
unsigned
int
i
=
0
;
i
<
_board
->
objPoints
.
size
();
i
++
)
{
for
(
unsigned
int
j
=
0
;
j
<
_board
->
objPoints
[
i
].
size
();
j
++
)
{
CV_Assert
(
boardZ
==
_board
->
objPoints
[
i
][
j
].
z
);
}
}
...
...
@@ -1007,14 +1050,14 @@ static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArra
// missing markers in different vectors
vector
<
int
>
undetectedMarkersIds
;
// ids of missing markers
// find markers included in board, and missing markers from board. Fill the previous vectors
for
(
unsigned
int
j
=
0
;
j
<
board
.
ids
.
size
();
j
++
)
{
for
(
unsigned
int
j
=
0
;
j
<
_board
->
ids
.
size
();
j
++
)
{
bool
found
=
false
;
for
(
unsigned
int
i
=
0
;
i
<
_detectedIds
.
total
();
i
++
)
{
if
(
_detectedIds
.
getMat
().
ptr
<
int
>
()[
i
]
==
board
.
ids
[
j
])
{
if
(
_detectedIds
.
getMat
().
ptr
<
int
>
()[
i
]
==
_board
->
ids
[
j
])
{
for
(
int
c
=
0
;
c
<
4
;
c
++
)
{
imageCornersAll
.
push_back
(
_detectedCorners
.
getMat
(
i
).
ptr
<
Point2f
>
()[
c
]);
detectedMarkersObj2DAll
.
push_back
(
Point2f
(
board
.
objPoints
[
j
][
c
].
x
,
board
.
objPoints
[
j
][
c
].
y
));
Point2f
(
_board
->
objPoints
[
j
][
c
].
x
,
_board
->
objPoints
[
j
][
c
].
y
));
}
found
=
true
;
break
;
...
...
@@ -1024,9 +1067,9 @@ static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArra
undetectedMarkersObj2D
.
push_back
(
vector
<
Point2f
>
());
for
(
int
c
=
0
;
c
<
4
;
c
++
)
{
undetectedMarkersObj2D
.
back
().
push_back
(
Point2f
(
board
.
objPoints
[
j
][
c
].
x
,
board
.
objPoints
[
j
][
c
].
y
));
Point2f
(
_board
->
objPoints
[
j
][
c
].
x
,
_board
->
objPoints
[
j
][
c
].
y
));
}
undetectedMarkersIds
.
push_back
(
board
.
ids
[
j
]);
undetectedMarkersIds
.
push_back
(
_board
->
ids
[
j
]);
}
}
if
(
imageCornersAll
.
size
()
==
0
)
return
;
...
...
@@ -1054,28 +1097,30 @@ static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArra
/**
*/
void
refineDetectedMarkers
(
InputArray
_image
,
const
Board
&
board
,
void
refineDetectedMarkers
(
InputArray
_image
,
Ptr
<
Board
>
&
_
board
,
InputOutputArrayOfArrays
_detectedCorners
,
InputOutputArray
_detectedIds
,
InputOutputArray
_rejectedCorners
,
InputArray
_cameraMatrix
,
InputArray
_distCoeffs
,
float
minRepDistance
,
float
errorCorrectionRate
,
bool
checkAllOrders
,
OutputArray
_recoveredIdxs
,
DetectorParameters
params
)
{
const
Ptr
<
DetectorParameters
>
&
_
params
)
{
CV_Assert
(
minRepDistance
>
0
);
if
(
_detectedIds
.
total
()
==
0
||
_rejectedCorners
.
total
()
==
0
)
return
;
DetectorParameters
&
params
=
*
_params
;
// get projections of missing markers in the board
vector
<
vector
<
Point2f
>
>
undetectedMarkersCorners
;
vector
<
int
>
undetectedMarkersIds
;
if
(
_cameraMatrix
.
total
()
!=
0
)
{
// reproject based on camera projection model
_projectUndetectedMarkers
(
board
,
_detectedCorners
,
_detectedIds
,
_cameraMatrix
,
_distCoeffs
,
_projectUndetectedMarkers
(
_
board
,
_detectedCorners
,
_detectedIds
,
_cameraMatrix
,
_distCoeffs
,
undetectedMarkersCorners
,
undetectedMarkersIds
);
}
else
{
// reproject based on global homography
_projectUndetectedMarkers
(
board
,
_detectedCorners
,
_detectedIds
,
undetectedMarkersCorners
,
_projectUndetectedMarkers
(
_
board
,
_detectedCorners
,
_detectedIds
,
undetectedMarkersCorners
,
undetectedMarkersIds
);
}
...
...
@@ -1083,8 +1128,9 @@ void refineDetectedMarkers(InputArray _image, const Board &board,
vector
<
bool
>
alreadyIdentified
(
_rejectedCorners
.
total
(),
false
);
// maximum bits that can be corrected
Dictionary
&
dictionary
=
*
(
_board
->
dictionary
);
int
maxCorrectionRecalculated
=
int
(
double
(
board
.
dictionary
.
maxCorrectionBits
)
*
errorCorrectionRate
);
int
(
double
(
dictionary
.
maxCorrectionBits
)
*
errorCorrectionRate
);
Mat
grey
;
_convertToGrey
(
_image
,
grey
);
...
...
@@ -1152,7 +1198,7 @@ void refineDetectedMarkers(InputArray _image, const Board &board,
// extract bits
Mat
bits
=
_extractBits
(
grey
,
rotatedMarker
,
board
.
dictionary
.
markerSize
,
params
.
markerBorderBits
,
grey
,
rotatedMarker
,
dictionary
.
markerSize
,
params
.
markerBorderBits
,
params
.
perspectiveRemovePixelPerCell
,
params
.
perspectiveRemoveIgnoredMarginPerCell
,
params
.
minOtsuStdDev
);
...
...
@@ -1161,7 +1207,7 @@ void refineDetectedMarkers(InputArray _image, const Board &board,
.
colRange
(
params
.
markerBorderBits
,
bits
.
rows
-
params
.
markerBorderBits
);
codeDistance
=
board
.
dictionary
.
getDistanceToId
(
onlyBits
,
undetectedMarkersIds
[
i
],
false
);
dictionary
.
getDistanceToId
(
onlyBits
,
undetectedMarkersIds
[
i
],
false
);
}
// if everythin is ok, assign values to current best match
...
...
@@ -1250,7 +1296,7 @@ void refineDetectedMarkers(InputArray _image, const Board &board,
/**
*/
int
estimatePoseBoard
(
InputArrayOfArrays
_corners
,
InputArray
_ids
,
const
Board
&
board
,
int
estimatePoseBoard
(
InputArrayOfArrays
_corners
,
InputArray
_ids
,
Ptr
<
Board
>
&
board
,
InputArray
_cameraMatrix
,
InputArray
_distCoeffs
,
OutputArray
_rvec
,
OutputArray
_tvec
)
{
...
...
@@ -1279,33 +1325,33 @@ int estimatePoseBoard(InputArrayOfArrays _corners, InputArray _ids, const Board
/**
*/
void
GridBoard
::
draw
(
Size
outSize
,
OutputArray
_img
,
int
marginSize
,
int
borderBits
)
{
aruco
::
drawPlanarBoard
((
*
this
)
,
outSize
,
_img
,
marginSize
,
borderBits
);
_drawPlanarBoardImpl
(
this
,
outSize
,
_img
,
marginSize
,
borderBits
);
}
/**
*/
GridBoard
GridBoard
::
create
(
int
markersX
,
int
markersY
,
float
markerLength
,
float
markerSeparation
,
Dictionary
_dictionary
)
{
GridBoard
res
;
Ptr
<
GridBoard
>
GridBoard
::
create
(
int
markersX
,
int
markersY
,
float
markerLength
,
float
markerSeparation
,
Ptr
<
Dictionary
>
&
dictionary
)
{
CV_Assert
(
markersX
>
0
&&
markersY
>
0
&&
markerLength
>
0
&&
markerSeparation
>
0
);
res
.
_markersX
=
markersX
;
res
.
_markersY
=
markersY
;
res
.
_markerLength
=
markerLength
;
res
.
_markerSeparation
=
markerSeparation
;
res
.
dictionary
=
_dictionary
;
Ptr
<
GridBoard
>
res
=
makePtr
<
GridBoard
>
();
res
->
_markersX
=
markersX
;
res
->
_markersY
=
markersY
;
res
->
_markerLength
=
markerLength
;
res
->
_markerSeparation
=
markerSeparation
;
res
->
dictionary
=
dictionary
;
size_t
totalMarkers
=
(
size_t
)
markersX
*
markersY
;
res
.
ids
.
resize
(
totalMarkers
);
res
.
objPoints
.
reserve
(
totalMarkers
);
res
->
ids
.
resize
(
totalMarkers
);
res
->
objPoints
.
reserve
(
totalMarkers
);
// fill ids with first identifiers
for
(
unsigned
int
i
=
0
;
i
<
totalMarkers
;
i
++
)
{
res
.
ids
[
i
]
=
i
;
res
->
ids
[
i
]
=
i
;
}
// calculate Board objPoints
...
...
@@ -1319,7 +1365,7 @@ GridBoard GridBoard::create(int markersX, int markersY, float markerLength, floa
corners
[
1
]
=
corners
[
0
]
+
Point3f
(
markerLength
,
0
,
0
);
corners
[
2
]
=
corners
[
0
]
+
Point3f
(
markerLength
,
-
markerLength
,
0
);
corners
[
3
]
=
corners
[
0
]
+
Point3f
(
0
,
-
markerLength
,
0
);
res
.
objPoints
.
push_back
(
corners
);
res
->
objPoints
.
push_back
(
corners
);
}
}
...
...
@@ -1403,15 +1449,13 @@ void drawAxis(InputOutputArray _image, InputArray _cameraMatrix, InputArray _dis
/**
*/
void
drawMarker
(
Dictionary
dictionary
,
int
id
,
int
sidePixels
,
OutputArray
_img
,
int
borderBits
)
{
dictionary
.
drawMarker
(
id
,
sidePixels
,
_img
,
borderBits
);
void
drawMarker
(
Ptr
<
Dictionary
>
&
dictionary
,
int
id
,
int
sidePixels
,
OutputArray
_img
,
int
borderBits
)
{
dictionary
->
drawMarker
(
id
,
sidePixels
,
_img
,
borderBits
);
}
/**
*/
void
drawPlanarBoard
(
const
Board
&
board
,
Size
outSize
,
OutputArray
_img
,
int
marginSize
,
void
_drawPlanarBoardImpl
(
Board
*
_board
,
Size
outSize
,
OutputArray
_img
,
int
marginSize
,
int
borderBits
)
{
CV_Assert
(
outSize
.
area
()
>
0
);
...
...
@@ -1424,17 +1468,17 @@ void drawPlanarBoard(const Board &board, Size outSize, OutputArray _img, int mar
out
.
colRange
(
marginSize
,
out
.
cols
-
marginSize
).
rowRange
(
marginSize
,
out
.
rows
-
marginSize
);
// calculate max and min values in XY plane
CV_Assert
(
board
.
objPoints
.
size
()
>
0
);
CV_Assert
(
_board
->
objPoints
.
size
()
>
0
);
float
minX
,
maxX
,
minY
,
maxY
;
minX
=
maxX
=
board
.
objPoints
[
0
][
0
].
x
;
minY
=
maxY
=
board
.
objPoints
[
0
][
0
].
y
;
minX
=
maxX
=
_board
->
objPoints
[
0
][
0
].
x
;
minY
=
maxY
=
_board
->
objPoints
[
0
][
0
].
y
;
for
(
unsigned
int
i
=
0
;
i
<
board
.
objPoints
.
size
();
i
++
)
{
for
(
unsigned
int
i
=
0
;
i
<
_board
->
objPoints
.
size
();
i
++
)
{
for
(
int
j
=
0
;
j
<
4
;
j
++
)
{
minX
=
min
(
minX
,
board
.
objPoints
[
i
][
j
].
x
);
maxX
=
max
(
maxX
,
board
.
objPoints
[
i
][
j
].
x
);
minY
=
min
(
minY
,
board
.
objPoints
[
i
][
j
].
y
);
maxY
=
max
(
maxY
,
board
.
objPoints
[
i
][
j
].
y
);
minX
=
min
(
minX
,
_board
->
objPoints
[
i
][
j
].
x
);
maxX
=
max
(
maxX
,
_board
->
objPoints
[
i
][
j
].
x
);
minY
=
min
(
minY
,
_board
->
objPoints
[
i
][
j
].
y
);
maxY
=
max
(
maxY
,
_board
->
objPoints
[
i
][
j
].
y
);
}
}
...
...
@@ -1459,14 +1503,15 @@ void drawPlanarBoard(const Board &board, Size outSize, OutputArray _img, int mar
}
// now paint each marker
for
(
unsigned
int
m
=
0
;
m
<
board
.
objPoints
.
size
();
m
++
)
{
Dictionary
&
dictionary
=
*
(
_board
->
dictionary
);
for
(
unsigned
int
m
=
0
;
m
<
_board
->
objPoints
.
size
();
m
++
)
{
// transform corners to markerZone coordinates
vector
<
Point2f
>
outCorners
;
outCorners
.
resize
(
4
);
for
(
int
j
=
0
;
j
<
4
;
j
++
)
{
Point2f
p0
,
p1
,
pf
;
p0
=
Point2f
(
board
.
objPoints
[
m
][
j
].
x
,
board
.
objPoints
[
m
][
j
].
y
);
p0
=
Point2f
(
_board
->
objPoints
[
m
][
j
].
x
,
_board
->
objPoints
[
m
][
j
].
y
);
// remove negativity
p1
.
x
=
p0
.
x
-
minX
;
p1
.
y
=
p0
.
y
-
minY
;
...
...
@@ -1476,9 +1521,9 @@ void drawPlanarBoard(const Board &board, Size outSize, OutputArray _img, int mar
}
// get tiny marker
int
tinyMarkerSize
=
10
*
board
.
dictionary
.
markerSize
+
2
;
int
tinyMarkerSize
=
10
*
dictionary
.
markerSize
+
2
;
Mat
tinyMarker
;
board
.
dictionary
.
drawMarker
(
board
.
ids
[
m
],
tinyMarkerSize
,
tinyMarker
,
borderBits
);
dictionary
.
drawMarker
(
_board
->
ids
[
m
],
tinyMarkerSize
,
tinyMarker
,
borderBits
);
// interpolate tiny marker to marker position in markerZone
Mat
inCorners
(
4
,
1
,
CV_32FC2
);
...
...
@@ -1506,10 +1551,19 @@ void drawPlanarBoard(const Board &board, Size outSize, OutputArray _img, int mar
/**
*/
void
drawPlanarBoard
(
Ptr
<
Board
>
&
_board
,
Size
outSize
,
OutputArray
_img
,
int
marginSize
,
int
borderBits
)
{
_drawPlanarBoardImpl
(
_board
,
outSize
,
_img
,
marginSize
,
borderBits
);
}
/**
*/
double
calibrateCameraAruco
(
InputArrayOfArrays
_corners
,
InputArray
_ids
,
InputArray
_counter
,
const
Board
&
board
,
Size
imageSize
,
InputOutputArray
_cameraMatrix
,
Ptr
<
Board
>
&
board
,
Size
imageSize
,
InputOutputArray
_cameraMatrix
,
InputOutputArray
_distCoeffs
,
OutputArrayOfArrays
_rvecs
,
OutputArrayOfArrays
_tvecs
,
int
flags
,
TermCriteria
criteria
)
{
...
...
@@ -1544,5 +1598,8 @@ double calibrateCameraAruco(InputArrayOfArrays _corners, InputArray _ids, InputA
return
calibrateCamera
(
processedObjectPoints
,
processedImagePoints
,
imageSize
,
_cameraMatrix
,
_distCoeffs
,
_rvecs
,
_tvecs
,
flags
,
criteria
);
}
}
}
modules/aruco/src/charuco.cpp
View file @
063c191d
...
...
@@ -93,8 +93,8 @@ void CharucoBoard::draw(Size outSize, OutputArray _img, int marginSize, int bord
// draw markers
Mat
markersImg
;
aruco
::
drawPlanarBoard
((
*
this
)
,
chessboardZoneImg
.
size
(),
markersImg
,
diffSquareMarkerLengthPixels
,
borderBits
);
aruco
::
_drawPlanarBoardImpl
(
this
,
chessboardZoneImg
.
size
(),
markersImg
,
diffSquareMarkerLengthPixels
,
borderBits
);
markersImg
.
copyTo
(
chessboardZoneImg
);
...
...
@@ -120,17 +120,17 @@ void CharucoBoard::draw(Size outSize, OutputArray _img, int marginSize, int bord
/**
*/
CharucoBoard
CharucoBoard
::
create
(
int
squaresX
,
int
squaresY
,
float
squareLength
,
float
markerLength
,
Dictionary
dictionary
)
{
Ptr
<
CharucoBoard
>
CharucoBoard
::
create
(
int
squaresX
,
int
squaresY
,
float
squareLength
,
float
markerLength
,
Ptr
<
Dictionary
>
&
dictionary
)
{
CV_Assert
(
squaresX
>
1
&&
squaresY
>
1
&&
markerLength
>
0
&&
squareLength
>
markerLength
);
CharucoBoard
res
;
Ptr
<
CharucoBoard
>
res
=
makePtr
<
CharucoBoard
>
()
;
res
.
_squaresX
=
squaresX
;
res
.
_squaresY
=
squaresY
;
res
.
_squareLength
=
squareLength
;
res
.
_markerLength
=
markerLength
;
res
.
dictionary
=
dictionary
;
res
->
_squaresX
=
squaresX
;
res
->
_squaresY
=
squaresY
;
res
->
_squareLength
=
squareLength
;
res
->
_markerLength
=
markerLength
;
res
->
dictionary
=
dictionary
;
float
diffSquareMarkerLength
=
(
squareLength
-
markerLength
)
/
2
;
...
...
@@ -147,10 +147,10 @@ CharucoBoard CharucoBoard::create(int squaresX, int squaresY, float squareLength
corners
[
1
]
=
corners
[
0
]
+
Point3f
(
markerLength
,
0
,
0
);
corners
[
2
]
=
corners
[
0
]
+
Point3f
(
markerLength
,
-
markerLength
,
0
);
corners
[
3
]
=
corners
[
0
]
+
Point3f
(
0
,
-
markerLength
,
0
);
res
.
objPoints
.
push_back
(
corners
);
res
->
objPoints
.
push_back
(
corners
);
// first ids in dictionary
int
nextId
=
(
int
)
res
.
ids
.
size
();
res
.
ids
.
push_back
(
nextId
);
int
nextId
=
(
int
)
res
->
ids
.
size
();
res
->
ids
.
push_back
(
nextId
);
}
}
...
...
@@ -161,11 +161,11 @@ CharucoBoard CharucoBoard::create(int squaresX, int squaresY, float squareLength
corner
.
x
=
(
x
+
1
)
*
squareLength
;
corner
.
y
=
(
y
+
1
)
*
squareLength
;
corner
.
z
=
0
;
res
.
chessboardCorners
.
push_back
(
corner
);
res
->
chessboardCorners
.
push_back
(
corner
);
}
}
res
.
_getNearestMarkerCorners
();
res
->
_getNearestMarkerCorners
();
return
res
;
}
...
...
@@ -230,7 +230,7 @@ void CharucoBoard::_getNearestMarkerCorners() {
/**
* Remove charuco corners if any of their minMarkers closest markers has not been detected
*/
static
unsigned
int
_filterCornersWithoutMinMarkers
(
const
CharucoBoard
&
board
,
static
unsigned
int
_filterCornersWithoutMinMarkers
(
Ptr
<
CharucoBoard
>
&
_
board
,
InputArray
_allCharucoCorners
,
InputArray
_allCharucoIds
,
InputArray
_allArucoIds
,
int
minMarkers
,
...
...
@@ -246,8 +246,8 @@ static unsigned int _filterCornersWithoutMinMarkers(const CharucoBoard &board,
int
currentCharucoId
=
_allCharucoIds
.
getMat
().
ptr
<
int
>
(
0
)[
i
];
int
totalMarkers
=
0
;
// nomber of closest marker detected
// look for closest markers
for
(
unsigned
int
m
=
0
;
m
<
board
.
nearestMarkerIdx
[
currentCharucoId
].
size
();
m
++
)
{
int
markerId
=
board
.
ids
[
board
.
nearestMarkerIdx
[
currentCharucoId
][
m
]];
for
(
unsigned
int
m
=
0
;
m
<
_board
->
nearestMarkerIdx
[
currentCharucoId
].
size
();
m
++
)
{
int
markerId
=
_board
->
ids
[
_board
->
nearestMarkerIdx
[
currentCharucoId
][
m
]];
bool
found
=
false
;
for
(
unsigned
int
k
=
0
;
k
<
_allArucoIds
.
getMat
().
total
();
k
++
)
{
if
(
_allArucoIds
.
getMat
().
ptr
<
int
>
(
0
)[
k
]
==
markerId
)
{
...
...
@@ -286,7 +286,7 @@ static unsigned int _filterCornersWithoutMinMarkers(const CharucoBoard &board,
class
CharucoSubpixelParallel
:
public
ParallelLoopBody
{
public
:
CharucoSubpixelParallel
(
const
Mat
*
_grey
,
vector
<
Point2f
>
*
_filteredChessboardImgPoints
,
vector
<
Size
>
*
_filteredWinSizes
,
DetectorParameters
*
_params
)
vector
<
Size
>
*
_filteredWinSizes
,
const
Ptr
<
DetectorParameters
>
&
_params
)
:
grey
(
_grey
),
filteredChessboardImgPoints
(
_filteredChessboardImgPoints
),
filteredWinSizes
(
_filteredWinSizes
),
params
(
_params
)
{}
...
...
@@ -316,7 +316,7 @@ class CharucoSubpixelParallel : public ParallelLoopBody {
const
Mat
*
grey
;
vector
<
Point2f
>
*
filteredChessboardImgPoints
;
vector
<
Size
>
*
filteredWinSizes
;
DetectorParameters
*
params
;
const
Ptr
<
DetectorParameters
>
&
params
;
};
...
...
@@ -358,7 +358,7 @@ static unsigned int _selectAndRefineChessboardCorners(InputArray _allCorners, In
else
_image
.
getMat
().
copyTo
(
grey
);
DetectorParameters
params
;
// use default params for corner refinement
const
Ptr
<
DetectorParameters
>
params
=
DetectorParameters
::
create
()
;
// use default params for corner refinement
//// For each of the charuco corners, apply subpixel refinement using its correspondind winSize
// for(unsigned int i=0; i<filteredChessboardImgPoints.size(); i++) {
...
...
@@ -377,7 +377,7 @@ static unsigned int _selectAndRefineChessboardCorners(InputArray _allCorners, In
// this is the parallel call for the previous commented loop (result is equivalent)
parallel_for_
(
Range
(
0
,
(
int
)
filteredChessboardImgPoints
.
size
()),
CharucoSubpixelParallel
(
&
grey
,
&
filteredChessboardImgPoints
,
&
filteredWinSizes
,
&
params
));
CharucoSubpixelParallel
(
&
grey
,
&
filteredChessboardImgPoints
,
&
filteredWinSizes
,
params
));
// parse output
_selectedCorners
.
create
((
int
)
filteredChessboardImgPoints
.
size
(),
1
,
CV_32FC2
);
...
...
@@ -399,7 +399,7 @@ static unsigned int _selectAndRefineChessboardCorners(InputArray _allCorners, In
* distance to their closest markers
*/
static
void
_getMaximumSubPixWindowSizes
(
InputArrayOfArrays
markerCorners
,
InputArray
markerIds
,
InputArray
charucoCorners
,
const
CharucoBoard
&
board
,
InputArray
charucoCorners
,
Ptr
<
CharucoBoard
>
&
board
,
vector
<
Size
>
&
sizes
)
{
unsigned
int
nCharucoCorners
=
(
unsigned
int
)
charucoCorners
.
getMat
().
total
();
...
...
@@ -407,15 +407,15 @@ static void _getMaximumSubPixWindowSizes(InputArrayOfArrays markerCorners, Input
for
(
unsigned
int
i
=
0
;
i
<
nCharucoCorners
;
i
++
)
{
if
(
charucoCorners
.
getMat
().
ptr
<
Point2f
>
(
0
)[
i
]
==
Point2f
(
-
1
,
-
1
))
continue
;
if
(
board
.
nearestMarkerIdx
[
i
].
size
()
==
0
)
continue
;
if
(
board
->
nearestMarkerIdx
[
i
].
size
()
==
0
)
continue
;
double
minDist
=
-
1
;
int
counter
=
0
;
// calculate the distance to each of the closest corner of each closest marker
for
(
unsigned
int
j
=
0
;
j
<
board
.
nearestMarkerIdx
[
i
].
size
();
j
++
)
{
for
(
unsigned
int
j
=
0
;
j
<
board
->
nearestMarkerIdx
[
i
].
size
();
j
++
)
{
// find marker
int
markerId
=
board
.
ids
[
board
.
nearestMarkerIdx
[
i
][
j
]];
int
markerId
=
board
->
ids
[
board
->
nearestMarkerIdx
[
i
][
j
]];
int
markerIdx
=
-
1
;
for
(
unsigned
int
k
=
0
;
k
<
markerIds
.
getMat
().
total
();
k
++
)
{
if
(
markerIds
.
getMat
().
ptr
<
int
>
(
0
)[
k
]
==
markerId
)
{
...
...
@@ -425,7 +425,7 @@ static void _getMaximumSubPixWindowSizes(InputArrayOfArrays markerCorners, Input
}
if
(
markerIdx
==
-
1
)
continue
;
Point2f
markerCorner
=
markerCorners
.
getMat
(
markerIdx
).
ptr
<
Point2f
>
(
0
)[
board
.
nearestMarkerCorners
[
i
][
j
]];
markerCorners
.
getMat
(
markerIdx
).
ptr
<
Point2f
>
(
0
)[
board
->
nearestMarkerCorners
[
i
][
j
]];
Point2f
charucoCorner
=
charucoCorners
.
getMat
().
ptr
<
Point2f
>
(
0
)[
i
];
double
dist
=
norm
(
markerCorner
-
charucoCorner
);
if
(
minDist
==
-
1
)
minDist
=
dist
;
// if first distance, just assign it
...
...
@@ -453,7 +453,7 @@ static void _getMaximumSubPixWindowSizes(InputArrayOfArrays markerCorners, Input
*/
static
int
_interpolateCornersCharucoApproxCalib
(
InputArrayOfArrays
_markerCorners
,
InputArray
_markerIds
,
InputArray
_image
,
const
CharucoBoard
&
board
,
Ptr
<
CharucoBoard
>
&
_
board
,
InputArray
_cameraMatrix
,
InputArray
_distCoeffs
,
OutputArray
_charucoCorners
,
OutputArray
_charucoIds
)
{
...
...
@@ -465,22 +465,24 @@ static int _interpolateCornersCharucoApproxCalib(InputArrayOfArrays _markerCorne
// approximated pose estimation using marker corners
Mat
approximatedRvec
,
approximatedTvec
;
int
detectedBoardMarkers
;
Ptr
<
Board
>
_b
=
_board
.
staticCast
<
Board
>
();
detectedBoardMarkers
=
aruco
::
estimatePoseBoard
(
_markerCorners
,
_markerIds
,
board
,
_cameraMatrix
,
_distCoeffs
,
approximatedRvec
,
approximatedTvec
);
aruco
::
estimatePoseBoard
(
_markerCorners
,
_markerIds
,
_b
,
_cameraMatrix
,
_distCoeffs
,
approximatedRvec
,
approximatedTvec
);
if
(
detectedBoardMarkers
==
0
)
return
0
;
// project chessboard corners
vector
<
Point2f
>
allChessboardImgPoints
;
projectPoints
(
board
.
chessboardCorners
,
approximatedRvec
,
approximatedTvec
,
_cameraMatrix
,
projectPoints
(
_board
->
chessboardCorners
,
approximatedRvec
,
approximatedTvec
,
_cameraMatrix
,
_distCoeffs
,
allChessboardImgPoints
);
// calculate maximum window sizes for subpixel refinement. The size is limited by the distance
// to the closes marker corner to avoid erroneous displacements to marker corners
vector
<
Size
>
subPixWinSizes
;
_getMaximumSubPixWindowSizes
(
_markerCorners
,
_markerIds
,
allChessboardImgPoints
,
board
,
_getMaximumSubPixWindowSizes
(
_markerCorners
,
_markerIds
,
allChessboardImgPoints
,
_
board
,
subPixWinSizes
);
// filter corners outside the image and subpixel-refine charuco corners
...
...
@@ -489,7 +491,7 @@ static int _interpolateCornersCharucoApproxCalib(InputArrayOfArrays _markerCorne
allChessboardImgPoints
,
_image
,
_charucoCorners
,
_charucoIds
,
subPixWinSizes
);
// to return a charuco corner, its two closes aruco markers should have been detected
nRefinedCorners
=
_filterCornersWithoutMinMarkers
(
board
,
_charucoCorners
,
_charucoIds
,
nRefinedCorners
=
_filterCornersWithoutMinMarkers
(
_
board
,
_charucoCorners
,
_charucoIds
,
_markerIds
,
2
,
_charucoCorners
,
_charucoIds
);
return
nRefinedCorners
;
...
...
@@ -502,7 +504,7 @@ static int _interpolateCornersCharucoApproxCalib(InputArrayOfArrays _markerCorne
*/
static
int
_interpolateCornersCharucoLocalHom
(
InputArrayOfArrays
_markerCorners
,
InputArray
_markerIds
,
InputArray
_image
,
const
CharucoBoard
&
board
,
Ptr
<
CharucoBoard
>
&
_
board
,
OutputArray
_charucoCorners
,
OutputArray
_charucoIds
)
{
...
...
@@ -518,28 +520,28 @@ static int _interpolateCornersCharucoLocalHom(InputArrayOfArrays _markerCorners,
for
(
unsigned
int
i
=
0
;
i
<
nMarkers
;
i
++
)
{
vector
<
Point2f
>
markerObjPoints2D
;
int
markerId
=
_markerIds
.
getMat
().
ptr
<
int
>
(
0
)[
i
];
vector
<
int
>::
const_iterator
it
=
find
(
board
.
ids
.
begin
(),
board
.
ids
.
end
(),
markerId
);
if
(
it
==
board
.
ids
.
end
())
continue
;
int
boardIdx
=
(
int
)
std
::
distance
(
board
.
ids
.
begin
(),
it
);
vector
<
int
>::
const_iterator
it
=
find
(
_board
->
ids
.
begin
(),
_board
->
ids
.
end
(),
markerId
);
if
(
it
==
_board
->
ids
.
end
())
continue
;
int
boardIdx
=
(
int
)
std
::
distance
<
std
::
vector
<
int
>::
const_iterator
>
(
_board
->
ids
.
begin
(),
it
);
markerObjPoints2D
.
resize
(
4
);
for
(
unsigned
int
j
=
0
;
j
<
4
;
j
++
)
markerObjPoints2D
[
j
]
=
Point2f
(
board
.
objPoints
[
boardIdx
][
j
].
x
,
board
.
objPoints
[
boardIdx
][
j
].
y
);
Point2f
(
_board
->
objPoints
[
boardIdx
][
j
].
x
,
_board
->
objPoints
[
boardIdx
][
j
].
y
);
transformations
[
i
]
=
getPerspectiveTransform
(
markerObjPoints2D
,
_markerCorners
.
getMat
(
i
));
}
unsigned
int
nCharucoCorners
=
(
unsigned
int
)
board
.
chessboardCorners
.
size
();
unsigned
int
nCharucoCorners
=
(
unsigned
int
)
_board
->
chessboardCorners
.
size
();
vector
<
Point2f
>
allChessboardImgPoints
(
nCharucoCorners
,
Point2f
(
-
1
,
-
1
));
// for each charuco corner, calculate its interpolation position based on the closest markers
// homographies
for
(
unsigned
int
i
=
0
;
i
<
nCharucoCorners
;
i
++
)
{
Point2f
objPoint2D
=
Point2f
(
board
.
chessboardCorners
[
i
].
x
,
board
.
chessboardCorners
[
i
].
y
);
Point2f
objPoint2D
=
Point2f
(
_board
->
chessboardCorners
[
i
].
x
,
_board
->
chessboardCorners
[
i
].
y
);
vector
<
Point2f
>
interpolatedPositions
;
for
(
unsigned
int
j
=
0
;
j
<
board
.
nearestMarkerIdx
[
i
].
size
();
j
++
)
{
int
markerId
=
board
.
ids
[
board
.
nearestMarkerIdx
[
i
][
j
]];
for
(
unsigned
int
j
=
0
;
j
<
_board
->
nearestMarkerIdx
[
i
].
size
();
j
++
)
{
int
markerId
=
_board
->
ids
[
_board
->
nearestMarkerIdx
[
i
][
j
]];
int
markerIdx
=
-
1
;
for
(
unsigned
int
k
=
0
;
k
<
_markerIds
.
getMat
().
total
();
k
++
)
{
if
(
_markerIds
.
getMat
().
ptr
<
int
>
(
0
)[
k
]
==
markerId
)
{
...
...
@@ -569,7 +571,7 @@ static int _interpolateCornersCharucoLocalHom(InputArrayOfArrays _markerCorners,
// calculate maximum window sizes for subpixel refinement. The size is limited by the distance
// to the closes marker corner to avoid erroneous displacements to marker corners
vector
<
Size
>
subPixWinSizes
;
_getMaximumSubPixWindowSizes
(
_markerCorners
,
_markerIds
,
allChessboardImgPoints
,
board
,
_getMaximumSubPixWindowSizes
(
_markerCorners
,
_markerIds
,
allChessboardImgPoints
,
_
board
,
subPixWinSizes
);
...
...
@@ -579,7 +581,7 @@ static int _interpolateCornersCharucoLocalHom(InputArrayOfArrays _markerCorners,
allChessboardImgPoints
,
_image
,
_charucoCorners
,
_charucoIds
,
subPixWinSizes
);
// to return a charuco corner, its two closes aruco markers should have been detected
nRefinedCorners
=
_filterCornersWithoutMinMarkers
(
board
,
_charucoCorners
,
_charucoIds
,
nRefinedCorners
=
_filterCornersWithoutMinMarkers
(
_
board
,
_charucoCorners
,
_charucoIds
,
_markerIds
,
2
,
_charucoCorners
,
_charucoIds
);
return
nRefinedCorners
;
...
...
@@ -590,19 +592,19 @@ static int _interpolateCornersCharucoLocalHom(InputArrayOfArrays _markerCorners,
/**
*/
int
interpolateCornersCharuco
(
InputArrayOfArrays
_markerCorners
,
InputArray
_markerIds
,
InputArray
_image
,
const
CharucoBoard
&
board
,
InputArray
_image
,
Ptr
<
CharucoBoard
>
&
_
board
,
OutputArray
_charucoCorners
,
OutputArray
_charucoIds
,
InputArray
_cameraMatrix
,
InputArray
_distCoeffs
)
{
// if camera parameters are avaible, use approximated calibration
if
(
_cameraMatrix
.
total
()
!=
0
)
{
return
_interpolateCornersCharucoApproxCalib
(
_markerCorners
,
_markerIds
,
_image
,
board
,
return
_interpolateCornersCharucoApproxCalib
(
_markerCorners
,
_markerIds
,
_image
,
_
board
,
_cameraMatrix
,
_distCoeffs
,
_charucoCorners
,
_charucoIds
);
}
// else use local homography
else
{
return
_interpolateCornersCharucoLocalHom
(
_markerCorners
,
_markerIds
,
_image
,
board
,
return
_interpolateCornersCharucoLocalHom
(
_markerCorners
,
_markerIds
,
_image
,
_
board
,
_charucoCorners
,
_charucoIds
);
}
}
...
...
@@ -679,7 +681,7 @@ static bool _arePointsEnoughForPoseEstimation(const vector< Point3f > &points) {
/**
*/
bool
estimatePoseCharucoBoard
(
InputArray
_charucoCorners
,
InputArray
_charucoIds
,
CharucoBoard
&
board
,
InputArray
_cameraMatrix
,
InputArray
_distCoeffs
,
Ptr
<
CharucoBoard
>
&
_
board
,
InputArray
_cameraMatrix
,
InputArray
_distCoeffs
,
OutputArray
_rvec
,
OutputArray
_tvec
)
{
CV_Assert
((
_charucoCorners
.
getMat
().
total
()
==
_charucoIds
.
getMat
().
total
()));
...
...
@@ -691,8 +693,8 @@ bool estimatePoseCharucoBoard(InputArray _charucoCorners, InputArray _charucoIds
objPoints
.
reserve
(
_charucoIds
.
getMat
().
total
());
for
(
unsigned
int
i
=
0
;
i
<
_charucoIds
.
getMat
().
total
();
i
++
)
{
int
currId
=
_charucoIds
.
getMat
().
ptr
<
int
>
(
0
)[
i
];
CV_Assert
(
currId
>=
0
&&
currId
<
(
int
)
board
.
chessboardCorners
.
size
());
objPoints
.
push_back
(
board
.
chessboardCorners
[
currId
]);
CV_Assert
(
currId
>=
0
&&
currId
<
(
int
)
_board
->
chessboardCorners
.
size
());
objPoints
.
push_back
(
_board
->
chessboardCorners
[
currId
]);
}
// points need to be in different lines, check if detected points are enough
...
...
@@ -709,12 +711,11 @@ bool estimatePoseCharucoBoard(InputArray _charucoCorners, InputArray _charucoIds
/**
*/
double
calibrateCameraCharuco
(
InputArrayOfArrays
_charucoCorners
,
InputArrayOfArrays
_charucoIds
,
const
CharucoBoard
&
board
,
Size
imageSize
,
Ptr
<
CharucoBoard
>
&
_
board
,
Size
imageSize
,
InputOutputArray
_cameraMatrix
,
InputOutputArray
_distCoeffs
,
OutputArrayOfArrays
_rvecs
,
OutputArrayOfArrays
_tvecs
,
int
flags
,
TermCriteria
criteria
)
{
CV_Assert
(
_charucoIds
.
total
()
>
0
&&
(
_charucoIds
.
total
()
==
_charucoCorners
.
total
()));
// Join object points of charuco corners in a single vector for calibrateCamera() function
...
...
@@ -727,8 +728,8 @@ double calibrateCameraCharuco(InputArrayOfArrays _charucoCorners, InputArrayOfAr
for
(
unsigned
int
j
=
0
;
j
<
nCorners
;
j
++
)
{
int
pointId
=
_charucoIds
.
getMat
(
i
).
ptr
<
int
>
(
0
)[
j
];
CV_Assert
(
pointId
>=
0
&&
pointId
<
(
int
)
board
.
chessboardCorners
.
size
());
allObjPoints
[
i
].
push_back
(
board
.
chessboardCorners
[
pointId
]);
CV_Assert
(
pointId
>=
0
&&
pointId
<
(
int
)
_board
->
chessboardCorners
.
size
());
allObjPoints
[
i
].
push_back
(
_board
->
chessboardCorners
[
pointId
]);
}
}
...
...
@@ -750,9 +751,9 @@ void detectCharucoDiamond(InputArray _image, InputArrayOfArrays _markerCorners,
const
float
minRepDistanceRate
=
0.12
f
;
// create Charuco board layout for diamond (3x3 layout)
CharucoBoard
charucoDiamondLayout
;
Dictionary
dict
=
getPredefinedDictionary
(
PREDEFINED_DICTIONARY_NAME
(
0
)
);
charucoDiamondLayout
=
CharucoBoard
::
create
(
3
,
3
,
squareMarkerLengthRate
,
1.
,
dict
);
Ptr
<
Dictionary
>
dict
=
getPredefinedDictionary
(
PREDEFINED_DICTIONARY_NAME
(
0
))
;
Ptr
<
CharucoBoard
>
_charucoDiamondLayout
=
CharucoBoard
::
create
(
3
,
3
,
squareMarkerLengthRate
,
1.
,
dict
);
vector
<
vector
<
Point2f
>
>
diamondCorners
;
vector
<
Vec4i
>
diamondIds
;
...
...
@@ -808,13 +809,15 @@ void detectCharucoDiamond(InputArray _image, InputArrayOfArrays _markerCorners,
// modify charuco layout id to make sure all the ids are different than current id
for
(
int
k
=
1
;
k
<
4
;
k
++
)
charucoDiamondLayout
.
ids
[
k
]
=
currentId
+
1
+
k
;
_charucoDiamondLayout
->
ids
[
k
]
=
currentId
+
1
+
k
;
// current id is assigned to [0], so it is the marker on the top
charucoDiamondLayout
.
ids
[
0
]
=
currentId
;
_charucoDiamondLayout
->
ids
[
0
]
=
currentId
;
// try to find the rest of markers in the diamond
vector
<
int
>
acceptedIdxs
;
aruco
::
refineDetectedMarkers
(
grey
,
charucoDiamondLayout
,
currentMarker
,
currentMarkerId
,
Ptr
<
Board
>
_b
=
_charucoDiamondLayout
.
staticCast
<
Board
>
();
aruco
::
refineDetectedMarkers
(
grey
,
_b
,
currentMarker
,
currentMarkerId
,
candidates
,
noArray
(),
noArray
(),
minRepDistance
,
-
1
,
false
,
acceptedIdxs
);
...
...
@@ -836,7 +839,7 @@ void detectCharucoDiamond(InputArray _image, InputArrayOfArrays _markerCorners,
// interpolate the charuco corners of the diamond
vector
<
Point2f
>
currentMarkerCorners
;
Mat
aux
;
interpolateCornersCharuco
(
currentMarker
,
currentMarkerId
,
grey
,
charucoDiamondLayout
,
interpolateCornersCharuco
(
currentMarker
,
currentMarkerId
,
grey
,
_
charucoDiamondLayout
,
currentMarkerCorners
,
aux
,
_cameraMatrix
,
_distCoeffs
);
// if everything is ok, save the diamond
...
...
@@ -878,22 +881,22 @@ void detectCharucoDiamond(InputArray _image, InputArrayOfArrays _markerCorners,
/**
*/
void
drawCharucoDiamond
(
Dictionary
dictionary
,
Vec4i
ids
,
int
squareLength
,
int
markerLength
,
void
drawCharucoDiamond
(
Ptr
<
Dictionary
>
&
dictionary
,
Vec4i
ids
,
int
squareLength
,
int
markerLength
,
OutputArray
_img
,
int
marginSize
,
int
borderBits
)
{
CV_Assert
(
squareLength
>
0
&&
markerLength
>
0
&&
squareLength
>
markerLength
);
CV_Assert
(
marginSize
>=
0
&&
borderBits
>
0
);
// create a charuco board similar to a charuco marker and print it
CharucoBoard
board
=
Ptr
<
CharucoBoard
>
board
=
CharucoBoard
::
create
(
3
,
3
,
(
float
)
squareLength
,
(
float
)
markerLength
,
dictionary
);
// assign the charuco marker ids
for
(
int
i
=
0
;
i
<
4
;
i
++
)
board
.
ids
[
i
]
=
ids
[
i
];
board
->
ids
[
i
]
=
ids
[
i
];
Size
outSize
(
3
*
squareLength
+
2
*
marginSize
,
3
*
squareLength
+
2
*
marginSize
);
board
.
draw
(
outSize
,
_img
,
marginSize
,
borderBits
);
board
->
draw
(
outSize
,
_img
,
marginSize
,
borderBits
);
}
...
...
modules/aruco/src/dictionary.cpp
View file @
063c191d
...
...
@@ -48,6 +48,16 @@ namespace aruco {
using
namespace
std
;
/**
*/
Dictionary
::
Dictionary
(
const
Ptr
<
Dictionary
>
&
_dictionary
)
{
markerSize
=
_dictionary
->
markerSize
;
maxCorrectionBits
=
_dictionary
->
maxCorrectionBits
;
bytesList
=
_dictionary
->
bytesList
.
clone
();
}
/**
*/
Dictionary
::
Dictionary
(
const
Mat
&
_bytesList
,
int
_markerSize
,
int
_maxcorr
)
{
...
...
@@ -57,6 +67,28 @@ Dictionary::Dictionary(const Mat &_bytesList, int _markerSize, int _maxcorr) {
}
/**
*/
Ptr
<
Dictionary
>
Dictionary
::
create
(
int
nMarkers
,
int
markerSize
)
{
Ptr
<
Dictionary
>
baseDictionary
=
makePtr
<
Dictionary
>
();
return
create
(
nMarkers
,
markerSize
,
baseDictionary
);
}
/**
*/
Ptr
<
Dictionary
>
Dictionary
::
create
(
int
nMarkers
,
int
markerSize
,
Ptr
<
Dictionary
>
&
baseDictionary
)
{
return
generateCustomDictionary
(
nMarkers
,
markerSize
,
baseDictionary
);
}
/**
*/
Ptr
<
Dictionary
>
Dictionary
::
get
(
int
dict
)
{
return
getPredefinedDictionary
(
dict
);
}
/**
*/
...
...
@@ -259,50 +291,55 @@ const Dictionary DICT_7X7_250_DATA = Dictionary(Mat(250, (7*7 + 7)/8 ,CV_8UC4, (
const
Dictionary
DICT_7X7_1000_DATA
=
Dictionary
(
Mat
(
1000
,
(
7
*
7
+
7
)
/
8
,
CV_8UC4
,
(
uchar
*
)
DICT_7X7_1000_BYTES
),
7
,
6
);
const
Dictionary
&
getPredefinedDictionary
(
PREDEFINED_DICTIONARY_NAME
name
)
{
Ptr
<
Dictionary
>
getPredefinedDictionary
(
PREDEFINED_DICTIONARY_NAME
name
)
{
switch
(
name
)
{
case
DICT_ARUCO_ORIGINAL
:
return
DICT_ARUCO_DATA
;
return
makePtr
<
Dictionary
>
(
DICT_ARUCO_DATA
)
;
case
DICT_4X4_50
:
return
DICT_4X4_50_DATA
;
return
makePtr
<
Dictionary
>
(
DICT_4X4_50_DATA
)
;
case
DICT_4X4_100
:
return
DICT_4X4_100_DATA
;
return
makePtr
<
Dictionary
>
(
DICT_4X4_100_DATA
)
;
case
DICT_4X4_250
:
return
DICT_4X4_250_DATA
;
return
makePtr
<
Dictionary
>
(
DICT_4X4_250_DATA
)
;
case
DICT_4X4_1000
:
return
DICT_4X4_1000_DATA
;
return
makePtr
<
Dictionary
>
(
DICT_4X4_1000_DATA
)
;
case
DICT_5X5_50
:
return
DICT_5X5_50_DATA
;
return
makePtr
<
Dictionary
>
(
DICT_5X5_50_DATA
)
;
case
DICT_5X5_100
:
return
DICT_5X5_100_DATA
;
return
makePtr
<
Dictionary
>
(
DICT_5X5_100_DATA
)
;
case
DICT_5X5_250
:
return
DICT_5X5_250_DATA
;
return
makePtr
<
Dictionary
>
(
DICT_5X5_250_DATA
)
;
case
DICT_5X5_1000
:
return
DICT_5X5_1000_DATA
;
return
makePtr
<
Dictionary
>
(
DICT_5X5_1000_DATA
)
;
case
DICT_6X6_50
:
return
DICT_6X6_50_DATA
;
return
makePtr
<
Dictionary
>
(
DICT_6X6_50_DATA
)
;
case
DICT_6X6_100
:
return
DICT_6X6_100_DATA
;
return
makePtr
<
Dictionary
>
(
DICT_6X6_100_DATA
)
;
case
DICT_6X6_250
:
return
DICT_6X6_250_DATA
;
return
makePtr
<
Dictionary
>
(
DICT_6X6_250_DATA
)
;
case
DICT_6X6_1000
:
return
DICT_6X6_1000_DATA
;
return
makePtr
<
Dictionary
>
(
DICT_6X6_1000_DATA
)
;
case
DICT_7X7_50
:
return
DICT_7X7_50_DATA
;
return
makePtr
<
Dictionary
>
(
DICT_7X7_50_DATA
)
;
case
DICT_7X7_100
:
return
DICT_7X7_100_DATA
;
return
makePtr
<
Dictionary
>
(
DICT_7X7_100_DATA
)
;
case
DICT_7X7_250
:
return
DICT_7X7_250_DATA
;
return
makePtr
<
Dictionary
>
(
DICT_7X7_250_DATA
)
;
case
DICT_7X7_1000
:
return
DICT_7X7_1000_DATA
;
return
makePtr
<
Dictionary
>
(
DICT_7X7_1000_DATA
)
;
}
return
DICT_4X4_50_DATA
;
return
makePtr
<
Dictionary
>
(
DICT_4X4_50_DATA
);
}
Ptr
<
Dictionary
>
getPredefinedDictionary
(
int
dict
)
{
return
getPredefinedDictionary
(
PREDEFINED_DICTIONARY_NAME
(
dict
));
}
...
...
@@ -339,11 +376,11 @@ static int _getSelfDistance(const Mat &marker) {
/**
*/
Dictionary
generateCustomDictionary
(
int
nMarkers
,
int
markerSize
,
const
Dictionary
&
baseDictionary
)
{
Ptr
<
Dictionary
>
generateCustomDictionary
(
int
nMarkers
,
int
markerSize
,
Ptr
<
Dictionary
>
&
baseDictionary
)
{
Dictionary
out
;
out
.
markerSize
=
markerSize
;
Ptr
<
Dictionary
>
out
=
makePtr
<
Dictionary
>
()
;
out
->
markerSize
=
markerSize
;
// theoretical maximum intermarker distance
// See S. Garrido-Jurado, R. Muñoz-Salinas, F. J. Madrid-Cuevas, and M. J. Marín-Jiménez. 2014.
...
...
@@ -353,17 +390,17 @@ Dictionary generateCustomDictionary(int nMarkers, int markerSize,
int
tau
=
2
*
(
int
)
std
::
floor
(
float
(
C
)
*
4.
f
/
3.
f
);
// if baseDictionary is provided, calculate its intermarker distance
if
(
baseDictionary
.
bytesList
.
rows
>
0
)
{
CV_Assert
(
baseDictionary
.
markerSize
==
markerSize
);
out
.
bytesList
=
baseDictionary
.
bytesList
.
clone
();
if
(
baseDictionary
->
bytesList
.
rows
>
0
)
{
CV_Assert
(
baseDictionary
->
markerSize
==
markerSize
);
out
->
bytesList
=
baseDictionary
->
bytesList
.
clone
();
int
minDistance
=
markerSize
*
markerSize
+
1
;
for
(
int
i
=
0
;
i
<
out
.
bytesList
.
rows
;
i
++
)
{
Mat
markerBytes
=
out
.
bytesList
.
rowRange
(
i
,
i
+
1
);
for
(
int
i
=
0
;
i
<
out
->
bytesList
.
rows
;
i
++
)
{
Mat
markerBytes
=
out
->
bytesList
.
rowRange
(
i
,
i
+
1
);
Mat
markerBits
=
Dictionary
::
getBitsFromByteList
(
markerBytes
,
markerSize
);
minDistance
=
min
(
minDistance
,
_getSelfDistance
(
markerBits
));
for
(
int
j
=
i
+
1
;
j
<
out
.
bytesList
.
rows
;
j
++
)
{
minDistance
=
min
(
minDistance
,
out
.
getDistanceToId
(
markerBits
,
j
));
for
(
int
j
=
i
+
1
;
j
<
out
->
bytesList
.
rows
;
j
++
)
{
minDistance
=
min
(
minDistance
,
out
->
getDistanceToId
(
markerBits
,
j
));
}
}
tau
=
minDistance
;
...
...
@@ -377,7 +414,7 @@ Dictionary generateCustomDictionary(int nMarkers, int markerSize,
const
int
maxUnproductiveIterations
=
5000
;
int
unproductiveIterations
=
0
;
while
(
out
.
bytesList
.
rows
<
nMarkers
)
{
while
(
out
->
bytesList
.
rows
<
nMarkers
)
{
Mat
currentMarker
=
_generateRandomMarker
(
markerSize
);
int
selfDistance
=
_getSelfDistance
(
currentMarker
);
...
...
@@ -386,8 +423,8 @@ Dictionary generateCustomDictionary(int nMarkers, int markerSize,
// if self distance is better or equal than current best option, calculate distance
// to previous accepted markers
if
(
selfDistance
>=
bestTau
)
{
for
(
int
i
=
0
;
i
<
out
.
bytesList
.
rows
;
i
++
)
{
int
currentDistance
=
out
.
getDistanceToId
(
currentMarker
,
i
);
for
(
int
i
=
0
;
i
<
out
->
bytesList
.
rows
;
i
++
)
{
int
currentDistance
=
out
->
getDistanceToId
(
currentMarker
,
i
);
minDistance
=
min
(
currentDistance
,
minDistance
);
if
(
minDistance
<=
bestTau
)
{
break
;
...
...
@@ -400,7 +437,7 @@ Dictionary generateCustomDictionary(int nMarkers, int markerSize,
unproductiveIterations
=
0
;
bestTau
=
0
;
Mat
bytes
=
Dictionary
::
getByteListFromBits
(
currentMarker
);
out
.
bytesList
.
push_back
(
bytes
);
out
->
bytesList
.
push_back
(
bytes
);
}
else
{
unproductiveIterations
++
;
...
...
@@ -416,15 +453,25 @@ Dictionary generateCustomDictionary(int nMarkers, int markerSize,
tau
=
bestTau
;
bestTau
=
0
;
Mat
bytes
=
Dictionary
::
getByteListFromBits
(
bestMarker
);
out
.
bytesList
.
push_back
(
bytes
);
out
->
bytesList
.
push_back
(
bytes
);
}
}
}
// update the maximum number of correction bits for the generated dictionary
out
.
maxCorrectionBits
=
(
tau
-
1
)
/
2
;
out
->
maxCorrectionBits
=
(
tau
-
1
)
/
2
;
return
out
;
}
/**
*/
Ptr
<
Dictionary
>
generateCustomDictionary
(
int
nMarkers
,
int
markerSize
)
{
Ptr
<
Dictionary
>
baseDictionary
=
makePtr
<
Dictionary
>
();
return
generateCustomDictionary
(
nMarkers
,
markerSize
,
baseDictionary
);
}
}
}
modules/aruco/test/test_arucodetection.cpp
View file @
063c191d
...
...
@@ -62,7 +62,7 @@ CV_ArucoDetectionSimple::CV_ArucoDetectionSimple() {}
void
CV_ArucoDetectionSimple
::
run
(
int
)
{
aruco
::
Dictionary
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
DICT_6X6_250
);
Ptr
<
aruco
::
Dictionary
>
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
DICT_6X6_250
);
// 20 images
for
(
int
i
=
0
;
i
<
20
;
i
++
)
{
...
...
@@ -99,7 +99,7 @@ void CV_ArucoDetectionSimple::run(int) {
// detect markers
vector
<
vector
<
Point2f
>
>
corners
;
vector
<
int
>
ids
;
aruco
::
DetectorParameters
params
;
Ptr
<
aruco
::
DetectorParameters
>
params
=
aruco
::
DetectorParameters
::
create
()
;
aruco
::
detectMarkers
(
img
,
dictionary
,
corners
,
ids
,
params
);
// check detection results
...
...
@@ -183,7 +183,7 @@ static void getSyntheticRT(double yaw, double pitch, double distance, Mat &rvec,
/**
* @brief Create a synthetic image of a marker with perspective
*/
static
Mat
projectMarker
(
aruco
::
Dictionary
dictionary
,
int
id
,
Mat
cameraMatrix
,
double
yaw
,
static
Mat
projectMarker
(
Ptr
<
aruco
::
Dictionary
>
&
dictionary
,
int
id
,
Mat
cameraMatrix
,
double
yaw
,
double
pitch
,
double
distance
,
Size
imageSize
,
int
markerBorder
,
vector
<
Point2f
>
&
corners
)
{
...
...
@@ -257,7 +257,7 @@ void CV_ArucoDetectionPerspective::run(int) {
cameraMatrix
.
at
<
double
>
(
0
,
0
)
=
cameraMatrix
.
at
<
double
>
(
1
,
1
)
=
650
;
cameraMatrix
.
at
<
double
>
(
0
,
2
)
=
imgSize
.
width
/
2
;
cameraMatrix
.
at
<
double
>
(
1
,
2
)
=
imgSize
.
height
/
2
;
aruco
::
Dictionary
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
DICT_6X6_250
);
Ptr
<
aruco
::
Dictionary
>
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
DICT_6X6_250
);
// detect from different positions
for
(
double
distance
=
0.1
;
distance
<=
0.5
;
distance
+=
0.2
)
{
...
...
@@ -275,9 +275,9 @@ void CV_ArucoDetectionPerspective::run(int) {
// detect markers
vector
<
vector
<
Point2f
>
>
corners
;
vector
<
int
>
ids
;
aruco
::
DetectorParameters
params
;
params
.
minDistanceToBorder
=
1
;
params
.
markerBorderBits
=
markerBorder
;
Ptr
<
aruco
::
DetectorParameters
>
params
=
aruco
::
DetectorParameters
::
create
()
;
params
->
minDistanceToBorder
=
1
;
params
->
markerBorderBits
=
markerBorder
;
aruco
::
detectMarkers
(
img
,
dictionary
,
corners
,
ids
,
params
);
// check results
...
...
@@ -320,7 +320,7 @@ CV_ArucoDetectionMarkerSize::CV_ArucoDetectionMarkerSize() {}
void
CV_ArucoDetectionMarkerSize
::
run
(
int
)
{
aruco
::
Dictionary
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
DICT_6X6_250
);
Ptr
<
aruco
::
Dictionary
>
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
DICT_6X6_250
);
int
markerSide
=
20
;
int
imageSize
=
200
;
...
...
@@ -337,10 +337,10 @@ void CV_ArucoDetectionMarkerSize::run(int) {
vector
<
vector
<
Point2f
>
>
corners
;
vector
<
int
>
ids
;
aruco
::
DetectorParameters
params
;
Ptr
<
aruco
::
DetectorParameters
>
params
=
aruco
::
DetectorParameters
::
create
()
;
// set a invalid minMarkerPerimeterRate
params
.
minMarkerPerimeterRate
=
min
(
4.
,
(
4.
*
markerSide
)
/
float
(
imageSize
)
+
0.1
);
params
->
minMarkerPerimeterRate
=
min
(
4.
,
(
4.
*
markerSide
)
/
float
(
imageSize
)
+
0.1
);
aruco
::
detectMarkers
(
img
,
dictionary
,
corners
,
ids
,
params
);
if
(
corners
.
size
()
!=
0
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Error in DetectorParameters::minMarkerPerimeterRate"
);
...
...
@@ -349,7 +349,7 @@ void CV_ArucoDetectionMarkerSize::run(int) {
}
// set an valid minMarkerPerimeterRate
params
.
minMarkerPerimeterRate
=
max
(
0.
,
(
4.
*
markerSide
)
/
float
(
imageSize
)
-
0.1
);
params
->
minMarkerPerimeterRate
=
max
(
0.
,
(
4.
*
markerSide
)
/
float
(
imageSize
)
-
0.1
);
aruco
::
detectMarkers
(
img
,
dictionary
,
corners
,
ids
,
params
);
if
(
corners
.
size
()
!=
1
||
(
corners
.
size
()
==
1
&&
ids
[
0
]
!=
id
))
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Error in DetectorParameters::minMarkerPerimeterRate"
);
...
...
@@ -358,7 +358,7 @@ void CV_ArucoDetectionMarkerSize::run(int) {
}
// set a invalid maxMarkerPerimeterRate
params
.
maxMarkerPerimeterRate
=
min
(
4.
,
(
4.
*
markerSide
)
/
float
(
imageSize
)
-
0.1
);
params
->
maxMarkerPerimeterRate
=
min
(
4.
,
(
4.
*
markerSide
)
/
float
(
imageSize
)
-
0.1
);
aruco
::
detectMarkers
(
img
,
dictionary
,
corners
,
ids
,
params
);
if
(
corners
.
size
()
!=
0
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Error in DetectorParameters::maxMarkerPerimeterRate"
);
...
...
@@ -367,7 +367,7 @@ void CV_ArucoDetectionMarkerSize::run(int) {
}
// set an valid maxMarkerPerimeterRate
params
.
maxMarkerPerimeterRate
=
max
(
0.
,
(
4.
*
markerSide
)
/
float
(
imageSize
)
+
0.1
);
params
->
maxMarkerPerimeterRate
=
max
(
0.
,
(
4.
*
markerSide
)
/
float
(
imageSize
)
+
0.1
);
aruco
::
detectMarkers
(
img
,
dictionary
,
corners
,
ids
,
params
);
if
(
corners
.
size
()
!=
1
||
(
corners
.
size
()
==
1
&&
ids
[
0
]
!=
id
))
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Error in DetectorParameters::maxMarkerPerimeterRate"
);
...
...
@@ -395,11 +395,12 @@ CV_ArucoBitCorrection::CV_ArucoBitCorrection() {}
void
CV_ArucoBitCorrection
::
run
(
int
)
{
aruco
::
Dictionary
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
DICT_6X6_250
);
aruco
::
Dictionary
dictionary2
=
dictionary
;
Ptr
<
aruco
::
Dictionary
>
_dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
DICT_6X6_250
);
aruco
::
Dictionary
&
dictionary
=
*
_dictionary
;
aruco
::
Dictionary
dictionary2
=
*
_dictionary
;
int
markerSide
=
50
;
int
imageSize
=
150
;
aruco
::
DetectorParameters
params
;
Ptr
<
aruco
::
DetectorParameters
>
params
=
aruco
::
DetectorParameters
::
create
()
;
// 10 markers
for
(
int
l
=
0
;
l
<
10
;
l
++
)
{
...
...
@@ -411,9 +412,9 @@ void CV_ArucoBitCorrection::run(int) {
// 5 valid cases
for
(
int
i
=
0
;
i
<
5
;
i
++
)
{
// how many bit errors (the error is low enough so it can be corrected)
params
.
errorCorrectionRate
=
0.2
+
i
*
0.1
;
params
->
errorCorrectionRate
=
0.2
+
i
*
0.1
;
int
errors
=
(
int
)
std
::
floor
(
dictionary
.
maxCorrectionBits
*
params
.
errorCorrectionRate
-
1.
);
(
int
)
std
::
floor
(
dictionary
.
maxCorrectionBits
*
params
->
errorCorrectionRate
-
1.
);
// create erroneous marker in currentCodeBits
Mat
currentCodeBits
=
...
...
@@ -427,14 +428,14 @@ void CV_ArucoBitCorrection::run(int) {
Mat
currentCodeBytesError
=
aruco
::
Dictionary
::
getByteListFromBits
(
currentCodeBits
);
currentCodeBytesError
.
copyTo
(
dictionary2
.
bytesList
.
rowRange
(
id
,
id
+
1
));
Mat
img
=
Mat
(
imageSize
,
imageSize
,
CV_8UC1
,
Scalar
::
all
(
255
));
aruco
::
drawMarker
(
dictionary2
,
id
,
markerSide
,
marker
);
dictionary2
.
drawMarker
(
id
,
markerSide
,
marker
);
Mat
aux
=
img
.
colRange
(
30
,
30
+
markerSide
).
rowRange
(
50
,
50
+
markerSide
);
marker
.
copyTo
(
aux
);
// try to detect using original dictionary
vector
<
vector
<
Point2f
>
>
corners
;
vector
<
int
>
ids
;
aruco
::
detectMarkers
(
img
,
dictionary
,
corners
,
ids
,
params
);
aruco
::
detectMarkers
(
img
,
_
dictionary
,
corners
,
ids
,
params
);
if
(
corners
.
size
()
!=
1
||
(
corners
.
size
()
==
1
&&
ids
[
0
]
!=
id
))
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Error in bit correction"
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
...
...
@@ -445,9 +446,9 @@ void CV_ArucoBitCorrection::run(int) {
// 5 invalid cases
for
(
int
i
=
0
;
i
<
5
;
i
++
)
{
// how many bit errors (the error is too high to be corrected)
params
.
errorCorrectionRate
=
0.2
+
i
*
0.1
;
params
->
errorCorrectionRate
=
0.2
+
i
*
0.1
;
int
errors
=
(
int
)
std
::
floor
(
dictionary
.
maxCorrectionBits
*
params
.
errorCorrectionRate
+
1.
);
(
int
)
std
::
floor
(
dictionary
.
maxCorrectionBits
*
params
->
errorCorrectionRate
+
1.
);
// create erroneous marker in currentCodeBits
Mat
currentCodeBits
=
...
...
@@ -458,21 +459,23 @@ void CV_ArucoBitCorrection::run(int) {
}
// dictionary3 is only composed by the modified marker (in its original form)
aruco
::
Dictionary
dictionary3
=
dictionary
;
dictionary3
.
bytesList
=
dictionary2
.
bytesList
.
rowRange
(
id
,
id
+
1
).
clone
();
Ptr
<
aruco
::
Dictionary
>
_dictionary3
=
makePtr
<
aruco
::
Dictionary
>
(
dictionary2
.
bytesList
.
rowRange
(
id
,
id
+
1
).
clone
(),
dictionary
.
markerSize
,
dictionary
.
maxCorrectionBits
);
// add erroneous marker to dictionary2 in order to create the erroneous marker image
Mat
currentCodeBytesError
=
aruco
::
Dictionary
::
getByteListFromBits
(
currentCodeBits
);
currentCodeBytesError
.
copyTo
(
dictionary2
.
bytesList
.
rowRange
(
id
,
id
+
1
));
Mat
img
=
Mat
(
imageSize
,
imageSize
,
CV_8UC1
,
Scalar
::
all
(
255
));
aruco
::
drawMarker
(
dictionary2
,
id
,
markerSide
,
marker
);
dictionary2
.
drawMarker
(
id
,
markerSide
,
marker
);
Mat
aux
=
img
.
colRange
(
30
,
30
+
markerSide
).
rowRange
(
50
,
50
+
markerSide
);
marker
.
copyTo
(
aux
);
// try to detect using dictionary3, it should fail
vector
<
vector
<
Point2f
>
>
corners
;
vector
<
int
>
ids
;
aruco
::
detectMarkers
(
img
,
dictionary3
,
corners
,
ids
,
params
);
aruco
::
detectMarkers
(
img
,
_
dictionary3
,
corners
,
ids
,
params
);
if
(
corners
.
size
()
!=
0
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Error in DetectorParameters::errorCorrectionRate"
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
...
...
modules/aruco/test/test_boarddetection.cpp
View file @
063c191d
...
...
@@ -98,7 +98,7 @@ static void getSyntheticRT(double yaw, double pitch, double distance, Mat &rvec,
/**
* @brief Project a synthetic marker
*/
static
void
projectMarker
(
Mat
&
img
,
aruco
::
Dictionary
dictionary
,
int
id
,
static
void
projectMarker
(
Mat
&
img
,
Ptr
<
aruco
::
Dictionary
>
&
dictionary
,
int
id
,
vector
<
Point3f
>
markerObjPoints
,
Mat
cameraMatrix
,
Mat
rvec
,
Mat
tvec
,
int
markerBorder
)
{
...
...
@@ -140,15 +140,15 @@ static void projectMarker(Mat &img, aruco::Dictionary dictionary, int id,
/**
* @brief Get a synthetic image of GridBoard in perspective
*/
static
Mat
projectBoard
(
aruco
::
GridBoard
board
,
Mat
cameraMatrix
,
double
yaw
,
double
pitch
,
static
Mat
projectBoard
(
Ptr
<
aruco
::
GridBoard
>
&
board
,
Mat
cameraMatrix
,
double
yaw
,
double
pitch
,
double
distance
,
Size
imageSize
,
int
markerBorder
)
{
Mat
rvec
,
tvec
;
getSyntheticRT
(
yaw
,
pitch
,
distance
,
rvec
,
tvec
);
Mat
img
=
Mat
(
imageSize
,
CV_8UC1
,
Scalar
::
all
(
255
));
for
(
unsigned
int
m
=
0
;
m
<
board
.
ids
.
size
();
m
++
)
{
projectMarker
(
img
,
board
.
dictionary
,
board
.
ids
[
m
],
board
.
objPoints
[
m
],
cameraMatrix
,
rvec
,
for
(
unsigned
int
m
=
0
;
m
<
board
->
ids
.
size
();
m
++
)
{
projectMarker
(
img
,
board
->
dictionary
,
board
->
ids
[
m
],
board
->
objPoints
[
m
],
cameraMatrix
,
rvec
,
tvec
,
markerBorder
);
}
...
...
@@ -177,8 +177,9 @@ void CV_ArucoBoardPose::run(int) {
int
iter
=
0
;
Mat
cameraMatrix
=
Mat
::
eye
(
3
,
3
,
CV_64FC1
);
Size
imgSize
(
500
,
500
);
aruco
::
Dictionary
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
DICT_6X6_250
);
aruco
::
GridBoard
board
=
aruco
::
GridBoard
::
create
(
3
,
3
,
0.02
f
,
0.005
f
,
dictionary
);
Ptr
<
aruco
::
Dictionary
>
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
DICT_6X6_250
);
Ptr
<
aruco
::
GridBoard
>
gridboard
=
aruco
::
GridBoard
::
create
(
3
,
3
,
0.02
f
,
0.005
f
,
dictionary
);
Ptr
<
aruco
::
Board
>
board
=
gridboard
.
staticCast
<
aruco
::
Board
>
();
cameraMatrix
.
at
<
double
>
(
0
,
0
)
=
cameraMatrix
.
at
<
double
>
(
1
,
1
)
=
650
;
cameraMatrix
.
at
<
double
>
(
0
,
2
)
=
imgSize
.
width
/
2
;
cameraMatrix
.
at
<
double
>
(
1
,
2
)
=
imgSize
.
height
/
2
;
...
...
@@ -188,21 +189,21 @@ void CV_ArucoBoardPose::run(int) {
for
(
double
distance
=
0.2
;
distance
<=
0.4
;
distance
+=
0.2
)
{
for
(
int
yaw
=
0
;
yaw
<
360
;
yaw
+=
100
)
{
for
(
int
pitch
=
30
;
pitch
<=
90
;
pitch
+=
50
)
{
for
(
unsigned
int
i
=
0
;
i
<
board
.
ids
.
size
();
i
++
)
board
.
ids
[
i
]
=
(
iter
+
int
(
i
))
%
250
;
for
(
unsigned
int
i
=
0
;
i
<
gridboard
->
ids
.
size
();
i
++
)
gridboard
->
ids
[
i
]
=
(
iter
+
int
(
i
))
%
250
;
int
markerBorder
=
iter
%
2
+
1
;
iter
++
;
// create synthetic image
Mat
img
=
projectBoard
(
board
,
cameraMatrix
,
deg2rad
(
pitch
),
deg2rad
(
yaw
),
distance
,
Mat
img
=
projectBoard
(
grid
board
,
cameraMatrix
,
deg2rad
(
pitch
),
deg2rad
(
yaw
),
distance
,
imgSize
,
markerBorder
);
vector
<
vector
<
Point2f
>
>
corners
;
vector
<
int
>
ids
;
aruco
::
DetectorParameters
params
;
params
.
minDistanceToBorder
=
3
;
params
.
markerBorderBits
=
markerBorder
;
Ptr
<
aruco
::
DetectorParameters
>
params
=
aruco
::
DetectorParameters
::
create
()
;
params
->
minDistanceToBorder
=
3
;
params
->
markerBorderBits
=
markerBorder
;
aruco
::
detectMarkers
(
img
,
dictionary
,
corners
,
ids
,
params
);
if
(
ids
.
size
()
==
0
)
{
...
...
@@ -218,8 +219,8 @@ void CV_ArucoBoardPose::run(int) {
// check result
for
(
unsigned
int
i
=
0
;
i
<
ids
.
size
();
i
++
)
{
int
foundIdx
=
-
1
;
for
(
unsigned
int
j
=
0
;
j
<
board
.
ids
.
size
();
j
++
)
{
if
(
board
.
ids
[
j
]
==
ids
[
i
])
{
for
(
unsigned
int
j
=
0
;
j
<
gridboard
->
ids
.
size
();
j
++
)
{
if
(
gridboard
->
ids
[
j
]
==
ids
[
i
])
{
foundIdx
=
int
(
j
);
break
;
}
...
...
@@ -232,7 +233,7 @@ void CV_ArucoBoardPose::run(int) {
}
vector
<
Point2f
>
projectedCorners
;
projectPoints
(
board
.
objPoints
[
foundIdx
],
rvec
,
tvec
,
cameraMatrix
,
distCoeffs
,
projectPoints
(
gridboard
->
objPoints
[
foundIdx
],
rvec
,
tvec
,
cameraMatrix
,
distCoeffs
,
projectedCorners
);
for
(
int
c
=
0
;
c
<
4
;
c
++
)
{
...
...
@@ -271,8 +272,9 @@ void CV_ArucoRefine::run(int) {
int
iter
=
0
;
Mat
cameraMatrix
=
Mat
::
eye
(
3
,
3
,
CV_64FC1
);
Size
imgSize
(
500
,
500
);
aruco
::
Dictionary
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
DICT_6X6_250
);
aruco
::
GridBoard
board
=
aruco
::
GridBoard
::
create
(
3
,
3
,
0.02
f
,
0.005
f
,
dictionary
);
Ptr
<
aruco
::
Dictionary
>
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
DICT_6X6_250
);
Ptr
<
aruco
::
GridBoard
>
gridboard
=
aruco
::
GridBoard
::
create
(
3
,
3
,
0.02
f
,
0.005
f
,
dictionary
);
Ptr
<
aruco
::
Board
>
board
=
gridboard
.
staticCast
<
aruco
::
Board
>
();
cameraMatrix
.
at
<
double
>
(
0
,
0
)
=
cameraMatrix
.
at
<
double
>
(
1
,
1
)
=
650
;
cameraMatrix
.
at
<
double
>
(
0
,
2
)
=
imgSize
.
width
/
2
;
cameraMatrix
.
at
<
double
>
(
1
,
2
)
=
imgSize
.
height
/
2
;
...
...
@@ -282,23 +284,23 @@ void CV_ArucoRefine::run(int) {
for
(
double
distance
=
0.2
;
distance
<=
0.4
;
distance
+=
0.2
)
{
for
(
int
yaw
=
0
;
yaw
<
360
;
yaw
+=
100
)
{
for
(
int
pitch
=
30
;
pitch
<=
90
;
pitch
+=
50
)
{
for
(
unsigned
int
i
=
0
;
i
<
board
.
ids
.
size
();
i
++
)
board
.
ids
[
i
]
=
(
iter
+
int
(
i
))
%
250
;
for
(
unsigned
int
i
=
0
;
i
<
gridboard
->
ids
.
size
();
i
++
)
gridboard
->
ids
[
i
]
=
(
iter
+
int
(
i
))
%
250
;
int
markerBorder
=
iter
%
2
+
1
;
iter
++
;
// create synthetic image
Mat
img
=
projectBoard
(
board
,
cameraMatrix
,
deg2rad
(
pitch
),
deg2rad
(
yaw
),
distance
,
Mat
img
=
projectBoard
(
grid
board
,
cameraMatrix
,
deg2rad
(
pitch
),
deg2rad
(
yaw
),
distance
,
imgSize
,
markerBorder
);
// detect markers
vector
<
vector
<
Point2f
>
>
corners
,
rejected
;
vector
<
int
>
ids
;
aruco
::
DetectorParameters
params
;
params
.
minDistanceToBorder
=
3
;
params
.
doCornerRefinement
=
true
;
params
.
markerBorderBits
=
markerBorder
;
Ptr
<
aruco
::
DetectorParameters
>
params
=
aruco
::
DetectorParameters
::
create
()
;
params
->
minDistanceToBorder
=
3
;
params
->
doCornerRefinement
=
true
;
params
->
markerBorderBits
=
markerBorder
;
aruco
::
detectMarkers
(
img
,
dictionary
,
corners
,
ids
,
params
,
rejected
);
// remove a marker from detection
...
...
modules/aruco/test/test_charucodetection.cpp
View file @
063c191d
...
...
@@ -98,7 +98,7 @@ static void getSyntheticRT(double yaw, double pitch, double distance, Mat &rvec,
/**
* @brief Project a synthetic marker
*/
static
void
projectMarker
(
Mat
&
img
,
aruco
::
Dictionary
dictionary
,
int
id
,
static
void
projectMarker
(
Mat
&
img
,
Ptr
<
aruco
::
Dictionary
>
dictionary
,
int
id
,
vector
<
Point3f
>
markerObjPoints
,
Mat
cameraMatrix
,
Mat
rvec
,
Mat
tvec
,
int
markerBorder
)
{
...
...
@@ -176,7 +176,7 @@ static Mat projectChessboard(int squaresX, int squaresY, float squareSize, Size
/**
* @brief Check pose estimation of charuco board
*/
static
Mat
projectCharucoBoard
(
aruco
::
CharucoBoard
board
,
Mat
cameraMatrix
,
double
yaw
,
static
Mat
projectCharucoBoard
(
Ptr
<
aruco
::
CharucoBoard
>
&
board
,
Mat
cameraMatrix
,
double
yaw
,
double
pitch
,
double
distance
,
Size
imageSize
,
int
markerBorder
,
Mat
&
rvec
,
Mat
&
tvec
)
{
...
...
@@ -184,15 +184,15 @@ static Mat projectCharucoBoard(aruco::CharucoBoard board, Mat cameraMatrix, doub
// project markers
Mat
img
=
Mat
(
imageSize
,
CV_8UC1
,
Scalar
::
all
(
255
));
for
(
unsigned
int
m
=
0
;
m
<
board
.
ids
.
size
();
m
++
)
{
projectMarker
(
img
,
board
.
dictionary
,
board
.
ids
[
m
],
board
.
objPoints
[
m
],
cameraMatrix
,
rvec
,
for
(
unsigned
int
m
=
0
;
m
<
board
->
ids
.
size
();
m
++
)
{
projectMarker
(
img
,
board
->
dictionary
,
board
->
ids
[
m
],
board
->
objPoints
[
m
],
cameraMatrix
,
rvec
,
tvec
,
markerBorder
);
}
// project chessboard
Mat
chessboard
=
projectChessboard
(
board
.
getChessboardSize
().
width
,
board
.
getChessboardSize
().
height
,
board
.
getSquareLength
(),
imageSize
,
cameraMatrix
,
rvec
,
tvec
);
projectChessboard
(
board
->
getChessboardSize
().
width
,
board
->
getChessboardSize
().
height
,
board
->
getSquareLength
(),
imageSize
,
cameraMatrix
,
rvec
,
tvec
);
for
(
unsigned
int
i
=
0
;
i
<
chessboard
.
total
();
i
++
)
{
if
(
chessboard
.
ptr
<
unsigned
char
>
()[
i
]
==
0
)
{
...
...
@@ -226,8 +226,8 @@ void CV_CharucoDetection::run(int) {
int
iter
=
0
;
Mat
cameraMatrix
=
Mat
::
eye
(
3
,
3
,
CV_64FC1
);
Size
imgSize
(
500
,
500
);
aruco
::
Dictionary
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
DICT_6X6_250
);
aruco
::
CharucoBoard
board
=
aruco
::
CharucoBoard
::
create
(
4
,
4
,
0.03
f
,
0.015
f
,
dictionary
);
Ptr
<
aruco
::
Dictionary
>
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
DICT_6X6_250
);
Ptr
<
aruco
::
CharucoBoard
>
board
=
aruco
::
CharucoBoard
::
create
(
4
,
4
,
0.03
f
,
0.015
f
,
dictionary
);
cameraMatrix
.
at
<
double
>
(
0
,
0
)
=
cameraMatrix
.
at
<
double
>
(
1
,
1
)
=
650
;
cameraMatrix
.
at
<
double
>
(
0
,
2
)
=
imgSize
.
width
/
2
;
...
...
@@ -251,9 +251,9 @@ void CV_CharucoDetection::run(int) {
// detect markers
vector
<
vector
<
Point2f
>
>
corners
;
vector
<
int
>
ids
;
aruco
::
DetectorParameters
params
;
params
.
minDistanceToBorder
=
3
;
params
.
markerBorderBits
=
markerBorder
;
Ptr
<
aruco
::
DetectorParameters
>
params
=
aruco
::
DetectorParameters
::
create
()
;
params
->
minDistanceToBorder
=
3
;
params
->
markerBorderBits
=
markerBorder
;
aruco
::
detectMarkers
(
img
,
dictionary
,
corners
,
ids
,
params
);
if
(
ids
.
size
()
==
0
)
{
...
...
@@ -276,14 +276,14 @@ void CV_CharucoDetection::run(int) {
// check results
vector
<
Point2f
>
projectedCharucoCorners
;
projectPoints
(
board
.
chessboardCorners
,
rvec
,
tvec
,
cameraMatrix
,
distCoeffs
,
projectPoints
(
board
->
chessboardCorners
,
rvec
,
tvec
,
cameraMatrix
,
distCoeffs
,
projectedCharucoCorners
);
for
(
unsigned
int
i
=
0
;
i
<
charucoIds
.
size
();
i
++
)
{
int
currentId
=
charucoIds
[
i
];
if
(
currentId
>=
(
int
)
board
.
chessboardCorners
.
size
())
{
if
(
currentId
>=
(
int
)
board
->
chessboardCorners
.
size
())
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Invalid Charuco corner id"
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_MISMATCH
);
return
;
...
...
@@ -325,8 +325,8 @@ void CV_CharucoPoseEstimation::run(int) {
int
iter
=
0
;
Mat
cameraMatrix
=
Mat
::
eye
(
3
,
3
,
CV_64FC1
);
Size
imgSize
(
500
,
500
);
aruco
::
Dictionary
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
DICT_6X6_250
);
aruco
::
CharucoBoard
board
=
aruco
::
CharucoBoard
::
create
(
4
,
4
,
0.03
f
,
0.015
f
,
dictionary
);
Ptr
<
aruco
::
Dictionary
>
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
DICT_6X6_250
);
Ptr
<
aruco
::
CharucoBoard
>
board
=
aruco
::
CharucoBoard
::
create
(
4
,
4
,
0.03
f
,
0.015
f
,
dictionary
);
cameraMatrix
.
at
<
double
>
(
0
,
0
)
=
cameraMatrix
.
at
<
double
>
(
1
,
1
)
=
650
;
cameraMatrix
.
at
<
double
>
(
0
,
2
)
=
imgSize
.
width
/
2
;
...
...
@@ -349,9 +349,9 @@ void CV_CharucoPoseEstimation::run(int) {
// detect markers
vector
<
vector
<
Point2f
>
>
corners
;
vector
<
int
>
ids
;
aruco
::
DetectorParameters
params
;
params
.
minDistanceToBorder
=
3
;
params
.
markerBorderBits
=
markerBorder
;
Ptr
<
aruco
::
DetectorParameters
>
params
=
aruco
::
DetectorParameters
::
create
()
;
params
->
minDistanceToBorder
=
3
;
params
->
markerBorderBits
=
markerBorder
;
aruco
::
detectMarkers
(
img
,
dictionary
,
corners
,
ids
,
params
);
if
(
ids
.
size
()
==
0
)
{
...
...
@@ -381,14 +381,14 @@ void CV_CharucoPoseEstimation::run(int) {
// check result
vector
<
Point2f
>
projectedCharucoCorners
;
projectPoints
(
board
.
chessboardCorners
,
rvec
,
tvec
,
cameraMatrix
,
distCoeffs
,
projectPoints
(
board
->
chessboardCorners
,
rvec
,
tvec
,
cameraMatrix
,
distCoeffs
,
projectedCharucoCorners
);
for
(
unsigned
int
i
=
0
;
i
<
charucoIds
.
size
();
i
++
)
{
int
currentId
=
charucoIds
[
i
];
if
(
currentId
>=
(
int
)
board
.
chessboardCorners
.
size
())
{
if
(
currentId
>=
(
int
)
board
->
chessboardCorners
.
size
())
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Invalid Charuco corner id"
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_MISMATCH
);
return
;
...
...
@@ -429,10 +429,10 @@ void CV_CharucoDiamondDetection::run(int) {
int
iter
=
0
;
Mat
cameraMatrix
=
Mat
::
eye
(
3
,
3
,
CV_64FC1
);
Size
imgSize
(
500
,
500
);
aruco
::
Dictionary
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
DICT_6X6_250
);
Ptr
<
aruco
::
Dictionary
>
dictionary
=
aruco
::
getPredefinedDictionary
(
aruco
::
DICT_6X6_250
);
float
squareLength
=
0.03
f
;
float
markerLength
=
0.015
f
;
aruco
::
CharucoBoard
board
=
Ptr
<
aruco
::
CharucoBoard
>
board
=
aruco
::
CharucoBoard
::
create
(
3
,
3
,
squareLength
,
markerLength
,
dictionary
);
cameraMatrix
.
at
<
double
>
(
0
,
0
)
=
cameraMatrix
.
at
<
double
>
(
1
,
1
)
=
650
;
...
...
@@ -447,7 +447,7 @@ void CV_CharucoDiamondDetection::run(int) {
int
markerBorder
=
iter
%
2
+
1
;
for
(
int
i
=
0
;
i
<
4
;
i
++
)
board
.
ids
[
i
]
=
4
*
iter
+
i
;
board
->
ids
[
i
]
=
4
*
iter
+
i
;
iter
++
;
// get synthetic image
...
...
@@ -458,9 +458,9 @@ void CV_CharucoDiamondDetection::run(int) {
// detect markers
vector
<
vector
<
Point2f
>
>
corners
;
vector
<
int
>
ids
;
aruco
::
DetectorParameters
params
;
params
.
minDistanceToBorder
=
0
;
params
.
markerBorderBits
=
markerBorder
;
Ptr
<
aruco
::
DetectorParameters
>
params
=
aruco
::
DetectorParameters
::
create
()
;
params
->
minDistanceToBorder
=
0
;
params
->
markerBorderBits
=
markerBorder
;
aruco
::
detectMarkers
(
img
,
dictionary
,
corners
,
ids
,
params
);
if
(
ids
.
size
()
!=
4
)
{
...
...
@@ -483,7 +483,7 @@ void CV_CharucoDiamondDetection::run(int) {
}
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
if
(
diamondIds
[
0
][
i
]
!=
board
.
ids
[
i
])
{
if
(
diamondIds
[
0
][
i
]
!=
board
->
ids
[
i
])
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect diamond ids"
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_MISMATCH
);
return
;
...
...
@@ -492,7 +492,7 @@ void CV_CharucoDiamondDetection::run(int) {
vector
<
Point2f
>
projectedDiamondCorners
;
projectPoints
(
board
.
chessboardCorners
,
rvec
,
tvec
,
cameraMatrix
,
distCoeffs
,
projectPoints
(
board
->
chessboardCorners
,
rvec
,
tvec
,
cameraMatrix
,
distCoeffs
,
projectedDiamondCorners
);
vector
<
Point2f
>
projectedDiamondCornersReorder
(
4
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment