当前位置: 首页 > news >正文

OpenCV标定演示,及如何生成标定板图片

标定的程序在官方的源码里有,

opencv-4.5.5\samples\cpp\tutorial_code\calib3d\camera_calibration

很多小白不知道怎么跑起来,这个也怪OpenCV官方,工作没做完善,其实的default.xml是要自己手动改的,输入的图片也要自己去拍摄,还有那个VID5.xml也要改成可以直接找到图片的路径;

我这里拍了5张图,故意做了鱼眼效果后,用于标定校正。程序已经改好了,直接visual studio就可以跑了,到这里去下载吧,

https://github.com/SpaceView/OpenCV455_cameraCalibrationDemo

关于标定板:

OpenCV官方曾经提供的标定板是CHESSBOARD 9x6和7x7的,实际应用根据场景的需要,可能需要不同的标定板。

标定程序实际支持三种标定板,包括chessboard,grid circle, asymmetric grid circle格子,这里我们手动生成标定板(包括这里提到的三种标定板)的图片, 程序如下,

class CalibTools {public:cv::Mat GenerateChessboard(int xBlockNum, int yBlockNum, int BLOCKWIDTH, std::string saveFileName) {//const int BLOCKWIDTH = 150;//const int xBlockNum = 7;//const int YBlockNum = 7;cv::Size sz = { xBlockNum * BLOCKWIDTH, yBlockNum * BLOCKWIDTH };cv::Mat  mat(sz, CV_8UC3);for (int r = 0; r < yBlockNum; r++) {for (int c = 0; c < xBlockNum; c++) {int IX = c * BLOCKWIDTH, IY = r * BLOCKWIDTH;int EX = IX + BLOCKWIDTH, EY = IY + BLOCKWIDTH;cv::Vec3b value;if (0 == (c + r) % 2) {value = { 0xFF,0xFF, 0xFF };}else {value = 0x000000;}for (int y = IY; y < EY; y++) {cv::Vec3b* p = mat.ptr<cv::Vec3b>(y);for (int x = IX; x < EX; x++) {p[x] = value;}}}}if (!saveFileName.empty()) {saveFileName += ".png";cv::imwrite(saveFileName, mat);}return mat;}/**     *   *   *   *   *   *   *   --> xDotNum1  = 7   _|_ 1*     *   *   *   *   *   *   *                       _|_ 2*     *   *   *   *   *   *   *                       _|_ 3*     *   *   *   *   *   *   *                       _|_ 4*     *   *   *   *   *   *   *                       _|_ 5*     *   *   *   *   *   *   *                       _|_ 6*     *   *   *   *   *   *   *                       _|_ 7 --> In total yDotNum = 7*/cv::Mat GenerateGridCircle(int xDotNum, int yDotNum, int dotRadius, int BLOCKWIDTH, std::string saveFileName) {cv::Size sz = { (xDotNum +1) * BLOCKWIDTH, (yDotNum+1) * BLOCKWIDTH };cv::Mat  mat(sz, CV_8UC3);mat.setTo(cv::Scalar(255,255,255));for (int r = 1; r <= yDotNum; r++) {int y = r * BLOCKWIDTH;for (int c = 1; c <= xDotNum; c++) {int x = c * BLOCKWIDTH;cv::circle(mat, cv::Point(x, y), dotRadius, cv::Scalar(0, 0, 0), cv::FILLED);}}if (!saveFileName.empty()) {saveFileName += ".png";cv::imwrite(saveFileName, mat);}return mat;}/**     *   *   *   *   *   *   *   --> xDotNum1  = 7    |*       *   *   *   *   *   *     --> xDotNum2  = 6   _|_  1, --> 2 rows make 1 unit in  yDotNum*     *   *   *   *   *   *   *                        |*       *   *   *   *   *   *                         _|_  2*     *   *   *   *   *   *   *                        |*       *   *   *   *   *   *                         _|_  3*     *   *   *   *   *   *   *                        |*       *   *   *   *   *   *                         _|_  4, --> In total yDotNum = 4* *     *<--->*    ---> DOTDIST*        **     *     **/cv::Mat GenerateAsymmetricGridCircle(int xDotNum1, int xDotNum2, int yDotNum, int dotRadius, int DOTDIST, std::string saveFileName) {int totXDotNum = xDotNum1 + xDotNum2 + 2;int totYDotNum = 2 * yDotNum + 2;int DIST = DOTDIST / 2;int HDIST = DIST / 2;cv::Size sz = { totXDotNum * DIST, totYDotNum * DIST };cv::Mat  mat(sz, CV_8UC3);mat.setTo(cv::Scalar(255, 255, 255));for (int r = 1; r < totYDotNum-1; r++) {for (int c = 1; c < totXDotNum-1; c++) {int IX = c * DIST, IY = r * DIST;int CX = IX + HDIST, CY = IY + HDIST;if (0 == (c + r) % 2) {cv::circle(mat, cv::Point(CX, CY), dotRadius, cv::Scalar(0, 0, 0), cv::FILLED);}}}if (!saveFileName.empty()) {saveFileName += ".png";cv::imwrite(saveFileName, mat);}return mat;}
};

调用方式举例如下,

CalibTools ct;
ct.GenerateChessboard(7, 7, 100, "GenerateChessboard");
ct.GenerateGridCircle(8, 8, 20, 80, "GeneratedGridCircles");
ct.GenerateAsymmetricGridCircle(8, 7, 6, 20, 100, "GenerateAsymmetricGridCircle");

这样,就可以生成下列形状的标定板,

然后打印出来就可以做标定板了。

关于非对称的圆形标定板,可以参考下面的贴子,

OpenCv相机标定——圆形标定板标定_opencv圆形标定板-CSDN博客

本文结束。

http://www.lryc.cn/news/215239.html

相关文章:

