
/*
* stereo_match.cpp
* calibration
*
* 创建者 Victor Eruhimov,日期为 2010年1月18日。
* 版权所有 2010 Argus Corp.
*
*/
#include "opencv2/calib3d/calib3d.hpp" // 导入OpenCV相机标定和三维重建相关的头文件
#include "opencv2/imgproc.hpp" // 导入OpenCV图像处理相关的头文件
#include "opencv2/imgcodecs.hpp" // 导入OpenCV图像编解码相关的头文件
#include "opencv2/highgui.hpp" // 导入OpenCV高层GUI(图形界面)相关的头文件
#include "opencv2/core/utility.hpp" // 导入OpenCV核心工具(utility)模块的头文件
#include <stdio.h> // 导入C标准输入输出头文件
#include <sstream> // 导入C++字符串流处理头文件
using namespace cv; // 使用OpenCV的命名空间
// 声明了print_help函数,用于显示帮助信息
static void print_help(char** argv)
{
// 打印使用demo时的帮助信息
printf("\nDemo stereo matching converting L and R images into disparity and point clouds\n");
// 打印程序使用方式的说明
printf("\nUsage: %s <left_image> <right_image> [--algorithm=bm|sgbm|hh|hh4|sgbm3way] [--blocksize=<block_size>]\n"
"[--max-disparity=<max_disparity>] [--scale=scale_factor>] [-i=<intrinsic_filename>] [-e=<extrinsic_filename>]\n"
"[--no-display] [--color] [-o=<disparity_image>] [-p=<point_cloud_file>]\n", argv[0]);
}
// 声明了saveXYZ函数,用于将三维点云数据保存到文件
static void saveXYZ(const char* filename, const Mat& mat)
{
// 设置三维点深度的最大值
const double max_z = 1.0e4;
// 以文本写入方式打开文件
FILE* fp = fopen(filename, "wt");
// 遍历图像的每个像素点
for(int y = 0; y < mat.rows; y++)
{
for(int x = 0; x < mat.cols; x++)
{
// 读取每个像素点的三维坐标
Vec3f point = mat.at<Vec3f>(y, x);
// 如果该点的Z坐标无效,则忽略此点
if(fabs(point[2] - max_z) < FLT_EPSILON || fabs(point[2]) > max_z) continue;
// 将有效的三维坐标写入到文件中
fprintf(fp, "%f %f %f\n", point[0], point[1], point[2]);
}
}
// 关闭文件
fclose(fp);
}
int main(int argc, char** argv)
{
// 定义了一系列的字符串变量用来存储命令行参数
std::string img1_filename = "";
std::string img2_filename = "";
std::string intrinsic_filename = "";
std::string extrinsic_filename = "";
std::string disparity_filename = "";
std::string point_cloud_filename = "";
// 定义了枚举类型,列出了所有双目算法
enum { STEREO_BM=0, STEREO_SGBM=1, STEREO_HH=2, STEREO_VAR=3, STEREO_3WAY=4, STEREO_HH4=5 };
int alg = STEREO_SGBM; // 默认使用STEREO_SGBM算法
int SADWindowSize, numberOfDisparities; // 定义了SAD窗口大小和视差的数量
bool no_display; // 定义了是否显示结果的标志位
bool color_display; // 定义了是否彩色显示视差图的标志位
float scale; // 定义了缩放因子
// 创建两种双目匹配算法实例对象:StereoBM和StereoSGBM
Ptr<StereoBM> bm = StereoBM::create(16,9);
Ptr<StereoSGBM> sgbm = StereoSGBM::create(0,16,3);
// 使用命令行解析器解析参数
cv::CommandLineParser parser(argc, argv,
"{@arg1||}{@arg2||}{help h||}{algorithm||}{max-disparity|0|}{blocksize|0|}{no-display||}{color||}{scale|1|}{i||}{e||}{o||}{p||}");
// 如果用户请求帮助,则调用print_help函数并退出
if(parser.has("help"))
{
print_help(argv);
return 0;
}
// 获取命令行中指定的左右图像文件名
img1_filename = samples::findFile(p