
#include <iostream> // 引入输入输出流库
#include <fstream> // 引入文件流库,用于文件输入输出
#include <string> // 引入字符串库
#include "opencv2/opencv_modules.hpp" // 引入OpenCV模块
#include <opencv2/core/utility.hpp> // 引入OpenCV核心和辅助功能
#include "opencv2/imgcodecs.hpp" // 引入图像编解码模块
#include "opencv2/highgui.hpp" // 引入高级GUI模块,用于展示图片等
#include "opencv2/stitching/detail/autocalib.hpp" // 引入图像缝合细节中的自动校准模块
#include "opencv2/stitching/detail/blenders.hpp" // 引入图像缝合细节中的图像融合模块
#include "opencv2/stitching/detail/timelapsers.hpp" // 引入时间错位模块
#include "opencv2/stitching/detail/camera.hpp" // 引入图像缝合细节中的相机模块
#include "opencv2/stitching/detail/exposure_compensate.hpp" // 引入曝光补偿模块
#include "opencv2/stitching/detail/matchers.hpp" // 引入特征匹配模块
#include "opencv2/stitching/detail/motion_estimators.hpp" // 引入运动估计模块
#include "opencv2/stitching/detail/seam_finders.hpp" // 引入接缝查找模块
#include "opencv2/stitching/detail/warpers.hpp" // 引入图像扭曲模块
#include "opencv2/stitching/warpers.hpp" // 引入图像扭曲模块
#ifdef HAVE_OPENCV_XFEATURES2D // 条件编译,检查是否包含特征检测模块
#include "opencv2/xfeatures2d.hpp" // 引入扩展特征检测模块
#include "opencv2/xfeatures2d/nonfree.hpp" // 引入非自由特征检测模块(如SIFT、SURF等)
#endif
#define ENABLE_LOG 1 // 定义一个用于控制是否打印日志的宏
#define LOG(msg) std::cout << msg // 定义一个宏,用于输出日志信息到控制台
#define LOGLN(msg) std::cout << msg << std::endl // 定义一个宏,用于输出日志信息到控制台,并换行
using namespace std; // 使用标准命名空间
using namespace cv; // 使用OpenCV命名空间
using namespace cv::detail; // 使用OpenCV细节命名空间
// 函数printUsage用于打印使用说明
// 打印使用说明
static void printUsage(char** argv)
{
cout <<
"旋转模型图像拼接器。\n\n"
<< argv[0] << " img1 img2 [...imgN] [flags]\n\n"
"Flags:\n"
" --preview\n"
" 以预览模式运行拼接。比普通模式更快,但输出图像分辨率较低。\n"
" --try_cuda (yes|no)\n"
" 尝试使用CUDA。默认值为'no'。所有默认值均为CPU模式。\n"
"\n运动估计标志:\n"
" --work_megapix <float>\n"
" 图像配准步骤的分辨率。默认值为0.6百万像素。\n"
" --features (surf|orb|sift|akaze)\n"
" 用于图像匹配的特征类型。\n"
" 如果可用,默认为surf,否则为orb。\n"
" --matcher (homography|affine)\n"
" 用于两两图像匹配的匹配器。\n"
" --estimator (homography|affine)\n"
" 用于变换估计的估计器类型。\n"
" --match_conf <float>\n"
" 特征匹配步骤的置信度。对于surf,默认值为0.65,对于orb,默认值为0.3。\n"
" --conf_thresh <float>\n"
" 两个图像为同一全景图的置信度阈值。\n"
" 默认值为1.0。\n"
" --ba (no|reproj|ray|affine)\n"
" 捆绑调整成本函数。默认为ray。\n"
" --ba_refine_mask (mask)\n"
" 为捆绑调整设置细化掩模。格式为'x_xxx',其中'x'表示细化相应参数,'_'表示不细化,格式如下:\n"
" <fx><skew><ppx><aspect><ppy>。默认掩模为'xxxxx'。如果捆绑调整不支持所选参数的估计,则相应标志将被忽略。\n"
" --wave_correct (no|horiz|vert)\n"
" 执行波效果校正。默认为'horiz'。\n"
" --save_graph <file_name>\n"
" 将匹配图保存为DOT语言表示的<file_name>文件。\n"
" 标签说明:Nm是匹配数,Ni是内点数,C是置信度。\n"
"\n合成标志:\n"
" --warp (affine|plane|cylindrical|spherical|fisheye|stereographic|compressedPlaneA2B1|compressedPlaneA1.5B1|compressedPlanePortraitA2B1|compressedPlanePortraitA1.5B1|paniniA2B1|paniniA1.5B1|paniniPortraitA2B1|paniniPortraitA1.5B1|mercator|transverseMercator)\n"
" 变换表面类型。默认为'spherical'。\n"
" --seam_megapix <float>\n"
" 接缝估计步骤的分辨率。默认为0.1百万像素。\n"
" --seam (no|voronoi|gc_color|gc_colorgrad)\n"
" 接缝估计方法。默认为'gc_color'。\n"
" --compose_megapix <float>\n"
" 合成步骤的分辨率。使用-1表示原始分辨率。\n"
" 默认值为-1。\n"
" --expos_comp (no|gain|gain_blocks|channels|channels_blocks)\n"
" 曝光补偿方法。默认为'gain_blocks'。\n"
" --expos_comp_nr_feeds <int>\n"
" 曝光补偿反馈次数。默认为1。\n"
" --expos_comp_nr_filtering <int>\n"
" 曝光补偿增益的过滤迭代次数。仅在使用块曝光补偿方法时使用。\n"
" 默认为2。\n"
" --expos_comp_block_size <int>\n"
" 曝光补偿器使用的块大小(以像素为单位)。\n"
" 仅在使用块曝光补偿方法时使用。\n"
" 默认为32。\n"
" --blend (no|feather|multiband)\n"
" 混合方法。默认为'multiband'。\n"
" --blend_strength <float>\n"
" 混合强度范围为[0,100]。默认值为5。\n"
" --output <result_img>\n"
" 输出图像的文件名。默认为'result.jpg'。\n"
" --timelapse (as_is|crop) \n"
" 将扭曲后的图像单独输出为时间-lapse电影的帧,输入文件名前加上'fixed_'。\n"
" --rangewidth <int>\n"
" 使用range_width限制要匹配的图像数量。\n";
}
// 默认的命令行参数
vector<String> img_names; // 存储图像文件名的向量
bool preview = false; // 是否预览模式的标志,默认关闭
bool try_cuda = false; // 是否尝试使用CUDA加速的标志,默认关闭
double work_megapix = 0.6; // 用于图像注册步骤的分辨率,默认为0.6百万像素
double seam_megapix = 0.1; // 用于估算缝合线的图像分辨率,默认为0.1百万像素
double compose_megapix = -1; // 图像融合步骤的分辨率,默认为原始分辨率
float conf_thresh = 1.f; // 配准图像的置信度阈值,默认为1.0
#ifdef HAVE_OPENCV_XFEATURES2D
string features_type = "surf"; // 默认特征类型为SURF,如果库中包含xfeatures2d特征
float match_conf = 0.65f; // 特征匹配的置信度,默认为0.65
#else
string features_type = "orb"; // 不包含xfeatures2d时,默认特征类型为ORB
float match_conf = 0.3f; // ORB特征的匹配置信度,默认为0.3
#endif
string matcher_type = "homography"; // 特征匹配器类型,默认为基于单应性矩阵的匹配器
string estimator_type = "homography"; // 用于变换估计的类型,默认也是单应性
string ba_cost_func = "ray"; // 光束平差(Bundle Adjustment)的代价函数,默认为"ray"
string ba_refine_mask = "xxxxx"; // 光束平差细化掩模,默认对所有参数进行细化
bool do_wave_correct = true; // 是否进行波形校正,默认开启
WaveCorrectKind wave_correct = detail::WAVE_CORRECT_HORIZ; // 波形校正的方向,默认水平方向
bool save_graph = false; // 是否保存图像匹配状态图,默认关闭
std::string save_graph_to; // 保存图像匹配状态图的文件名称
string warp_type = "spherical"; // 进行图像变形的类型,默认为球形变形
int expos_comp_type = ExposureCompensator::GAIN_BLOCKS; // 曝光补偿的类型,默认为gain_blocks
int expos_comp_nr_feeds = 1; // 曝光补偿阶段的输入数,默认为1
int expos_comp_nr_filtering = 2; // 曝光补偿增益的滤波迭代次数,默认为2次
int expos_comp_block_size = 32; // 曝光补偿时块的大小,默认为32像素
string seam_find_type = "gc_color"; // 缝合线发现的方法,默认为基于颜色的图割方法
int blend_type = Blender::MULTI_BAND; // 图像融合的方法,默认为多频段融合
int timelapse_type = Timelapser::AS_IS; // 创建时光延展图像的类型,默认为AS_IS(即原样)
float blend_strength = 5; // 融合的强度,默认值为5
string result_name = "result.jpg"; // 最终生成的全景图像的文件名,默认为result.jpg
bool timelapse = false; // 是否创建时光延展图像,默认为否
int range_width = -1; // 限制匹配图像数量的范围宽度,默认不限制
```cpp
// 解析命令行参数的静态函数定义
static int parseCmdArgs(int argc, char** argv)
{
// 如果只有一个参数(程序名),打印使用说明并返回-1
if (argc == 1)
{
printUsage(argv);
return -1;
}
// 遍历命令行提供的所有参数
for (int i = 1; i < argc; ++i)
{
// 如果命令行参数为"--help"或"/?",打印使用说明并返回-1
if (string(argv[i]) == "--help" || string(argv[i]) == "/?")
{
printUsage(argv);
return -1;
}
// 如果命令行参数为"--preview",设置预览模式标志为真
else if (string(argv[i]) == "--preview")
{
preview = true;
}
// 如果命令行参数为"--try_cuda",根据后续参数选择是否尝试CUDA加速
else if (string(argv[i]) == "--try_cuda")
{
// 根据后续参数的值 ("no" 或 "yes") 设定try_cuda变量
if (string(argv[i + 1]) == "no")
try_cuda = false;
else if (string(argv[i + 1]) == "