2016-09-21 81 views
1

我正在构建一个Android应用程序来创建全景图。用户捕捉一组图像,那些图像 被发送到我的原生针迹功能,该功能基于https://github.com/opencv/opencv/blob/master/samples/cpp/stitching_detailed.cpp。 由于图像是按顺序排列的,因此我想只将每个图像与矢量中的下一个图像进行匹配。OpenCV 3.1为了拍摄而拼接图像

我发现英特尔的一篇文章,在做这一点与下面的代码:

vector<MatchesInfo> pairwise_matches; 
BestOf2NearestMatcher matcher(try_gpu, match_conf); 
Mat matchMask(features.size(),features.size(),CV_8U,Scalar(0)); 
for (int i = 0; i < num_images -1; ++i) 
{ 
    matchMask.at<char>(i,i+1) =1; 
} 
matcher(features, pairwise_matches,matchMask); 
matcher.collectGarbage(); 

问题是,这不会编译。我猜是因为即时通讯使用OpenCV 3.1。 后来我发现的地方,该代码会做同样的:

int range_width = 2; 
BestOf2NearestRangeMatcher matcher(range_width, try_cuda, match_conf); 
matcher(features, pairwise_matches); 
matcher.collectGarbage(); 

而对于我的大部分样品能正常工作。但有时候,特别是当我拼接一大组图像(大约15)时,一些对象出现在彼此的顶部和它们不应该的位置。 我也注意到,最终结果的“开始”(左侧)并不是向量中的第一个图像,这是奇怪的 。

我使用“orb”作为features_type和“ray”作为ba_cost_func。似乎我不能在OpenCV 3.1上使用SURF。 我的初始参数,其余是这样的:

bool try_cuda = false; 
double compose_megapix = -1; //keeps resolution for final panorama 
float match_conf = 0.3f; //0.3 default for orb 
string ba_refine_mask = "xxxxx"; 
bool do_wave_correct = true; 
WaveCorrectKind wave_correct = detail::WAVE_CORRECT_HORIZ; 
int blend_type = Blender::MULTI_BAND; 
float blend_strength = 5; 

double work_megapix = 0.6; 
double seam_megapix = 0.08; 
float conf_thresh = 0.5f; 
int expos_comp_type = ExposureCompensator::GAIN_BLOCKS; 
string seam_find_type = "dp_colorgrad"; 
string warp_type = "spherical"; 

所以任何人都可以开导我,为什么这不是工作,我应该如何符合我的特点是什么?任何帮助或方向将不胜感激!

TL; DR:我想按拍摄顺序拼接图像,但上面的代码不适合我,我该怎么做?

回答

0

所以我发现这里的问题不是图像拼接的顺序,而是基于Homography Based Estimator和Bundle Ray Adjuster的相机参数估计的旋转。

这些旋转角度是考虑自转相机估计的,我的用例包含旋转相机的用户(这意味着也会进行一些平移) 因为(我猜)水平角度(绕Y轴)是高度高估这意味着该算法考虑该组图像的覆盖> = 360度这导致不应该重叠一些重叠区域。

仍然还没有找到这个问题)中的溶液虽然。

0

匹配器(取UMat作为掩码而不是Mat对象,所以请尝试以下代码:

vector<MatchesInfo> pairwise_matches; 
BestOf2NearestMatcher matcher(try_gpu, match_conf); 
Mat matchMask(features.size(),features.size(),CV_8U,Scalar(0)); 
for (int i = 0; i < num_images -1; ++i) 
{ 
    matchMask.at<char>(i,i+1) =1; 
} 

UMat umask = matchMask.getUMat(ACCESS_READ); 

matcher(features, pairwise_matches, umask); 
matcher.collectGarbage();