棋盘格应用非常广泛,可以用在需要标定的任何场景,而且有着不俗的精度。但是鉴于有些人对matlab、opencv不是很熟悉,因此制作棋盘格往往会耗费新手很多时间。本文就是帮助新手制作棋盘格的教程,可以直接在下面链接下载该程序(包含exe和源码):
https://download.csdn.net/download/u012283902/10854231
(注意:exe运行需要安装vs2017的运行库)
1. 编程环境:
QT5.11.2+VS2017+OpenCV4.0
2. 界面设计,如图所示
3. 主要代码:
(1)create_checkboard.h
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_create_checkboard.h"
class create_checkboard : public QMainWindow
{
Q_OBJECT
public:
create_checkboard(QWidget *parent = Q_NULLPTR);
private slots:
void setPathBtn();
void generateBtn();
private:
Ui::create_checkboardClass ui;
QString directory;
};
(2)create_checkboard.cpp
#pragma execution_character_set("utf-8")
#include "create_checkboard.h"
#include <QFileDialog>
#include <QMessageBox>
#include <opencv2/opencv.hpp>
create_checkboard::create_checkboard(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
QDir dir;
directory = dir.currentPath();
ui.pathLabel->setText(directory);
// 连接信号槽
connect(ui.setPathBtn, SIGNAL(clicked()), this, SLOT(setPathBtn()));
connect(ui.generateBtn, SIGNAL(clicked()), this, SLOT(generateBtn()));
connect(ui.quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
}
void create_checkboard::setPathBtn()
{
QFileDialog::Options options;
options |= QFileDialog::DontResolveSymlinks | QFileDialog::ShowDirsOnly;
QString dir = QFileDialog::getExistingDirectory(this,
tr("获得保存图像的路径"),
"./",
options);
if (!dir.isEmpty())
{
directory = dir;
ui.pathLabel->setText(directory);
}
}
void create_checkboard::generateBtn()
{
if (directory.isEmpty())
{
// 需要设置保存路径
QMessageBox::question(NULL, "注意", "请设置保存路径", QMessageBox::Yes, QMessageBox::Yes);
return;
}
int width = ui.widthSpin->value();
int height = ui.heightSpin->value();
int pixSize = ui.pixSizeSpin->value();
if (width < 2 || height < 2 || pixSize == 0)
{
QMessageBox::question(NULL, "注意", "请重新设置参数", QMessageBox::Yes, QMessageBox::Yes);
return;
}
// 图像大小,并初始化图片大小
int imageWidth = (width + 1)*pixSize;
int imageHeight = (height + 1)*pixSize;
cv::Mat image(cv::Size(imageWidth, imageHeight), CV_8UC1);
int grayRowValue = 0;
int grayColValue = 0;
// 左上角为黑色棋盘格,相邻为白色,黑白间隔排列,以此类推
for (int i = 0; i < height +1; i++)
{
for (int j = 0; j < width +1; j++)
{
for (int singleBoardHeight = 0; singleBoardHeight < pixSize; singleBoardHeight++)
{
for (int singleBoardWidth = 0; singleBoardWidth < pixSize; singleBoardWidth++)
{
int w = i * pixSize + singleBoardWidth;
int h = j * pixSize + singleBoardHeight;
image.at<uchar>(w,h) = grayRowValue;
}
}
grayRowValue == 0 ? grayRowValue = 255 : grayRowValue = 0;
}
grayColValue == 0 ? grayColValue = 255 : grayColValue = 0;
grayRowValue = grayColValue;
}
// 生成保存的名称
QString fileName = directory+"/"+QString::number(width) + "-" + QString::number(height) + "-" + QString::number(pixSize)+".jpg";
std::string std_filename = (const char *)fileName.toLocal8Bit();
cv::imwrite(std_filename,image);
QMessageBox::about(NULL, "提醒", fileName+" 保存完成!");
}
3. 运行结果(以4*6,100像素为例)