c++学习【3】棋盘格标定

在C++中,vector是一个容器类,用于存储动态数组。

vector<Point2f>表示一个Point2f类型的动态数组,可以理解为一个一维的数组。

而vector<vector<Point2f>>表示一个二维的动态数组,其中每个元素都是一个Point2f类型的动态数组。

为什么要这样嵌套写呢?这是因为在计算机视觉中,我们经常需要处理的是二维的数据,例如图像中的像素、特征点、轮廓点等。因此,我们需要使用一个二维的动态数组来存储这些数据。如果直接使用一个一维的动态数组,可能会比较难以处理这些二维数据。因此,使用vector<vector<Point2f>>这种嵌套写法,可以方便地存储和访问二维数据,同时也具有很大的灵活性和可扩展性。

Point3f是OpenCV库中定义的一个结构体类型,表示一个三维坐标点。在C++中,6.0f表示一个float类型的浮点数,其值为6.0。在C++中,float类型的浮点数通常使用字母"f"来表示,以便于区分double类型的浮点数。如果不加"f",则默认为double类型的浮点数。

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
    // 定义和初始化一个Point3f类型的变量
    Point3f pt1(1.0f, 2.0f, 3.0f);
    // 或者使用默认构造函数来初始化
    Point3f pt2;

    // 访问Point3f变量的成员变量x、y、z
    float x = pt1.x;
    float y = pt1.y;
    float z = pt1.z;

    // 修改Point3f变量的成员变量
    pt2.x = 4.0f;
    pt2.y = 5.0f;
    pt2.z = 6.0f;
    
    cout << pt1 << endl;

    return 0;
}

遍历棋盘格角点坐标:OpenCV 库中使用的是标准库中的容器类 std::vectorcv::Point3f 是 OpenCV 库中定义的一个结构体类型,表示一个三维坐标点,包含三个 float 类型的成员变量,分别表示 x、y、z 三个坐标轴上的坐标值。在使用 std::vector 容器时,可以将 cv::Point3f 类型的对象作为元素添加到容器中,实现对一组三维坐标点的存储和管理。例如,可以定义一个 std::vector<cv::Point3f> 类型的变量,用于存储多个三维坐标点。

int main() {
    // 定义棋盘格大小和个数
    Size boardSize(8, 8);
    int boardNum = 10;

    // 定义棋盘格角点坐标
    vector<vector<Point3f>> objPoints;
    /*定义了一个二维向量的变量objPoints,其中每个元素都是一个三维点(Point3f)的向量(vector)。*/
    /*其中objPoints中的每个元素都是一个由相机观察到的三维物体的点云,可以用于重建三维模型或者计算相机的内外参数等。*/

    // 生成棋盘格角点坐标
    vector<Point3f> obj;
    for (int i = 0; i < boardSize.height; i++)
    {
        for (int j = 0; j < boardSize.width; j++)
        {
            obj.push_back(Point3f(j, i, 0));
        }
    }
    for (int i = 0; i < boardNum; i++)
    {
        objPoints.push_b
### C++ 棋盘格标定法实现代码示例 以下是基于 OpenCV 的 C++ 实现棋盘格标定法的完整代码示例。该代码通过检测图像中的棋盘格角点来完成相机标定。 #### 准备工作 为了运行此程序,需准备一组包含棋盘格图案的照片,并确保这些照片是从不同角度拍摄的。此外,还需要知道棋盘格内部角点的数量(即行列数)。以下是一个完整的代码示例: ```cpp #include <opencv2/opencv.hpp> #include <iostream> #include <vector> using namespace cv; using namespace std; int main() { // 定义棋盘格尺寸 (宽度, 高度),表示内部角点数量 Size boardSize(9, 6); // 存储世界坐标系下的三维点和图像坐标系下的二维点 vector<vector<Point3f>> objectPoints; vector<vector<Point2f>> imagePoints; // 创建世界坐标系下标准棋盘格角点的位置 vector<Point3f> obj; for(int i = 0; i < boardSize.height; ++i){ for(int j = 0; j < boardSize.width; ++j){ obj.push_back(Point3f(j,i,0)); } } // 加载图片并查找角点 vector<string> images = {"image1.jpg", "image2.jpg", "image3.jpg"}; // 替换为实际文件名列表 bool found; Mat img, gray; for(size_t i = 0; i < images.size(); ++i){ img = imread(images[i], IMREAD_GRAYSCALE); if(img.empty()){ cout << "无法加载图像:" << images[i] << endl; continue; } found = findChessboardCorners(img, boardSize, noArray(), CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_NORMALIZE_IMAGE | CALIB_CB_FAST_CHECK); if(found){ cornerSubPix(img, corners, Size(11,11), Size(-1,-1), TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 30, 0.1)); imagePoints.push_back(corners); objectPoints.push_back(obj); } else { cout << "未找到角点:" << images[i] << endl; } } // 执行相机标定 Mat cameraMatrix, distCoeffs, rvecs, tvecs; double rms = calibrateCamera(objectPoints, imagePoints, img.size(), cameraMatrix, distCoeffs, rvecs, tvecs); // 输出结果 cout << "RMS error: " << rms << endl; cout << "camera matrix:\n" << cameraMatrix << endl; cout << "distortion coefficients:\n" << distCoeffs << endl; return 0; } ``` 上述代码实现了以下几个功能: - **定义棋盘格大小**:指定棋盘格内部角点的数量 `boardSize`[^1]。 - **创建对象点数组**:构建了一个理想化的三维空间点集合,用于描述棋盘格上每个角点的世界坐标位置。 - **读取图像数据**:循环处理多张含有棋盘格的图像,提取其中的角点信息[^2]。 - **亚像素精度优化**:利用 `cornerSubPix()` 提高角点定位的精确度。 - **执行标定过程**:调用 `calibrateCamera()` 计算相机矩阵、畸变系数以及每幅图对应的旋转和平移向量。 #### 注意事项 - 图像分辨率应一致;如果输入图像具有不同的分辨率,则需要调整至相同大小后再进行标定操作。 - 使用高质量的棋盘格模板可以提高标定准确性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值