Marker rendering and pose recognition.
MarkerPos consists of 2 parts:
- Marker rendering - creates a 3D environment by using real world camera parameters and renders a marker with the given pose.
- Marker recognition - the rendered image is being used as an input to the recognition module in order to find marker's 3D pose in the camera space.
We need 6 parameters in order to create the simplest camera in our imaginary environment:
- sensor resolution (width and height)
- focal length (horizontal and vertical)
- principal point coordinates (X and Y)
A marker is just a flat square image that consists of 2 parts:
- a white frame along the edges
- an array of N*N smaller black-or-white squares
Figure 1. An example of a marker with N=3 (ID=4).
Four corner squares (3 white and 1 black) are used to calculate marker rotation (0, 90, 180, 270 degrees), the rest make up its ID number. N can be in the range [2; 6]. N=2 means there is no ID (2*2=4 - only four corner squares), N=6 means the ID is a 32-bit number (6*6-4=32).
Figure 2. A marker in a standard upright position. Corner squares are marked with 'X', numbers 0-4 denote ID bit numbers (0 being the LSB).
The entire recognition algorithm is just a solution to the P4P problem (it currently uses the cv::solvePNP function). Real camera is being simulated by calculating the OpenGL perspective matrix from camera's intrinsic parameters. Marker 3D position values are the same as OpenGL coordinates. Rotation matrix is decomposed into Euler angles, we don't use angles outside of (-90; 90), except for rotating around OZ.
The orientation in OpenGL is as follows:
- X increases to the right
- Y increases upwards
- Z increases towards us (we look at negative Z)
The following plots show absolute erros between real marker pose and the measured one. In images 1-3 marker distance from the camera is locked at 3.0.
To build the project you will need:
Copyright 2016 Łukasz Nocuń