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

这篇具有很好参考价值的文章主要介绍了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,人工智能,计算机视觉

OpenCV标定演示,及如何生成标定板图片,opencv,人工智能,计算机视觉

OpenCV标定演示,及如何生成标定板图片,opencv,人工智能,计算机视觉

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

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

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

本文结束。文章来源地址https://www.toymoban.com/news/detail-739427.html

到了这里,关于OpenCV标定演示,及如何生成标定板图片的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 图片如何resize及使用opencv实现图片resize

    example: 以下代码就可以将原图片转化为宽和长分别为300,300的图片。width和height可以自己任意指定,不论大小。 InputArray src :输入,原图像,即待改变大小的图像; OutputArray dst: 输出,改变后的图像。这个图像和原图像具有相同的内容,只是大小和原图像不一样而已; dsi

    2024年02月17日
    浏览(39)
  • 4 OpenCV实现多目三维重建(多张图片增量式生成稀疏点云)【附源码】

    本文是基于 OpenCV4.80 进行的,关于环境的配置可能之后会单独说,先提一嘴 vcpkg 真好用 从多张图片逐步生成稀疏点云,这个过程通常包括以下步骤: 初始重建: 初始两张图片的选择 十分重要 ,这是整个流程的基础,后续的增图都是在这两张图片的基础上进行的 对于输入图

    2024年02月06日
    浏览(45)
  • opencv如何给图片添加中文并更改字体

     opencv中自带的cv2.putText()函数不能在图像中绘制汉字,可以通过添加PIL模块来达到在图像中显示汉字 通过PIP命令来添加库 指令如下 下载模块之后就可以通过调用来在图片上显示中文了,示例代码如下  如果想更改中文显示字体的话,在电脑的字体库中找到你想要显示的的字

    2024年02月09日
    浏览(62)
  • python 手眼标定OpenCV手眼标定(calibrateHandeye())一

    以下代码来源 本篇博客通过该代码,附上记录的公式与查找连接,方面以后调用能弄懂各个参数的意思 本篇看完看第二篇代码踩坑部分python 手眼标定OpenCV手眼标定(calibrateHandeye())二 相机标定原理视频介绍 calibrateHandeye() 参数描述如下:R_gripper2base,t_gripper2base是机械臂抓手

    2024年02月15日
    浏览(45)
  • python 手眼标定OpenCV手眼标定(calibrateHandeye())二

    这一章我们来根据上一章的分析,为手眼标定函数calibrateHandEye 准备他那些麻烦的参数 更详细的参数参考链接 即R_all_end_to_base_1,T_all_end_to_base_1, 我们可用通过输入的机械臂提供的6组参数得到,3个位姿与3个欧拉角 示例代码 这里是关系是 通过 cv2.findChessboardCorners 角点查找函数

    2024年02月01日
    浏览(36)
  • 用OpenCV进行相机标定(张正友标定,有代码)

    理论部分可以参考其他博客或者视觉slam十四讲 相机标定主要是为了获得相机的内参矩阵K和畸变参数 内参矩阵K 畸变系数:径向畸变(k1,k2,k3), 切向畸变(p1,p2) 径向畸变公式 切向畸变公式 张正友标定方法能够提供一个比较好的初始解,用于后序的最优化. 这里用棋盘格进行标定,如

    2024年02月07日
    浏览(42)
  • [C++] opencv中如何生成随机颜色?

    我们可以通过C++来生成OpenCV绘图使用的随机颜色,代码如下: 这个代码将生成一个大小为100x100像素的随机颜色图像。它首先使用当前时间作为随机数种子来初始化随机数生成器。然后,它使用 rand() 函数生成三个介于0到255之间的随机整数,分别表示红色、绿色和蓝色通道的

    2024年01月19日
    浏览(37)
  • opencv相机标定

      当你把摄像机放在一个特定的位置,在它的后面放一个目标图像,或者是把摄像机放到某个物体上,摄像机周围的物体是什么形状,你需要知道这些信息。 当你在计算机上处理图像时,会使用以下三个参数: 1.像素坐标(pixel):像素坐标是相机中每个点的世界坐标(x,y

    2024年02月16日
    浏览(36)
  • OpenCV实战(23)——相机标定

    我们已经了解了相机如何通过在 2D 传感器平面上投射光线来拍摄 3D 场景,生成的图像准确地表示了在捕获图像的瞬间从特定视点观察场景。然而,图像形成过程消除了与其所表示场景元素的深度有关的所有信息。为了恢复场景的 3D 结构和摄像机的 3D 姿态,我们需要对相机参

    2024年02月08日
    浏览(55)
  • OpenCV中的相机标定

          之前在https://blog.csdn.net/fengbingchun/article/details/130039337 中介绍了相机的内参和外参,这里通过OpenCV中的接口实现对内参和外参的求解。       估计相机参数的过程称为相机标定(camera calibration)。相机标定是使用已知的真实世界模式(例如棋盘)来估计相机镜头和传感器的外

    2023年04月19日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包