AbyssGaze

使用Opencv创建tag板

由于要完成3D多视角下数据集的搭建,所以要尽兴多视角下,相机的位姿估计。由于生活中部分物体的纹理信息并不丰富,所以使用sift等特征点然后LM求解并不可靠,而在一侧放置标定板,会因为视角的变化,导致部分被遮挡,所以此处使用了一圈tag来进行位姿估计,在创建board时,犯了一些错误,此处也会将相应的视线代码贴出来,仅供参考。

marker的生成

单独生成对应的marker,具体的函数如下:

1
2
3
4
Ptr<aruco::Dictionary> dictionary = aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
Mat markerImage;
aruco::drawMarker(dictionary, 10, 200, markerImage);

board的生成

虽然能生成单个的marker但是想要生成多个marker联合的board,可以运行下面的代码:

1
2
3
4
5
6
Ptr<aruco::Dictionary> dictionary = aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
Ptr<aruco::GridBoard> board = aruco::GridBoard::create(5, 7, 0.04, 0.01, dictionary);
board->draw( Size(600, 500), boardImage, 40, 1);
imwrite("../data/board.png", boardImage);

自定义board的生成

有时候为了更好地完成任务,需要自己对board进行定义,所以使用了自定义的方法生成一圈tag,
在生成自定义board的过程中,犯了很多傻傻的错误,总是提示

1
OpenCV Error: Assertion failed (sidePixels >= (markerSize + 2*borderBits)) in drawMarker

一直在苦恼时哪个地方的参数没写对吗?结果发现是建立四个点的时候,不是逆时针,因为 aruco::Board::create 要求是逆时针建立四个点,所以改过来就好了。其中可以更改的相关参数如:length marker的宽度, aruco::drawPlanarBoard(board, Size(3000, 3000), boardImage, 70, 1); 中70为边缘的宽度,下面就可以生成对应的board了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <opencv2/opencv.hpp>
#include <opencv2/aruco.hpp>
#include <vector>
#include <iostream>
using namespace std;
using namespace cv;
int main(){
//create_marker
Ptr<aruco::Dictionary> dictionary = aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
//marker length
double length = 0.065;
vector<vector<Point3f> > marker_corner_vec;
vector<int> ids_vec;
//marker left up corner coordinate
vector<double> corners_x = {0, 0.08, 0.16, 0.24, 0.32, 0.40, 0.48, 0, 0.08, 0.16, 0.24, 0.32, 0.40, 0.48, 0, 0, 0, 0, 0, 0.48, 0.48, 0.48, 0.48, 0.48};
vector<double> corners_y = {0, 0, 0, 0, 0, 0, 0, 0.48, 0.48, 0.48, 0.48, 0.48, 0.48, 0.48, 0.08, 0.16, 0.24, 0.32, 0.40, 0.08, 0.16, 0.24, 0.32, 0.40};
//CCW order is important
//here we order the four corners for:left up, left bottom, right bottom and right up
for(unsigned i = 0; i < corners_x.size(); ++i){
vector<Point3f> marker_corners(4, Point3f(0, 0, 0));
marker_corners[0].x = corners_x[i];
marker_corners[0].y = corners_y[i];
marker_corners[1].x = corners_x[i];
marker_corners[1].y = corners_y[i] + length;
marker_corners[2].x = corners_x[i] + length;
marker_corners[2].y = corners_y[i] + length;
marker_corners[3].x = corners_x[i] + length;
marker_corners[3].y = corners_y[i];
marker_corner_vec.push_back(marker_corners);
ids_vec.push_back(i + 1);
}
// create the board
Ptr<aruco::Board> board = aruco::Board::create(marker_corner_vec, dictionary, ids_vec);
Mat boardImage;
//translate the board to mat
aruco::drawPlanarBoard(board, Size(3000, 3000), boardImage, 70, 1);
//write the mat into image
imwrite("../data/board.png", boardImage);
// imshow("artag", boardImage);
waitKey(0);
}

生成了对应的board。