or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

aruco.mdcamera-calibration.mdcomputational-photography.mdcontours-shapes.mdcore-operations.mddnn.mdfeature-detection.mdgui-drawing.mdimage-processing.mdimage-video-io.mdindex.mdmachine-learning.mdobject-detection.mdtask-log.mdvideo-analysis.md

aruco.mddocs/

0

# ArUco Marker Detection

1

2

ArUco markers are square fiducial markers used for camera pose estimation, augmented reality, and object tracking. The `cv2.aruco` module provides tools for detecting ArUco markers, estimating their poses, and using them for camera calibration.

3

4

## Overview

5

6

ArUco markers are binary square patterns with a unique identifier. They're commonly used in:

7

- Camera calibration

8

- Pose estimation for AR/VR applications

9

- Robot navigation and localization

10

- Object tracking

11

- Measurement and 3D reconstruction

12

13

## Capabilities

14

15

### Dictionary Management

16

17

ArUco dictionaries define the set of valid marker patterns. OpenCV provides predefined dictionaries with various marker sizes and counts.

18

19

```python { .api }

20

def aruco.getPredefinedDictionary(name: int) -> aruco.Dictionary:

21

"""

22

Get a predefined ArUco dictionary.

23

24

Args:

25

name: Dictionary identifier (e.g., cv2.aruco.DICT_4X4_50)

26

27

Returns: ArUco dictionary object

28

"""

29

...

30

31

class aruco.Dictionary:

32

"""

33

Dictionary of ArUco marker patterns.

34

Contains all valid marker codes for a specific marker configuration.

35

"""

36

bytesList: np.ndarray # Array of marker bit patterns

37

markerSize: int # Size of marker in bits (e.g., 4, 5, 6, 7)

38

maxCorrectionBits: int # Maximum number of bits that can be corrected

39

40

def __init__(self, bytesList, markerSize, maxCorrectionBits): ...

41

def getDistanceToId(self, bits, id, allRotations=True): ...

42

def identify(self, onlyBits, idx, rotation, maxCorrectionRate): ...

43

```

44

45

**Predefined Dictionary Constants:**

46

47

```python { .api }

48

# 4x4 bit markers

49

cv2.aruco.DICT_4X4_50: int # 50 markers, 4x4 bits

50

cv2.aruco.DICT_4X4_100: int # 100 markers, 4x4 bits

51

cv2.aruco.DICT_4X4_250: int # 250 markers, 4x4 bits

52

cv2.aruco.DICT_4X4_1000: int # 1000 markers, 4x4 bits

53

54

# 5x5 bit markers

55

cv2.aruco.DICT_5X5_50: int # 50 markers, 5x5 bits

56

cv2.aruco.DICT_5X5_100: int # 100 markers, 5x5 bits

57

cv2.aruco.DICT_5X5_250: int # 250 markers, 5x5 bits

58

cv2.aruco.DICT_5X5_1000: int # 1000 markers, 5x5 bits

59

60

# 6x6 bit markers

61

cv2.aruco.DICT_6X6_50: int # 50 markers, 6x6 bits

62

cv2.aruco.DICT_6X6_100: int # 100 markers, 6x6 bits

63

cv2.aruco.DICT_6X6_250: int # 250 markers, 6x6 bits

64

cv2.aruco.DICT_6X6_1000: int # 1000 markers, 6x6 bits

65

66

# 7x7 bit markers

67

cv2.aruco.DICT_7X7_50: int # 50 markers, 7x7 bits

68

cv2.aruco.DICT_7X7_100: int # 100 markers, 7x7 bits

69

cv2.aruco.DICT_7X7_250: int # 250 markers, 7x7 bits

70

cv2.aruco.DICT_7X7_1000: int # 1000 markers, 7x7 bits

71

72

# Original ArUco dictionary

73

cv2.aruco.DICT_ARUCO_ORIGINAL: int # Original ArUco dictionary (1024 markers, 5x5 bits)

74

```

75

76

### Marker Detection

77

78

Detect ArUco markers in images using the ArucoDetector class or legacy functions.

79

80

