没有合适的资源?快使用搜索试试~ 我知道了~
首页OpenCV stitching_detailed.cpp解读
OpenCV stitching_detailed.cpp解读
需积分: 48 938 浏览量
更新于2023-05-27
评论
收藏 1.05MB PDF 举报
OpenCV stitching_detailed.cpp例程的详细解读,包括怎么分析程序和拼接的参数,步骤解读
资源详情
资源评论
资源推荐

一、stitching_detail 程序运行流程
1.命令行调用程序,输入源图像以及程序的参数
2.特征点检测,判断是使用 surf 还是 orb,默认是 surf。
3.对图像的特征点进行匹配,使用最近邻和次近邻方法,将两个最优的匹配的置信度
保存下来。
4.对图像进行排序以及将置信度高的图像保存到同一个集合中,删除置信度比较低的
图像间的匹配,得到能正确匹配的图像序列。这样将置信度高于门限的所有匹配合并到一个
集合中。
5.对所有图像进行相机参数粗略估计,然后求出旋转矩阵
6.使用光束平均法进一步精准的估计出旋转矩阵。
7.波形校正,水平或者垂直
8.拼接
9.融合,多频段融合,光照补偿,
二、stitching_detail 程序接口介绍
img1 img2 img3 输入图像
--preview 以预览模式运行程序,比正常模式要快,但输出图像分辨率低,拼接的分辨
率 compose_megapix 设置为 0.6
--try_gpu (yes|no) 是否使用 GPU(图形处理器),默认为 no
/* 运动估计参数 */
--work_megapix <--work_megapix <float>> 图像匹配的分辨率大小,图像的面积尺寸
变为 work_megapix*100000,默认为 0.6
--features (surf|orb) 选择 surf 或者 orb 算法进行特征点计算,默认为 surf
--match_conf <float> 特征点检测置信等级,最近邻匹配距离与次近邻匹配距离的比值,
surf 默认为 0.65,orb 默认为 0.3
--conf_thresh <float> 两幅图来自同一全景图的置信度,默认为 1.0
--ba (reproj|ray) 光束平均法的误差函数选择,默认是 ray 方法
--ba_refine_mask (mask) ---------------
--wave_correct (no|horiz|vert) 波形校验 水平,垂直或者没有 默认是 horiz
--save_graph <file_name> 将匹配的图形以点的形式保存到文件中, Nm 代表匹配的
数量,NI 代表正确匹配的数量,C 表示置信度
/*图像融合参数:*/
--warp
(plane|cylindrical|spherical|fisheye|stereographic|compressedPlaneA2B1|compressedPla
neA1.5B1|compressedPlanePortraitA2B1

|compressedPlanePortraitA1.5B1|paniniA2B1|paniniA1.5B1|paniniPortraitA2B1|paniniPor
traitA1.5B1|mercator|transverseMercator)
选择融合的平面,默认是球形
--seam_megapix <float> 拼接缝像素的大小 默认是 0.1 ------------
--seam (no|voronoi|gc_color|gc_colorgrad) 拼接缝隙估计方法 默认是 gc_color
--compose_megapix <float> 拼接分辨率,默认为-1
--expos_comp (no|gain|gain_blocks) 光照补偿方法,默认是 gain_blocks
--blend (no|feather|multiband) 融合方法,默认是多频段融合
--blend_strength <float> 融合强度,0-100.默认是 5.
--output <result_img> 输出图像的文件名,默认是 result,jpg
命令使用实例,以及程序运行时的提示:
三、程序代码分析
1.参数读入

