Comprehensive guide to marker detection.
Comprehensive guide to marker detection.
This page provides detailed information and code examples for detecting various types of markers using the MarkerDetection and MarkerConfiguration classes. These tools are essential for computer vision applications such as camera calibration, pose estimation, and augmented reality.
Marker Detection Overview
Marker detection is a fundamental computer vision technique used for camera calibration, pose estimation, and augmented reality applications. The MarkerDetection class provides a unified interface for detecting various types of markers, while the MarkerConfiguration class allows you to configure the specific marker type and parameters.
Applications
- Camera Calibration: Determine intrinsic camera parameters (focal length, principal point, distortion coefficients)
- Pose Estimation: Calculate the 3D position and orientation of cameras or objects
- Augmented Reality: Track real-world objects to overlay virtual content
- Robotics: Localize robots or tools in 3D space
- Medical Imaging: Track surgical instruments or patient anatomy
- Quality Control: Measure object positions and orientations in manufacturing
Typical Workflow
- Configure Marker Type: Set up the appropriate marker configuration
- Detect Markers: Process images to find marker corners
- Extract Points: Get 2D image points and corresponding 3D object points
- Estimate Pose: Calculate camera pose using camera parameters
- Validate Results: Check detection quality and pose accuracy
Available Marker Types
The ImFusion SDK supports several marker types, each with different characteristics and use cases:
Chessboard
- Description: Traditional black and white checkerboard pattern
- Pros: Simple, reliable, widely supported
- Best for: Camera calibration
- Configuration: Grid size, cell size, detector parameters
Charuco Board
- Description: Chessboard with embedded ArUco markers
- Pros: Robust detection, handles partial occlusion, good for calibration
- Best for: Camera calibration
- Configuration: Grid size, cell size, marker size, dictionary, detector parameters
ArUco Markers
- Description: Binary-coded square markers with unique IDs
- Pros: Fast detection, unique identification, handles occlusion
- Best for: Pose estimation, augmented reality, tracking
- Configuration: Dictionary, marker size, detector parameters
AprilTag
- Description: Robust fiducial markers with error correction
- Pros: Very robust, handles lighting variations, unique IDs
- Cons: Larger markers needed for good detection
- Best for: Industrial applications, outdoor use, long-range detection
- Configuration: Family, marker size, detector parameters
STag
- Description: Circular fiducial markers with high accuracy
- Pros: Sub-pixel accuracy, handles perspective distortion well
- Cons: Limited number of unique markers
- Best for: High-precision applications
- Configuration: Diameter, detector parameters
Circle Board
- Description: Pattern of circular markers arranged in a grid
- Pros: Rotation invariant, handles perspective well
- Cons: Requires good contrast, can be affected by lighting
- Best for: Camera calibration, industrial applications
- Configuration: Grid size, circle spacing, detector parameters
Basic Marker Detection Usage
Basic Chessboard Detection
The following example demonstrates basic chessboard detection:
#include <ImFusion/Base/SharedImage.h>
#include <ImFusion/Vision/MarkerDetection.h>
#include <ImFusion/Vision/MarkerConfiguration.h>
chessboardParams.gridSize = vec2i(9, 7);
chessboardParams.cellSize = vec2(30, 30);
if (success) {
}
Describes the configuration of a marker calibration target.
Definition MarkerConfiguration.h:17
void setMarkerType(MarkerType type)
Set Marker type.
void setChessboardParameters(const ChessboardInfo ¶ms)
Set Chesssboard parameters.
Generic marker detection class for a wide range of marker types, such as Aruco, Charuco,...
Definition MarkerDetection.h:20
void setMarkerConfiguration(const MarkerConfiguration &markerConfig)
Set marker configuration for the marker detection.
Definition MarkerDetection.h:25
bool detectMarker(const SharedImage *image, SharedImage *detectionImage=nullptr)
Run marker detection on provided image detectionImage is an optional output which must have the same ...
void detections(std::vector< vec3 > &objectPoints, std::vector< vec2 > &imagePoints, std::vector< int > *pointIds=nullptr, std::vector< std::vector< vec2 > > *markerCorners=nullptr, std::vector< int > *markerIds=nullptr) const
Obtain extracted marker parameters.
#define LOG_INFO(...)
Emits a log message of Log::Level::Info, optionally with a category.
Definition Log.h:247
Namespace of the ImFusion SDK.
Definition Assert.h:7
Information about a chessboard.
Definition MarkerConfiguration.h:155
Charuco Board Detection
Charuco boards combine the benefits of chessboards and ArUco markers:
#include <ImFusion/Base/SharedImage.h>
#include <ImFusion/Vision/MarkerDetection.h>
#include <ImFusion/Vision/MarkerConfiguration.h>
charucoParams.gridSize = vec2i(9, 7);
charucoParams.cellSize = 30.0;
charucoParams.markerSize = 10.0;
charucoParams.dictionary = 0;
charucoParams.minAdjacentMarkers = 2;
if (success) {
detector.
detections(objectPoints, imagePoints, &pointIds, &markerCorners, &markerIds);
}
void setCharucoBoardParameters(const CharucoBoardInfo ¶ms)
Set Charuco parameters.
void setDetectSizeHintAutomatically(bool v)
If set to true and if not all markers were detected during the first time, the marker detection will ...
Definition MarkerDetection.h:90
Information about a Charuco board.
Definition MarkerConfiguration.h:141
ArUco Marker Detection
ArUco markers are ideal for pose estimation and tracking:
#include <ImFusion/Base/SharedImage.h>
#include <ImFusion/Vision/MarkerDetection.h>
#include <ImFusion/Vision/MarkerConfiguration.h>
arucoParams.id = 0;
arucoParams.dictionary = 3;
arucoParams.size = 50.0;
arucoParams.T = mat4::Identity();
arucoParams2.id = 1;
arucoParams2.dictionary = 3;
arucoParams2.size = 50.0;
arucoParams2.T = mat4::Identity();
arucoParams2.T.block<3, 1>(0, 3) = vec3(100.0, 0.0, 0.0);
detectorParams.adaptiveThreshWinSizeMin = 3;
detectorParams.adaptiveThreshWinSizeMax = 23;
detectorParams.minMarkerPerimeterRate = 0.03;
detectorParams.maxMarkerPerimeterRate = 4.0;
detectorParams.cornerRefinementMethod = MarkerConfiguration::DetectorParameters::Subpix;
detectorParams.cornerRefinementWinSize = 5;
if (success) {
detector.
detections(objectPoints, imagePoints, &pointIds, &markerCorners, &markerIds);
for (
size_t i = 0; i < markerIds.
size(); ++i) {
LOG_INFO(
"Marker ID: " << markerIds[i]);
}
}
void addArucoMarker(const ArucoMarkerInfo ¶ms)
Add Aruco marker with specified parameters.
Information about a single Aruco marker.
Definition MarkerConfiguration.h:99
Detector parameters for Aruco markers, boards and Charuco boards.
Definition MarkerConfiguration.h:38
Pose Estimation
Once markers are detected, you can estimate the camera pose:
#include <ImFusion/Base/SharedImage.h>
#include <ImFusion/Vision/MarkerDetection.h>
#include <ImFusion/Vision/MarkerConfiguration.h>
mat3 K;
vec5 dist;
if (success) {
double reprojectionError;
mat4 cameraPose = detector.
pose(&reprojectionError, &reprojectedPoints);
if (cameraPose != mat4::Zero()) {
LOG_INFO(
"Camera pose estimated successfully");
LOG_INFO(
"Reprojection error: " << reprojectionError <<
" pixels");
mat3 rotation = cameraPose.block<3, 3>(0, 0);
vec3 translation = cameraPose.block<3, 1>(0, 3);
LOG_INFO(
"Translation: [" << translation.x() <<
", " << translation.y() <<
", " << translation.z() <<
"]");
} else {
}
}
void setCameraParameters(const mat3 &K, const Eigen::Matrix< double, 5, 1 > &dist)
Set camera parameters.
Definition MarkerDetection.h:52
mat4 pose(double *mre=nullptr, std::vector< vec2 > *reprojectedPoints=nullptr)
Estimate camera pose (i.e.
#define LOG_WARN(...)
Emits a log message of Log::Level::Warning, optionally with a category.
Definition Log.h:252
Marker Generation
The MarkerGenerationAlgorithm class allows you to generate various types of markers for printing and use in calibration or tracking applications.
Basic Marker Generation
Generate a chessboard pattern for camera calibration:
#include <ImFusion/Vision/MarkerGenerationAlgorithm.h>
#include <ImFusion/Vision/MarkerConfiguration.h>
chessboardParams.gridSize = vec2i(9, 7);
chessboardParams.cellSize = vec2(30, 30);
generator.setMarkerConfig(config);
Algorithm for creating calibration markers.
Definition MarkerGenerationAlgorithm.h:14
Parameter< std::string > p_outputSVGPath
If set, the generated marker will be saved as SVG to this path.
Definition MarkerGenerationAlgorithm.h:29
Parameter< double > p_dpi
Dots per inch for the marker, used to calculate the size of the marker in pixels.
Definition MarkerGenerationAlgorithm.h:31
Parameter< int > p_padding
Padding in pixels around the marker, useful for printing markers.
Definition MarkerGenerationAlgorithm.h:30
void compute() override
Execute the algorithm.
Charuco Board Generation
Generate a Charuco board for robust calibration:
#include <ImFusion/Vision/MarkerGenerationAlgorithm.h>
#include <ImFusion/Vision/MarkerConfiguration.h>
charucoParams.gridSize = vec2i(9, 7);
charucoParams.cellSize = 30.0;
charucoParams.markerSize = 10.0;
charucoParams.dictionary = 0;
charucoParams.minAdjacentMarkers = 2;
generator.setMarkerConfig(config);
Circle Board Generation
Generate a circle board pattern:
#include <ImFusion/Vision/MarkerGenerationAlgorithm.h>
#include <ImFusion/Vision/MarkerConfiguration.h>
circleParams.gridSize = vec2i(9, 7);
generator.setMarkerConfig(config);
void setCircleBoardParameters(const CircleBoardInfo ¶ms)
Set Circle Board parameters.
Parameter< double > p_circleDiameter
0 means automatic diameter based on circle spacing
Definition MarkerGenerationAlgorithm.h:32
Information about a circle board.
Definition MarkerConfiguration.h:163
bool symmetric
Asymmetric grids have an additional line of circles offset by half the circle spacing between every r...
Definition MarkerConfiguration.h:166
double circleSpacing
Spacing between the circle centers.
Definition MarkerConfiguration.h:165
Generation Parameters
The marker generation algorithm provides several parameters to control the output:
DPI and Resolution
- DPI: Controls the resolution of the generated marker (typically 300-600 DPI for printing)
- Padding: Adds space around the marker for easier handling and printing
- Circle Diameter: For circle boards, controls the size of individual circles
Output Formats
- SVG: Vector format for scalable printing and editing
- Direct Image: Access the generated image programmatically for further processing via takeOutput
Visualization and Debugging
Visualization Example
Create detection visualization for debugging and validation:
#include <ImFusion/Base/SharedImage.h>
#include <ImFusion/Vision/MarkerDetection.h>
#include <ImFusion/Vision/MarkerConfiguration.h>
auto detectionImage = inputImage->clone();
bool success = detector.
detectMarker(inputImage.
get(), detectionImage.get());
if (success) {
saveImage(detectionImage.get(), "detection_result.jpg");
detector.
detections(objectPoints, imagePoints, &pointIds, &markerCorners, &markerIds);
LOG_INFO(
" Total corners detected: " << imagePoints.
size());
for (
size_t i = 0; i < markerIds.
size(); ++i) {
LOG_INFO(
" Marker " << i <<
": ID=" << markerIds[i] <<
", Corners=" << markerCorners[i].size());
}
for (
size_t i = 0; i < imagePoints.
size(); ++i) {
LOG_INFO(
" Corner " << i <<
": (" << imagePoints[i].x() <<
", " << imagePoints[i].y() <<
")");
}
}
}
Best Practices
Marker Type Selection Guidelines
Choose the appropriate marker type based on your application:
Camera Calibration
- Chessboard: Simple, reliable, good for static environments
- Charuco Board: Robust, handles partial occlusion, good for dynamic environments
- Circle Board: Rotation invariant, good for industrial applications
Pose Tracking
- ArUco Markers: Fast detection, unique IDs, good for real-time applications
- AprilTag: Very robust, handles lighting variations, good for outdoor use
- STag: High precision, good for medical or precision applications
Parameter Tuning Guidelines
Size and Scale Parameters
- Marker Size: Should be large enough for reliable detection (typically 20-100 mm)
- Grid Size: Balance between detection robustness and computational cost
- Cell Size: Should match the physical size of your calibration target
Detection Parameters
- Adaptive Threshold: Adjust for different lighting conditions
- Corner Refinement: Use subpixel refinement for higher accuracy
- Minimum Perimeter Rate: Adjust based on marker distance from camera
Environmental Considerations
Lighting
- Even Illumination: Avoid shadows and specular reflections
- Contrast: Ensure good contrast between marker and background
- Dynamic Range: Consider using HDR imaging for challenging lighting
Motion and Blur
- Exposure Time: Use short exposure to minimize motion blur
- Frame Rate: Higher frame rates for moving targets
- Stabilization: Consider image stabilization for handheld cameras
Validation and Quality Control
Reprojection Error
- Acceptable Range: Typically < 1-2 pixels for good calibration
- Monitoring: Track reprojection error over time
- Thresholds: Set appropriate thresholds for your application
Coverage and Distribution
- Image Coverage: Ensure markers cover the full image area
- Depth Variation: Include markers at different distances
- Orientation: Vary marker orientations for robust calibration
Troubleshooting
Common Issues and Solutions
No Detection
- Symptoms: No markers detected despite being visible
- Solutions:
- Check marker configuration parameters
- Verify marker size and grid size
- Adjust detector parameters for lighting conditions
- Ensure good contrast between marker and background
Poor Detection Accuracy
- Symptoms: High reprojection error, inconsistent results
- Solutions:
- Use subpixel corner refinement
- Increase marker size or improve image quality
- Check for motion blur or camera shake
- Verify camera parameters are correct
Slow Performance
- Symptoms: Long detection times
- Solutions:
- Use size hints to limit search area
- Reduce grid size or number of markers
- Optimize detector parameters
- Consider using GPU acceleration where available
False Positives
- Symptoms: Detecting markers where none exist
- Solutions:
- Adjust minimum perimeter rate
- Increase minimum corner distance
- Use more restrictive detector parameters
- Enable duplicate marker removal
- See also
- MarkerDetection class, MarkerConfiguration class