OpenCV总结6——stitcher
之前写过⼀次stitcher,但是写的不太好,这次准备⼀点⼀点的总结,可能有出错的地⽅,欢迎指正。
之前总结的时候忘了查看源码的版本,看的是旧版的源码,这次是新的。先从头⽂件开始。
在stitcer.cpp中包含的头⽂件是precomp.hpp,这个⽂件中包含了许多cuda并⾏计算⽤的类
#ifndef __OPENCV_STITCHING_PRECOMP_H__
#define __OPENCV_STITCHING_PRECOMP_H__
#include"opencv2/opencv_modules.hpp"
#include<vector>
#include<algorithm>
#include<utility>
#include<t>
#include<functional>
我只在乎你日语版#include<sstream>
#include<iostream>
#include<cmath>
#include"opencv2/core.hpp"
#include"opencv2/core/ocl.hpp"
#include"opencv2/core/utility.hpp"
#include"opencv2/stitching.hpp"
#include"opencv2/stitching/detail/autocalib.hpp"
come back home#include"opencv2/stitching/detail/blenders.hpp"
#include"opencv2/stitching/detail/timelaprs.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/am_finders.hpp"
#include"opencv2/stitching/detail/util.hpp"
#include"opencv2/stitching/detail/warpers.hpp"
#include"opencv2/imgproc.hpp"
#include"opencv2/features2d.hpp"
#include"opencv2/calib3d.hpp"
#ifdef HAVE_OPENCV_CUDAARITHM
# include"opencv2/cudaarithm.hpp"
拉帕奇#endif
#ifdef HAVE_OPENCV_CUDAWARPING
# include"opencv2/cudawarping.hpp"
#endif
#ifdef HAVE_OPENCV_CUDAFEATURES2D
# include"opencv2/cudafeatures2d.hpp"
#endif
#ifdef HAVE_OPENCV_CUDALEGACY
# include"opencv2/cudalegacy.hpp"
#endif
#include"opencv2/core/private.hpp"
#include"util_log.hpp"
#endif
但是上⾯的头⽂件我们⾃⼰是⽆法引⽤的,这⾥主要针对算法需要的类以及内容进⾏总结。stitcher.hpp
需要⽤到的opencv的库,这些库都是stitcher管线中需要⽤到的⼀些算法库
#include<opencv.hpp>
#include<opencv2\features2d.hpp>
#include<opencv2\stitching\warpers.hpp>
#include<opencv2\stitching\detail\matchers.hpp>
#include<opencv2\stitching\detail\motion_estimators.hpp>
#include<opencv2\stitching\detail\exposure_compensate.hpp>
#include<opencv2\stitching\detail\am_finders.hpp>
#include<opencv2\stitching\detail\blenders.hpp>
#include<opencv2\stitching\detail\camera.hpp>
定义警告,Detected X11中可能存在相同的定义,导致构建错误,应该先包含这个⽂件
#if defined(Status)
# warning Detected X11 'Status' macro definition, it can cau build conflicts.Plea, include this header before any X11 headers. #endif
头⽂件主体
namespace cv {
class CV_EXPORTS_W Stitcher//导出dll
{
public:
/**
* When tting a resolution for stitching, this values is a placeholder
* for prerving the original resolution.
*/
//针对不同的编译器版本,不同的编译器对于static const的初始化⽅式不同
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900/*MSVS 2015*/)
static constexpr double ORIG_RESOL =-1.0;
#el
// support MSVS 2013
static const double ORIG_RESOL;// Initialized in stitcher.cpp
#endif
enum Status//算法的完成状态
{
OK =0,
ERR_NEED_MORE_IMGS =1,
ERR_HOMOGRAPHY_EST_FAIL =2,
ERR_CAMERA_PARAMS_ADJUST_FAIL =3
};
enum Mode//两种模式配置
{
/** Mode for creating photo panoramas. Expects images under perspective
transformation and projects resulting pano to sphere.
@sa detail::BestOf2NearestMatcher SphericalWarper
*/
PANORAMA =0,//球形映射
/** Mode for composing scans. Expects images under affine transformation does
not compensate exposure by default.
@sa detail::AffineBestOf2NearestMatcher AffineWarper
*/
SCANS =1,//仿射变换,默认不使⽤光照补偿
};
/** @brief Creates a Stitcher configured in one of the stitching modes.
@param mode Scenario for stitcher operation. This is usually determined by source of images
to stitch and their transformation. Default parameters will be chon for operation in given
scenario.
@return Stitcher class instance.
@return Stitcher class instance.
*/
//CV_WRAP ⽤于创建Python和java的包装器
/*
选择⼀种模式进⾏拼接的创建
*/
CV_WRAP static Ptr<Stitcher>create(Mode mode = Stitcher::PANORAMA);//CV_WRAP是脚本标志,⽤于创建Python和java的包装器
//设置的参数基本上是⽤来控制分辨率,尺度或者缩放⼤⼩的
CV_WRAP double registrationResol()const{return registr_resol_;}
CV_WRAP void tRegistrationResol(double resol_mpx){ registr_resol_ = resol_mpx;}//将图像的缩放率控制在0-1之间,因为图像⼀般为三位数的边长,所以这样计算了⼀个⽐例将图像进⾏了缩放,相对的图像的细节与特征点的数量也就会变化,这个值越⼤则图像中的细节就越多,特征点也会越多
CV_WRAP double amEstimationResol()const{return am_est_resol_;}//接缝尺度计算因⼦
CV_WRAP void tSeamEstimationResol(double resol_mpx){ am_est_resol_ = resol_mpx;}迈克学摇滚 传奇
CV_WRAP double compositingResol()const{return compo_resol_;}//曝光
CV_WRAP void tCompostitingResol(double resol_mpx){ compo_resol_ = resol_mpx;}
CV_WRAP double panoConfidenceThresh()const{return conf_thresh_;}//置信度
CV_WRAP void tPanoConfidenceThresh(double conf_thresh){ conf_thresh_ = conf_thresh;}
CV_WRAP bool waveCorrection()const{return do_wave_correct_;}//波形校正
CV_WRAP void tWaveCorrection(bool flag){ do_wave_correct_ = flag;}
CV_WRAP InterpolationFlags interpolationFlags()const{return interp_flags_;}//插值
CV_WRAP void tInterpolationFlags(InterpolationFlags interp_falgs){ interp_flags_ = interp_falgs;}
detail::WaveCorrectKind waveCorrectionKind()const{return wave_correct_kind_;}
void tWavecorrectKind(detail::WaveCorrectKind kind){ wave_correct_kind_ = kind;}//波形校正
Ptr<Feature2D>featuresFinder(){return features_finder_;}
const Ptr<Feature2D>featuresFinder()const{return features_finder_;}//特征查找
void tFeaturesFinder(Ptr<Feature2D> features_finder){ features_finder_ = features_finder;}
Ptr<detail::FeaturesMatcher>featuresMatcher(){return features_matcher_;}//特征配准器
const Ptr<detail::FeaturesMatcher>featuresMatcher()const{return features_matcher_;}
void tFeaturesMatcher(Ptr<detail::FeaturesMatcher> features_matcher){ features_matcher_ = features_matcher;}
const cv::UMat&matchingMask()const{return matching_mask_;}//配准遮罩
void tMatchingMask(const cv::UMat &mask)
{
CV_pe()== CV_8U&&ls == ws);
matching_mask_ = mask.clone();
}
Ptr<detail::BundleAdjusterBa>bundleAdjuster(){return bundle_adjuster_;}//相机参数优化
const Ptr<detail::BundleAdjusterBa>bundleAdjuster()const{return bundle_adjuster_;}
void tBundleAdjuster(Ptr<detail::BundleAdjusterBa> bundle_adjuster){ bundle_adjuster_ = bundle_adjuster;}
Ptr<detail::Estimator>estimator(){return estimator_;}//相机旋转估计类,它根据所有图像的特征,针对所有成对匹配的图像进⾏相机旋转的估计坐标原点取决于实现,例如可以始终相对于第⼀个摄像机标准化旋转
const Ptr<detail::Estimator>estimator()const{return estimator_;}
collaboration
void tEstimator(Ptr<detail::Estimator> estimator){ estimator_ = estimator;}
Ptr<WarperCreator>warper(){return warper_;}//图像扭曲变换⼯⼚基类
const Ptr<WarperCreator>warper()const{return warper_;}
void tWarper(Ptr<WarperCreator> creator){ warper_ = creator;}
Ptr<detail::ExposureCompensator>exposureCompensator(){return exposure_comp_;}//曝光补偿器
const Ptr<detail::ExposureCompensator>exposureCompensator()const{return exposure_comp_;}
void tExposureCompensator(Ptr<detail::ExposureCompensator> exposure_comp){ exposure_comp_ = exposure_comp;}
Ptr<detail::SeamFinder>amFinder(){return am_finder_;}//接缝
const Ptr<detail::SeamFinder>amFinder()const{return am_finder_;}
void tSeamFinder(Ptr<detail::SeamFinder> am_finder){ am_finder_ = am_finder;}
void tSeamFinder(Ptr<detail::SeamFinder> am_finder){ am_finder_ = am_finder;}
Ptr<detail::Blender>blender(){return blender_;}//混合器
const Ptr<detail::Blender>blender()const{return blender_;}
wheelvoid tBlender(Ptr<detail::Blender> b){ blender_ = b;}
/** @brief The functions try to match the given images and to estimate rotations of each camera.
@note U the functions only if you're aware of the stitching pipeline, otherwi u
Stitcher::stitch.
@param images Input images.
@param masks Masks for each input image specifying where to look for keypoints (optional).
@return Status code.
*/
/
/估计相机变换,也可以指定特征点的查找位置
CV_WRAP Status estimateTransform(InputArrayOfArrays images, InputArrayOfArrays masks =noArray());
/** @overload */
//全景拼接函数存在重载函数
CV_WRAP Status compoPanorama(OutputArray pano);//在得到变换估计后,通过这些函数进⾏变换和拼接
/** @brief The functions try to compo the given images (or images stored internally from the other function
calls) into the final pano under the assumption that the image transformations were estimated
before.
@note U the functions only if you're aware of the stitching pipeline, otherwi u
Stitcher::stitch.
@param images Input images.
@param pano Final pano.
@return Status code.
*/
Status compoPanorama(InputArrayOfArrays images, OutputArray pano);
loudly/** @brief The functions try to stitch the given images.
@param images Input images.
@param masks Masks for each input image specifying where to look for keypoints (optional).
@param pano Final pano.
@return Status code.
*/
CV_WRAP Status stitch(InputArrayOfArrays images, InputArrayOfArrays masks, OutputArray pano);//拼接管线接⼝,调⽤整个过程 std::vector<int>component()const{return indices_;}//⽤于拼接图像的索引
职称英语考试资料std::vector<detail::CameraParams>cameras()const{return cameras_;}//返回所有的相机参数
CV_WRAP double workScale()const{return work_scale_;}//返回配准的尺度
UMat resultMask()const{return result_mask_;}//结果遮罩
private:
Status matchImages();
Status estimateCameraParams();
double registr_resol_;//误差
double am_est_resol;//接缝
double compo_resol;//光照
double conf_thresh_;//置信度
InterpolationFlags interp_flags_;//插值算法
Ptr<Feature2D> features_finder_;//特征
Ptr<detail::FeaturesMatcher> features_matcher_;//特征匹配
cv::UMat matching_mask_;//遮罩,opencl加速
Ptr<detail::BundleAdjusterBa> bundle_adjuster_;//相机参数估计
Ptr<detail::Estimator> estimator_;//参数估计
bool do_wave_correct_;//是否进⾏波形校正
detail::WaveCorrectKind wave_correct_kind_;//波形校正,使图像更加的⽔平或者垂直
Ptr<WarperCreator> warper_;//图像变换基类
Ptr<detail::ExposureCompensator> exposure_comp_;//所有曝光补偿器的基类
Ptr<detail::SeamFinder> am_finder_;//估计缝隙
Ptr < detail::Blender> blender_;//混合
std::vector<cv::UMat> imgs_;
std::vector<cv::UMat> masks_;
std::vector<cv::UMat> masks_;
std::vector<cv::Size> full_img_sizes_;//图像的尺⼨
std::vector<detail::ImageFeatures> features_;//图像特征结构
std::vector<detail::MatchesInfo> pairwi_matches_;//包含两个图像匹配信息的结构,假设这些图像具有单应性
std::vector<cv::UMat> am_est_imgs_;//缝隙估计图像
std::vector<int> indices_;//剔除置信度低的图像后的图像的索引
std::vector<detail::CameraParams> cameras_;//相机参数
UMat result_mask_;//结果遮罩
double work_scale_;//⼯作尺度
double am_scale_;//接缝尺度
double am_work_aspect_;//接缝⼯作尺度
double warped_image_scale_;//变换尺度
};
//将要被弃⽤的接⼝,旧版本接⼝,暂时保留⽤于兼容,后期可能删除
/**
* @deprecated u Stitcher::create
*/
CV_DEPRECATED Ptr<Stitcher>createStitcher(bool try_u_gpu =fal);//CV_DEPRECATED opencv的不建议使⽤的关键字
/**
* @deprecated u Stitcher::create
*/
CV_DEPRECATED Ptr<Stitcher>createStitcherScans(bool try_u_gpu =fal);
//! @} stitching
}// namespace cv
可以看到这个算法涉及到的过程还是很多的,是⼀个⽐较复杂的算法,当然效果还是不错的。对于不熟悉整个算法的⼈⽽⾔,提供了简单的调⽤⽅法,stitch函数直接调⽤拼接的管线,可以不⽤管内部的具体过程与实现,程序会按照固定的管线直接执⾏。对于要求不⾼的情况⾜够,但是因为我在使⽤的过程中会出现⼀些奇怪的错误,包括图像提前释放和图像⼤⼩越界等,所以决定好好研究⼀下代码,总结⼀下这个算法的整个过程。
stitcher.cpp
这⾥头⽂件包含的是precomp.hpp,其中包含了包括cuda的所有类
#include"precomp.hpp"
namespace cv {
//不同的编译器的变量初始化
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900/*MSVS 2015*/)
// Stitcher::ORIG_RESOL is initialized in stitching.hpp.
#el
const double Stitcher::ORIG_RESOL =-1.0;//负数代表不进⾏缩放
obie
#endif
style怎么读
create()
stitcher的对象通过Ptr智能指针获得对象,其他⽅式获得对象运⾏时各个参数都没有初始化,运⾏管线时会报错。