程序参数读入分析,将程序运行是输入的参数以及需要拼接的图像读入内存,检查图像
是否多于 2 张。
[cpp] view plaincopy
1. int retval = parseCmdArgs(argc, argv);
2. if (retval)
3. return retval;
4.
5. // Check if have enough images
6. int num_images = static_cast<int>(img_names.size());
7. if (num_images < 2)
8. {
9. LOGLN("Need more images");
10. return -1;
11. }
2.特征点检测
判断选择是 surf 还是 orb 特征点检测(默认是 surf)以及对图像进行预处理(尺寸缩
放),然后计算每幅图形的特征点,以及特征点描述子
2.1 计算 work_scale,将图像 resize 到面积在 work_megapix*10^6 以下,
(work_megapix 默认是 0.6)
[cpp] view plaincopy
1. work_scale = min(1.0, sqrt(work_megapix * 1e6 / full_img.size().area()));
[cpp] view plaincopy
1. resize(full_img, img, Size(), work_scale, work_scale);
图像大小是 740*830,面积大于 6*10^5,所以计算出 work_scale = 0.98,然后对图像
resize。

2.2 计算 seam_scale,也是根据图像的面积小于 seam_megapix*10^6,
(seam_megapix 默认是 0.1),seam_work_aspect 目前还没用到
[cpp] view plaincopy
1. seam_scale = min(1.0, sqrt(seam_megapix * 1e6 / full_img.size().area()));
2. seam_work_aspect = seam_scale / work_scale; //seam_megapix = 0.1 seam_work_a
spect = 0.69
2.3 计算图像特征点,以及计算特征点描述子,并将 img_idx 设置为 i。
[cpp] view plaincopy
1. (*finder)(img, features[i]);//matcher.cpp 348
2. features[i].img_idx = i;
特征点描述的结构体定义如下:
[cpp] view plaincopy
1. struct detail::ImageFeatures
2. Structure containing image keypoints and descriptors.
3. struct CV_EXPORTS ImageFeatures
4. {
5. int img_idx;//
6. Size img_size;
7. std::vector<KeyPoint> keypoints;
8. Mat descriptors;
9. };
2.4 将源图像 resize 到 seam_megapix*10^6,并存入 image[]中
[cpp] view plaincopy

1. resize(full_img, img, Size(), seam_scale, seam_scale);
2. images[i] = img.clone();
3.图像匹配
对任意两副图形进行特征点匹配,然后使用查并集法,将图片的匹配关系找出,并删
除那些不属于同一全景图的图片。
3.1 使用最近邻和次近邻匹配,对任意两幅图进行特征点匹配。
[cpp] view plaincopy
1. vector<MatchesInfo> pairwise_matches;//Structure containing information abou
t matches between two images.
2. BestOf2NearestMatcher matcher(try_gpu, match_conf);//最近邻和次近邻法
3. matcher(features, pairwise_matches);//对每两个图片进行 matcher,20-》
400 matchers.cpp 502
介绍一下 BestOf2NearestMatcher 函数:
[cpp] view plaincopy
1. //Features matcher which finds two best matches for each feature and leav
es the best one only if the ratio between descriptor distances is greater th
an the threshold match_conf.
2. detail::BestOf2NearestMatcher::BestOf2NearestMatcher(bool try_use_gpu=fals
e,float match_conf=0.3f,
3. intnum_matches_thresh1=6,
int num_matches_thresh2=6)
4. Parameters: try_use_gpu – Should try to use GPU or not
5. match_conf – Match distances ration threshold
6. num_matches_thresh1 – Minimum number of matches required for the 2D projecti
ve
7. transform estimation used in the inliers classification step
8. num_matches_thresh2 – Minimum number of matches required for the 2D projecti
ve
9. transform re-estimation on inliers
函数的定义(只是设置一下参数,属于构造函数):
[cpp] view plaincopy
1. BestOf2NearestMatcher::BestOf2NearestMatcher(bool try_use_gpu, float match_c
onf, int num_matches_thresh1, int num_matches_thresh2)
2. {
3. #ifdef HAVE_OPENCV_GPU
4. if (try_use_gpu && getCudaEnabledDeviceCount() > 0)
5. impl_ = new GpuMatcher(match_conf);
6. else
剩余33页未读,继续阅读


















安全验证
文档复制为VIP权益,开通VIP直接复制

评论0