  • python venv 虚拟环境使用
  • useCallback和useMemo的区别?
  • Angular组件生命周期详解
  • Redsync 多 Redis 实例使用 demo
  • Docker(1)——安装Docker以及配置阿里云镜像加速
  • MCU HardFault_Handler调试方法
  • 【深度学习】AUTOMATIC1111 / stable-diffusion-webui docker
  • [Hive] 查询结果保存
  • Es中出现unassigned shards问题解决
  • RT-DERT:在实时目标检测上,DETRs打败了yolo
  • uniapp/H5富文本复制文本功能
  • 通付盾Web3专题 | 智能账户:数字时代基础单元
  • java网上阅读网站系统eclipse定制开发mysql数据库BS模式java编程jdbc
  • 人工智能基础_机器学习007_高斯分布_概率计算_最小二乘法推导_得出损失函数---人工智能工作笔记0047
  • 开源播放器GSYVideoPlayer的简单介绍及播放rtsp流的优化
  • 安卓手机数据恢复工具 DiskDigger Pro 中文版-适用于已获得 root 权限的设备!可以从您的存储卡或内存恢复数据
  • Python 生成Android不同尺寸的图标
  • PHP使用GuzzleHttp进行HTTP请求
  • pytorch笔记:allclose,isclose,eq,equal
  • YoloV8修改检测框为中心点
  • 文言一心中将C语言归类为低级语言,这对么?
  • [补题记录] Codeforces Round 906 (Div. 2)(A~D)
  • Kubernetes yaml文件
  • Linux——切换CUDA版本
  • 利用云计算和微服务架构开发可扩展的同城外卖APP
  • 数据结构详细笔记——二叉树
  • react实现列表增删改查的小demo(class组件版)
  • 运行批处理文件,Windows 10至少提供了三种方法,有的可以设置定时运行
  • C++ detach线程的归属权和控制权交给runtime library的原因
  • Android应用集成RabbitMQ消息处理指南