自动生成一个任意分辨率、任意尺寸的棋盘
如图是生成的一个分辨率为489* 643,格子尺寸为10×9的棋盘,像如下图的棋盘,有些地方喜欢称为9×8的棋盘,因为算的不是格子,而是角点。请看代码中33行的t1、t2对应如图标记的两行格子。因为代码中会在一个Mat中反复push_back(t1 or t2)。
好了,请看代码:
1 #include<opencv2/opencv.hpp> 2 using namespace cv; 3 4 #include <iostream> 5 using namespace std; 6 7 8 /***************************************************************************************************************************************************************************************************** 9 10 功能:生成一张棋盘图 11 12 输入:(rows, cols):棋盘图分辨率,(m, n):棋盘图有 m + 1 列格子, n + 1 行格子 13 14 输出:棋盘图 15 16 返回:同上 17 18 备注:棋盘上格子最好满足:一边为奇数、一边为偶数;直接返回一个Mat有点低效... 19 20 *****************************************************************************************************************************************************************************************************/ 21 Mat getChessBoard(const int& rows, const int& cols, const size_t& n, const size_t& m) 22 { 23 Mat backGround = Mat::ones(rows, cols, CV_8UC1) * 255; 24 25 // size of a cell 26 int r = rows / (int)(n + 1); // 格子高度 27 int c = cols / (int)(m + 1); // 格子宽度 28 29 // cell 30 Mat whiteCell = Mat::ones(r, c, CV_8UC1) * 255; 31 Mat blackCell = Mat::zeros(r, c, CV_8UC1); 32 33 Mat t1, t2; 34 t1 = blackCell.clone(); 35 t2 = whiteCell.clone(); 36 for (size_t i = 0; i < m; i++) 37 { 38 if (i % 2 == 1) 39 { 40 hconcat(t1, blackCell, t1); // 在 t1 右侧拼接一个 blackCell 41 hconcat(t2, whiteCell, t2); // 提示:从下面凭借用vconcat 42 } 43 if (i % 2 == 0) 44 { 45 hconcat(t1, whiteCell, t1); 46 hconcat(t2, blackCell, t2); 47 } 48 } 49 50 Mat view; 51 view = t1.clone(); 52 for (size_t i = 0; i < n; i++) 53 { 54 if (i % 2 == 1) 55 { 56 view.push_back(t1); 57 } 58 if (i % 2 == 0) 59 { 60 view.push_back(t2); 61 } 62 } 63 view.copyTo(backGround(Rect(0, 0, view.cols, view.rows))); 64 return backGround; 65 } 66 67 int main() 68 { 69 // 70 int rows = 643; 71 int cols = 489; 72 73 // num of cell 74 // 一边为奇数、一边为偶数 75 size_t n = 8; // n + 1 行格子 76 size_t m = 9; // m + 1 列格子 77 78 // 获取一个棋盘图 79 Mat chessBoard = getChessBoard(rows, cols, n, m); 80 81 Mat chessBoards[3]; 82 chessBoards[0] = chessBoard; 83 chessBoards[1] = chessBoard; 84 chessBoards[2] = chessBoard; 85 Mat chessBoardRGB; 86 merge(chessBoards, 3, chessBoardRGB); 87 88 89 vector<Point2f> imagPoints; 90 Size boardSize((int)m, (int)n); 91 92 bool found = findChessboardCorners(chessBoard, boardSize, imagPoints, CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_FAST_CHECK | CALIB_CB_NORMALIZE_IMAGE); 93 if (found) 94 { 95 cornerSubPix(chessBoard, imagPoints, Size(11, 11), Size(-1, -1), TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 30, 0.1)); 96 97 drawChessboardCorners(chessBoardRGB, boardSize, Mat(imagPoints), found); 98 } 99 100 namedWindow("...", WINDOW_NORMAL); 101 imshow("...", chessBoardRGB); 102 waitKey(0); 103 return -1; 104 }
CV&DL