自动生成一个任意分辨率、任意尺寸的棋盘

      如图是生成的一个分辨率为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 }

 

 

posted @ 2020-04-20 15:47  佚名12  阅读(41)  评论(0编辑  收藏  举报