```python { .api }

81

class aruco.ArucoDetector:

82

"""

83

ArUco marker detector (recommended for OpenCV 4.7+).

84

Encapsulates dictionary and detection parameters.

85

"""

86

def __init__(self, dictionary: aruco.Dictionary, detectorParams: aruco.DetectorParameters = None): ...

87

88

def detectMarkers(self, image: np.ndarray, corners=None, ids=None, rejectedImgPoints=None):

89

"""

90

Detect ArUco markers in an image.

91

92

Args:

93

image: Input image (grayscale or color)

94

corners: Output vector of detected marker corners

95

ids: Output vector of detected marker identifiers

96

rejectedImgPoints: Output vector of rejected candidate markers

97

98

Returns: Tuple of (corners, ids, rejected)

99

- corners: List of marker corners (list of 4x2 arrays)

100

- ids: Array of marker IDs

101

- rejected: List of rejected marker corner candidates

102

"""

103

...

104

105

class aruco.DetectorParameters:

106

"""

107

Parameters for ArUco marker detection.

108

Controls detection sensitivity, accuracy, and performance.

109

"""

110

def __init__(self): ...

111

112

# Adaptive thresholding parameters

113

adaptiveThreshWinSizeMin: int # Minimum window size for adaptive thresholding

114

adaptiveThreshWinSizeMax: int # Maximum window size for adaptive thresholding

115

adaptiveThreshWinSizeStep: int # Step size for window size search

116

adaptiveThreshConstant: float # Constant subtracted from mean in adaptive thresholding

117

118

# Contour filtering

119

minMarkerPerimeterRate: float # Minimum perimeter as ratio of image diagonal

120

maxMarkerPerimeterRate: float # Maximum perimeter as ratio of image diagonal

121

polygonalApproxAccuracyRate: float # Accuracy for polygon approximation

122

123

# Marker identification

124

minCornerDistanceRate: float # Minimum distance between corners

125

minDistanceToBorder: int # Minimum distance from image border

126

minMarkerDistanceRate: float # Minimum distance between markers

127

128

# Bit extraction

129

markerBorderBits: int # Width of marker border (usually 1)

130

perspectiveRemovePixelPerCell: int # Number of pixels per cell for perspective removal

131

perspectiveRemoveIgnoredMarginPerCell: float # Margin to ignore in each cell

132

133

# Error correction

134

maxErroneousBitsInBorderRate: float # Maximum allowed erroneous bits in border

135

minOtsuStdDev: float # Minimum standard deviation for Otsu threshold

136

errorCorrectionRate: float # Error correction rate (0.0-1.0)

137

138

# Corner refinement

139

cornerRefinementMethod: int # Corner refinement method

140

cornerRefinementWinSize: int # Window size for corner refinement

141

cornerRefinementMaxIterations: int # Max iterations for corner refinement

142

cornerRefinementMinAccuracy: float # Minimum accuracy for corner refinement

143

```

144

145

**Legacy Detection Function:**

146

147

```python { .api }

148

def aruco.detectMarkers(image, dictionary, parameters=None, corners=None, ids=None, rejectedImgPoints=None):

149

"""

150

Detect ArUco markers (legacy function, use ArucoDetector for new code).

151

152

Args:

153

image: Input image

154

dictionary: ArUco dictionary

155

parameters: Detector parameters

156

corners: Output marker corners

157

ids: Output marker IDs

158

rejectedImgPoints: Output rejected candidates

159

160

Returns: Tuple of (corners, ids, rejected)

161

"""

162

...

163

```

164

165

**Usage Example:**

166

167

```python

168

import cv2

169

import numpy as np

170

171

# Load ArUco dictionary

172

aruco_dict = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_6X6_250)

173

174

# Create detector parameters

175

parameters = cv2.aruco.DetectorParameters()

176

parameters.adaptiveThreshConstant = 7

177

178

# Create detector

179

detector = cv2.aruco.ArucoDetector(aruco_dict, parameters)

180

181

# Read image

182

image = cv2.imread('markers.jpg')

183

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

184

185

# Detect markers

186

corners, ids, rejected = detector.detectMarkers(gray)

187

188

print(f"Detected {len(corners)} markers")

189

if ids is not None:

190

print(f"Marker IDs: {ids.flatten()}")

191

```

