引入
使用c++学习
边读代码边用ai自学
calibration.cpp
根据定义类逐个了解
注:一开始看错了,以为是保存视频的cpp,结果是标定畸变的cpp

12*9的棋盘格,12行9列 (代码中是Size sizeBoard = Size(11, 8); )(哪里理解有误?)
std::string
std::string 是标准C++库中的一个类,用于表示和操作字符串。string imagesFolder = "../res/calibration/temp/"; // 打开标定图像
举例:读取图象文件
1 | # |
Size
Size 是OpenCV中用于表示尺寸的结构体,包含 width 和 height 两个成员。
在相机标定过程中,Size 被用来表示标定板的角点数(如 Size sizeBoard = Size(11, 8); 表示标定板有11行8列角点)和标定板上每个棋盘格的边长(如 Size sizeSquare = Size(20, 20); 表示每个棋盘格的边长为20x20毫米)。
Size 也被用来存储图像的尺寸,如代码中的 Size sizeImage;。在读取图像后,可以通过 imageInput.cols 和 imageInput.rows 获取图像的宽度和高度,并赋值给 sizeImage 的 width 和 height 成员。
Mat
代表了一个n维的密集数值单通道或多通道数组,可以用来存储图像、矩阵、直方图
创建Mat
构造函数:
Mat image = Mat(rows, cols, type, Scalar(value));
图像文件读取:Mat image = imread(filePath);
复制现有Mat对象:Mat imageCopy = image.clone();或Mat imageCopy = image;(注意:后者是浅拷贝,仅复制头部)
1 | Mat cameraMatrix = Mat(3, 3, CV_32FC1, Scalar::all(0)); //创建一个3x3的浮点型矩阵,用于存储摄像机的内参矩阵。 |
vector(c++内容)
一种序列容器,它允许你在运行时动态地插入和删除元素。
vector 是基于数组的数据结构,但它可以自动管理内存,这意味着你不需要手动分配和释放内存。
1 | int main() { |
1 | //vector<String> imagesPath; 这行代码定义了一个名为 imagesPath 的变量,该变量是一个 vector 容器,用于存储 String 类型的元素。 |

Display
赛鼠自定义类
1 | /** |
1 | Display display(2); |
glob
glob 函数用于查找符合特定模式的文件路径。
1 | int glob(const string& pattern, vector<String>& result, bool recursive = false); |
pattern:要搜索的文件模式。这可以是一个包含通配符(如 * 和 ?)的字符串,用于匹配多个文件。
result:一个 vector
recursive:一个布尔值,指示搜索是否应递归地进入子文件夹。如果设置为 true,则 glob 将搜索指定文件夹及其所有子文件夹中的文件;如果设置为 false,则仅搜索指定文件夹中的文件。
1 | glob(imagesFolder, imagesPath, false); // OpenCV提取文件夹中的所有文件 |
struct stat
C++编程中,struct stat 是一个结构体,用于存储文件的状态信息。
这个结构体定义在POSIX标准中,并且在许多Unix-like系统(包括Linux和macOS)以及Windows的Cygwin环境中都是可用的。它包含了关于文件的各种信息,如文件大小、修改时间、权限等。
1 | struct stat buffer; |
struct stat 是一个结构体,包含了文件或目录的各种状态信息,如文件大小、修改时间、权限等。这个结构体的具体字段可能因操作系统而异,但通常包含以下一些基本字段:
st_size:文件大小(以字节为单位)。
st_mode:文件类型和权限。
st_mtime:最后修改时间。
st_ctime:最后状态改变时间。
st_uid:文件所有者的用户ID。
st_gid:文件所有者的组ID。
stat函数
1 | int stat(const char *pathname, struct stat *buf); |
pathname:这是一个指向以null结尾的字符串的指针,表示要检查的文件或目录的路径。
buf:这是一个指向 struct stat 类型的指针,函数将把获取到的文件或目录的状态信息存储在这个结构体中。
img_path.c_str()
C++中,std::string 类型是标准库提供的一个用于表示和操作字符串的类。然而,C语言风格的函数(如POSIX系统调用和某些C库函数)通常要求字符串参数是C风格的字符串,即以null结尾的字符数组(char* 类型)。
std::string 类提供了一个成员函数 c_str(),该函数返回一个指向C风格字符串的指针,该字符串与 std::string 对象的内容相同。这样,您就可以将 std::string 对象传递给需要C风格字符串参数的函数了。
1 | string img_path = "../res/calibration/corners/" + filename; |
Point2f
在OpenCV库中,Point2f 是一个用于表示二维点的类,其中“2”表示点的维度(即x和y坐标),“f”表示坐标值的数据类型为浮点数(float)。Point2f 类定义在 opencv2/core.hpp 头文件中,是OpenCV核心模块的一部分。
imread
在OpenCV库中,imread 函数用于从指定文件路径读取图像。
1 | Mat imread(const std::string& filename, int flags = IMREAD_COLOR); |
filename:这是一个字符串参数,表示要读取的图像文件的路径。
flags:这是一个可选的整数参数,用于指定读取图像的方式。默认情况下,它的值为 IMREAD_COLOR(即1),表示以彩色模式读取图像。如果设置为 IMREAD_GRAYSCALE(即0),则以灰度模式读取图像;如果设置为 IMREAD_UNCHANGED(即-1),则包括图像的alpha通道(如果存在)。可以不填写
imread 函数返回一个 Mat 对象,该对象包含了读取的图像数据。如果图像文件成功读取,Mat 对象将包含图像的有效数据;如果读取失败(例如,文件不存在或路径错误),Mat 对象将是一个空矩阵。
vector<vector>和vector
vector<vector
类型:这是一个二维向量,其中每个元素都是一个 vector
用途:用于存储多张图像中检测到的所有角点坐标。外层的 vector 存储每张图像的角点信息,内层的 vector 存储单张图像中所有角点的坐标。
结构:可以想象成一个表格,其中每一行代表一张图像的角点信息,每一列代表一个角点的坐标(x和y)。
vector
类型:这是一个一维向量,其中每个元素都是一个 Point2f 类型的对象。
用途:用于存储单张图像中检测到的角点坐标。
结构:可以想象成一个一维数组,其中每个元素代表一个角点的坐标(x和y)。
在代码中,pointsCorners 被初始化并用于存储所有图像的角点信息。在循环处理每张图像时,会创建一个临时的 pointCorners 向量来存储当前图像的角点坐标。如果当前图像中的角点数量符合要求(即角点数量等于标定板上的角点总数),则将这些角点坐标添加到 pointsCorners 中。
findChessboardCorners
黑盒
findChessboardCorners 函数是OpenCV库中用于检测图像中棋盘格角点的一个重要函数。该函数通常用于相机标定过程中,以提取标定板(棋盘格)的角点信息。
1 | bool findChessboardCorners(InputArray image, Size patternSize, OutputArray corners, |
image:输入图像,应为8位灰度图像或彩色图像。
patternSize:棋盘格的内角点数量,包括行数和列数。例如,一个8x8的棋盘格应使用Size(8,8)。
corners:检测到的角点输出,通常是一个std::vectorcv::Point2f类型的对象。
flags:可选参数,用于指定检测角点时的附加选项。默认为CALIB_CB_ADAPTIVE_THRESH和CALIB_CB_NORMALIZE_IMAGE的组合,这有助于在光照不均的情况下更好地检测角点。
函数返回一个布尔值,指示是否成功检测到足够数量的角点。如果返回true,则corners向量中将包含检测到的角点坐标;如果返回false,则表示检测失败,可能是因为图像中不存在棋盘格或角点数量不足。
1 | Size sizeBoard = Size(11, 8); // 标定板的角点数(行,列) |
cvtColor
黑盒
cvtColor 函数是OpenCV库中用于颜色空间转换的一个常用函数。该函数能够将图像从一个颜色空间转换到另一个颜色空间,比如从RGB颜色空间转换到灰度颜色空间。
1 | Mat imageGray; |
1 | void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0 ); |
find4QuadCornerSubpix
黑盒
find4QuadCornerSubpix 是 OpenCV 库中提供的一个函数,
1 | void find4QuadCornerSubpix(InputArray image, InputOutputArray corners, |
1 | find4QuadCornerSubpix(imageGray, pointCorners, Size(5, 5), Size(-1,-1), |
cv::namedWindow
黑盒
在OpenCV库中,cv::namedWindow 函数用于创建一个窗口,该窗口可以用于显示图像或视频流。
1 | // 在提供的代码片段中,cv::namedWindow 函数被用来创建一个名为 "Corners" 的窗口,并且允许用户调整窗口大小: |
1 | void namedWindow(const std::string& winname, int flags = WINDOW_AUTOSIZE); |
system
system 函数被用来执行操作系统命令,
1 | int system(const char *command); |
1 | string command = "mkdir -p ../res/calibration/corners/"; |
imwrite
在OpenCV库中,imwrite 函数用于将图像保存到指定的文件路径
1 | bool imwrite(const std::string& filename, InputArray img, |
1 | imwrite(img_path, imageInput); |
imshow
在OpenCV库中,imshow 函数用于在窗口中显示图像
1 | void imshow(const std::string& winname, InputArray mat); |
1 | imshow("Corners", imageInput); // 在名为 "Corners" 的窗口中显示图像 |
waitKey
waitKey 函数通常与 imshow 函数一起使用,用于控制图像显示窗口的持续时间以及处理键盘事件。
1 | int waitKey(int delay = 0); |
1 | waitKey(500); // 停顿500ms |
calibrateCamera
黑盒
calibrateCamera 是 OpenCV 中用于相机标定的核心函数,它根据已知的三维世界坐标和对应的二维图像坐标来计算相机的内参矩阵、畸变系数、旋转向量和平移向量。在提供的代码片段中,calibrateCamera 函数被用来开始标定过程。
1 | double calibrateCamera(InputArrayOfArrays objectPoints, |
1 | calibrateCamera(pointsObject, pointsCorners, sizeImage, cameraMatrix, distCoeffs, rvecsMat, tvecsMat, 0); |
fout
在 C++ 编程中,cout 和 fout 是两种不同的输出流,它们用于将信息输出到不同的目的地。
- cout 是标准输出流(std::ostream 的一个实例),通常用于将信息输出到控制台或终端。
- fout
1 | // 类型:fout 是一个文件输出流(std::ofstream 的一个实例),用于将信息写入到文件中。 |
projectPoints
projectPoints 是 OpenCV 库中用于相机标定的一个重要函数,它根据相机的内参矩阵、畸变系数、旋转向量和平移向量,将三维空间中的点投影到二维图像平面上。
1 | void projectPoints(InputArray objectPoints, |
1 | vector<Point3f> tempPointSet = pointsObject[i]; |
collection.cpp
遥控手柄宏
1 | class Joystick |
private(私有部分):
- JS_EVENT_BUTTON 按钮类型
- JS_EVENT_AXIS 摇杆类型
- JS_EVENT_INIT 设备初始状态
- EventJoy结构体的joy 游戏手柄事件结构体(触发时间time,操控值value,操控类型type,操控编号number)
- idFileJoy:文件描述符
- threadJoy:子线程指针 (详情如下)
1 | std::unique_ptr<std::thread> threadJoy; // 遥控手柄子线程 |
public(公有部分):
- bool sampleMore = false; // 连续图像采样使能
- bool sampleOnce = false; // 单次图像采样使能
- float speed = 0; // 车速:m/s
- float servo = PWMSERVOMID; // 打舵:PWM
- bool ahead = true; // 车辆速度方向:默认向前
- bool uartSend = false; // 串口发送使能
- bool buzzer = false; // 提示音效
- 同名构造函数joystick()—>让文件描述符idFileJoy指向手柄事件(初始化)
- 关闭线程threadJoy
- 开启线程threadJoy
1 | void start(void) |
- 遥控线程任务threadJoystick
lambda表达式:
Lambda 表达式是 C++11 引入的一种简洁的定义匿名函数对象的方式。它们可以捕获外部变量,并用于需要函数对象的场合,如算法的标准库函数或作为线程函数。
1 | void start(void) |
主函数部分
shared_ptr
shared_ptr
语句用于创建一个指向 Uart 类实例的智能指针 uart,并通过构造函数传递设备文件路径 /dev/ttyUSB0 来初始化串口驱动。
VideoCapture
1 | VideoCapture capture("/dev/video0"); |
putText
putText 是 OpenCV 库中的一个函数,用于在图像上指定位置添加文本。
1 | putText(frame, to_string(index), Point(10, 30), cv::FONT_HERSHEY_TRIPLEX, 1, cv::Scalar(0, 0, 254), 1, CV_AA); // 显示图片保存序号 |
img2video.cpp
- 帧率(frame_fps):20帧/s
- 帧宽(frame_width):每一帧的宽度,这里设置为320像素。
- 帧高(frame_height):每一帧的高度,这里设置为240像素。
VideoWriter
在OpenCV中,VideoWriter类用于创建视频文件并向其中写入帧。它是处理视频输出的核心类。
1 | writer = VideoWriter("../res/samples/sample.mp4", CV_FOURCC('P', 'I', 'M', '1'), |
writer << img
1 | writer << img; |