1.简述
在实现多图像无序输入的拼接中,我们先使用surf算法对任意两幅图像进行特征点匹配,每对图像的匹配都有一个置信度confidence参数,来衡量两幅图匹配的可信度,当confidence>conf_threshold,我们就认为这两幅图可以拼接,属于一个全景拼接的集合,然后扩展这个集合就可以确定最大的可拼接集合,排除一些无效的图像,然后进行后续的拼接。
并查集的定义就是并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。即将属于相同集合的元素合并起来,中间需要查找某个元素属于哪个集合,然后需要将两个元素或者集合进行合并处理。
2.结构体及函数定义
下面我们介绍opencv_stitching中使用的互斥集结构和函数的定义
- classDisjointSets
- {
- public:
-
- DisjointSets(intelem_count=0){createOneElemSets(elem_count);}
-
-
- voidcreateOneElemSets(intelem_count);
- intfindSetByElem(intelem);
- intmergeSets(intset1,intset2);
- std::vector<int>parent;
- std::vector<int>size;
- private:
- int>rank_;
- };
copy
- /*
- 创建一个互斥集,尺寸为n
- %参数intn,输入互斥集的尺寸
- */
- /************************************************************************/
- voidDisjointSets::createOneElemSets(intn)
- rank_.assign(n,0);
- size.assign(n,1);
- parent.resize(n);
- for(inti=0;i<n;++i)
- parent[i]=i;
- }
- /*
- 查找元素所在的集合
- %参数intelem输入元素
- */
- intDisjointSets::findSetByElem(intelem)
- {
- //由于互斥集也是树形结构,所以需要向上递归到根节点,即元素所属的最终集合
- intset=elem;
- while(set!=parent[set])
- set=parent[set];
- intnext;
- while(elem!=parent[elem])
- next=parent[elem];
- parent[elem]=set;
- elem=next;
- returnset;
- 合并两个集合
- %参数intset1,intset2两个集合set1和set2
- intDisjointSets::mergeSets(intset2)
- //比较两个集合的rank_,将rank_值小的集合合并到值大的集合中
- if(rank_[set1]<rank_[set2])
- parent[set1]=set2;
- size[set2]+=size[set1];
- returnset2;
- if(rank_[set2]<rank_[set1])
- parent[set2]=set1;
- size[set1]+=size[set2];
- returnset1;
- //如果rank_相等,则默认将set1合并到set2中,set2的rank_值+1
- parent[set1]=set2;
- rank_[set2]++;
- }
模拟程序:
copy
#include"astdio.h"
- #include"disjointset.h"
- #defineconf_threshold90
- #definenum_images10
- voidmain()
- intmax_comp=0;
- intmax_size=0;
- vector<int>confident(num_images*num_images);
- DisjointSetscomps(num_images);
- //使用随机数模拟多幅图像中每个图像相互匹配的置信度(0-100)
- //另外1与2的匹配置信度和2与1的置信度我们默认相同(实际中是不相同的)
- srand((unsigned)time(NULL));
- inti=0;i<num_images;i++)
- cout<<endl;
- intj=0;j<num_images;j++)
- if(!confident[i*num_images+j])
- confident[i*num_images+j]=rand()%100;
- confident[j*num_images+i]=confident[i*num_images+j];
- if(i==j)
- confident[i*num_images+j]=100;
- }
- cout<<""<<confident[i*num_images+j];
- //根据两幅图匹配置信度是否大于conf_threshold来决定是否属于一个全景集合
- inti=0;i<num_images;++i)
- intj=0;j<num_images;++j)
- if(confident[i*num_images+j]<conf_threshold)
- continue;
- intcomp1=comps.findSetByElem(i);
- intcomp2=comps.findSetByElem(j);
- if(comp1!=comp2)
- comps.mergeSets(comp1,comp2);
- //找出包含图片最多的全景集合
- inti=0;i<num_images;i++)
- if(i==0)
- max_comp=0;
- max_size=comps.size[i];
- elseif(comps.size[i]>max_size)
- max_comp=i;
- max_size=comps.size[i];
- //将该集合中的元素打印出来
- cout<<endl<<"imagesinthemax_comp:"<<endl;
- intj=0;
- if(comps.findSetByElem(i)==max_comp)
- cout<<++j<<":"<<i<<endl;
- while(1);
- }
输出结果:
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|