192

193

### Marker Visualization

194

195

Draw detected markers and marker axes on images.

196

197

```python { .api }

198

def aruco.drawDetectedMarkers(image, corners, ids=None, borderColor=(0, 255, 0)):

199

"""

200

Draw detected markers on an image.

201

202

Args:

203

image: Input/output image

204

corners: Detected marker corners (from detectMarkers)

205

ids: Detected marker IDs (optional)

206

borderColor: Color for marker borders (B, G, R)

207

208

Returns: Image with drawn markers

209

"""

210

...

211

212

def aruco.drawMarker(dictionary, id, sidePixels, img=None, borderBits=1):

213

"""

214

Generate an ArUco marker image.

215

216

Args:

217

dictionary: ArUco dictionary

218

id: Marker ID to generate (0 to dictionary size - 1)

219

sidePixels: Size of output image in pixels

220

img: Output image (if None, creates new image)

221

borderBits: Width of marker border in bits (usually 1)

222

223

Returns: Marker image

224

"""

225

...

226

227

def aruco.drawAxis(image, cameraMatrix, distCoeffs, rvec, tvec, length):

228

"""

229

Draw coordinate system axes for a marker pose.

230

231

Args:

232

image: Input/output image

233

cameraMatrix: Camera intrinsic matrix (3x3)

234

distCoeffs: Camera distortion coefficients

235

rvec: Rotation vector for marker pose

236

tvec: Translation vector for marker pose

237

length: Length of axes in same units as tvec

238

239

Returns: Image with drawn axes (X=red, Y=green, Z=blue)

240

"""

241

...

242

```

243

244

**Usage Example:**

245

246

```python

247

# Draw detected markers

248

if ids is not None:

249

cv2.aruco.drawDetectedMarkers(image, corners, ids)

250

251

# Generate a marker for printing

252

marker_image = cv2.aruco.drawMarker(aruco_dict, id=42, sidePixels=200)

253

cv2.imwrite('marker_42.png', marker_image)

254

```

255

256

### Pose Estimation

257

258

Estimate the 3D pose (position and orientation) of markers relative to the camera.

259

260

```python { .api }

261

def aruco.estimatePoseSingleMarkers(corners, markerLength, cameraMatrix, distCoeffs, rvecs=None, tvecs=None):

262

"""

263

Estimate pose of single ArUco markers.

264

265

Args:

266

corners: Detected marker corners (from detectMarkers)

267

markerLength: Physical marker side length in meters

268

cameraMatrix: Camera intrinsic matrix (3x3)

269

distCoeffs: Camera distortion coefficients

270

rvecs: Output rotation vectors for each marker

271

tvecs: Output translation vectors for each marker

272

273

Returns: Tuple of (rvecs, tvecs, objPoints)

274

- rvecs: Rotation vectors (axis-angle representation)

275

- tvecs: Translation vectors (camera to marker center)

276

- objPoints: 3D corner points in marker coordinate system

277

"""

278

...

279

```

280

281

**Usage Example:**

282

283

```python

284

# Estimate marker poses

285

if ids is not None:

286

# Camera calibration parameters

287

camera_matrix = np.array([[800, 0, 320], [0, 800, 240], [0, 0, 1]], dtype=float)

288

dist_coeffs = np.zeros(5)

289

marker_length = 0.05 # 5 cm markers

290

291

# Estimate poses

292

rvecs, tvecs, _ = cv2.aruco.estimatePoseSingleMarkers(

293

corners, marker_length, camera_matrix, dist_coeffs

294

)

295

296

# Draw axes on each marker

297

for i in range(len(ids)):

298

cv2.aruco.drawAxis(image, camera_matrix, dist_coeffs,

299

rvecs[i], tvecs[i], marker_length * 0.5)

300

301

# Print distance to first marker

302

distance = np.linalg.norm(tvecs[0])

303

print(f"Marker 0 distance: {distance:.3f} meters")

304

```

305

306

### Board Detection

307

308

ArUco boards are collections of markers with known spatial arrangement, useful for camera calibration and more robust pose estimation.

309

310

```python { .api }

311

class aruco.Board:

312

"""

313

Base class for ArUco marker boards.

314

"""

315

dictionary: aruco.Dictionary # Dictionary used by the board

316

ids: np.ndarray # Marker IDs in the board

317

objPoints: list # 3D positions of marker corners

318

319

class aruco.GridBoard(aruco.Board):

320

"""

321

Grid board of ArUco markers.

322

"""

323

@staticmethod

324

def create(markersX, markersY, markerLength, markerSeparation, dictionary, firstMarker=0):

325

"""

326

Create a grid board.

327

328

Args:

329

markersX: Number of markers in X direction

330

markersY: Number of markers in Y direction

331

markerLength: Marker side length (same units as markerSeparation)

332

markerSeparation: Separation between markers

333

dictionary: ArUco dictionary

334

firstMarker: ID of first marker in board

335

336

Returns: GridBoard object

337

"""

338

...

339

340

def aruco.estimatePoseBoard(corners, ids, board, cameraMatrix, distCoeffs, rvec=None, tvec=None):

341

"""

342

Estimate pose of an ArUco board.

343

344

Args:

345

corners: Detected marker corners

346

ids: Detected marker IDs

347

board: Board object

348

cameraMatrix: Camera intrinsic matrix

349

distCoeffs: Camera distortion coefficients

350

rvec: Initial/output rotation vector

351

tvec: Initial/output translation vector

352

353

Returns: Tuple of (num_markers, rvec, tvec)

354

- num_markers: Number of markers used for pose estimation

355

- rvec: Rotation vector

356

- tvec: Translation vector

357

"""

358

...

359

```

360

361

### ChArUco Boards

362

363

ChArUco boards combine a chessboard pattern with ArUco markers, providing benefits of both (corner accuracy + robust detection).

364

365

```python { .api }

366

class aruco.CharucoBoard(aruco.Board):

367

"""

368

ChArUco board - chessboard + ArUco markers.

369

Provides accurate corners from chessboard and robust detection from markers.

370

"""

371

@staticmethod

372

def create(squaresX, squaresY, squareLength, markerLength, dictionary):

373

"""

374

Create a ChArUco board.

375

376

Args:

377

squaresX: Number of chessboard squares in X direction

378

squaresY: Number of chessboard squares in Y direction

379

squareLength: Chessboard square side length

380

markerLength: ArUco marker side length

381

dictionary: ArUco dictionary

382

383

Returns: CharucoBoard object

384

"""

385

...

386

387

class aruco.CharucoDetector:

388

"""

389

ChArUco pattern detector.

390

"""

391

def __init__(self, board, charucoParams=None, detectorParams=None, refineParams=None): ...

392

393

def detectBoard(self, image, charucoCorners=None, charucoIds=None, markerCorners=None, markerIds=None):

394

"""

395

Detect ChArUco board corners.

396

397

Args:

398

image: Input image

399

charucoCorners: Output chessboard corner coordinates

400

charucoIds: Output chessboard corner IDs

401

markerCorners: Output ArUco marker corners

402

markerIds: Output ArUco marker IDs

403

404

Returns: Tuple of (charucoCorners, charucoIds, markerCorners, markerIds)

405

"""

406

...

407

408

def aruco.interpolateCornersCharuco(markerCorners, markerIds, image, board, charucoCorners=None, charucoIds=None, cameraMatrix=None, distCoeffs=None, minMarkers=2):

409

"""

410

Interpolate ChArUco corners from detected ArUco markers.

411

412

Args:

413

markerCorners: Detected ArUco marker corners

414

markerIds: Detected ArUco marker IDs

415

image: Input image

416

board: ChArUco board

417

charucoCorners: Output ChArUco corner coordinates

418

charucoIds: Output ChArUco corner IDs

419

cameraMatrix: Optional camera matrix for refinement

420

distCoeffs: Optional distortion coefficients

421

minMarkers: Minimum number of adjacent markers for corner interpolation

422

423

Returns: Tuple of (num_corners, charucoCorners, charucoIds)

424

"""

425

...

426

427

def aruco.drawDetectedCornersCharuco(image, charucoCorners, charucoIds=None, cornerColor=(255, 0, 0)):

428

"""

429

Draw detected ChArUco corners.

430

431

Args:

432

image: Input/output image

433

charucoCorners: Detected ChArUco corners

434

charucoIds: Detected ChArUco corner IDs

435

cornerColor: Color for corners

436

437

Returns: Image with drawn corners

438

"""

439

...

440

```

441

442

### Camera Calibration with ArUco

443

444

Use ArUco markers or ChArUco boards for camera calibration.

445

446

```python { .api }

447

def aruco.calibrateCameraAruco(corners, ids, counter, board, imageSize, cameraMatrix, distCoeffs, rvecs=None, tvecs=None, flags=0, criteria=None):

448

"""

449

Calibrate camera using ArUco board.

450

451

Args:

452

corners: Vector of detected marker corners for each image

453

ids: Vector of detected marker IDs for each image

454

counter: Number of markers detected in each image

455

board: ArUco board

456

imageSize: Image size

457

cameraMatrix: Input/output camera matrix

458

distCoeffs: Input/output distortion coefficients

459

rvecs: Output rotation vectors for each image

460

tvecs: Output translation vectors for each image

461

flags: Calibration flags (same as cv2.calibrateCamera)

462

criteria: Termination criteria

463

464

Returns: Tuple of (reprojection_error, cameraMatrix, distCoeffs, rvecs, tvecs)

465

"""

466

...

467

468

def aruco.calibrateCameraCharuco(charucoCorners, charucoIds, board, imageSize, cameraMatrix, distCoeffs, rvecs=None, tvecs=None, flags=0, criteria=None):

469

"""

470

Calibrate camera using ChArUco board (more accurate than ArUco-only).

471

472

Args:

473

charucoCorners: Vector of detected ChArUco corners for each image

474

charucoIds: Vector of detected ChArUco corner IDs for each image

475

board: ChArUco board

476

imageSize: Image size

477

cameraMatrix: Input/output camera matrix

478

distCoeffs: Input/output distortion coefficients

479

rvecs: Output rotation vectors for each image

480

tvecs: Output translation vectors for each image

481

flags: Calibration flags

482

criteria: Termination criteria

483

484

Returns: Tuple of (reprojection_error, cameraMatrix, distCoeffs, rvecs, tvecs)

485

"""

486

...

487

```

488

489

## Complete Workflow Example

490

491

```python

492

import cv2

493

import numpy as np

494

495

# 1. Create and print markers

496

aruco_dict = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_6X6_250)

497

498

# Generate markers for printing

499

for marker_id in range(4):

500

marker_img = cv2.aruco.drawMarker(aruco_dict, marker_id, 200)

501

cv2.imwrite(f'marker_{marker_id}.png', marker_img)

502

503

# 2. Detect markers in video

504

detector = cv2.aruco.ArucoDetector(aruco_dict)

505

cap = cv2.VideoCapture(0)

506

507

# Camera calibration (replace with your calibrated values)

508

camera_matrix = np.array([[800, 0, 320], [0, 800, 240], [0, 0, 1]], dtype=float)

509

dist_coeffs = np.zeros(5)

510

marker_length = 0.05 # 5 cm

511

512

while True:

513

ret, frame = cap.read()

514

if not ret:

515

break

516

517

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

518

519

# Detect markers

520

corners, ids, rejected = detector.detectMarkers(gray)

521

522

if ids is not None:

523

# Draw detected markers

524

cv2.aruco.drawDetectedMarkers(frame, corners, ids)

525

526

# Estimate poses

527

rvecs, tvecs, _ = cv2.aruco.estimatePoseSingleMarkers(

528

corners, marker_length, camera_matrix, dist_coeffs

529

)

530

531

# Draw axes for each marker

532

for i in range(len(ids)):

533

cv2.aruco.drawAxis(frame, camera_matrix, dist_coeffs,

534

rvecs[i], tvecs[i], marker_length * 0.5)

535

536

cv2.imshow('ArUco Detection', frame)

537

if cv2.waitKey(1) & 0xFF == ord('q'):

538

break

539

540

cap.release()

541

cv2.destroyAllWindows()

542

```

543