并查集(disjoint set)结构介绍
来源:互联网 发布:安倍 修宪 知乎 编辑:程序博客网 时间:2024/06/07 00:39
1.简述
在实现多图像无序输入的拼接中,我们先使用surf算法对任意两幅图像进行特征点匹配,每对图像的匹配都有一个置信度confidence参数,来衡量两幅图匹配的可信度,当confidence>conf_threshold,我们就认为这两幅图可以拼接,属于一个全景拼接的集合,然后扩展这个集合就可以确定最大的可拼接集合,排除一些无效的图像,然后进行后续的拼接。
并查集的定义就是并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。即将属于相同集合的元素合并起来,中间需要查找某个元素属于哪个集合,然后需要将两个元素或者集合进行合并处理。
2.结构体及函数定义
下面我们介绍opencv_stitching中使用的互斥集结构和函数的定义
class DisjointSets{public://互斥集初始化,元素个数是elem_countDisjointSets(int elem_count = 0) { createOneElemSets(elem_count); }void createOneElemSets(int elem_count);//创建互斥集int findSetByElem(int elem);//查找元素所属的集合int mergeSets(int set1, int set2);//合并两个集合std::vector<int> parent;//元素所属集合 parent[elem] = set ,元素elem的集合是setstd::vector<int> size;//集合的包含的元素个数 size[set] = set_size,集合set的元素数是set_sizeprivate:std::vector<int> rank_;//rank_[set] = rank,集合set标记};
/************************************************************************//* 创建一个互斥集,尺寸为n %参数 int n,输入互斥集的尺寸*//************************************************************************/void DisjointSets::createOneElemSets(int n){ rank_.assign(n, 0);//设置rank_长度为n,初始值为0 size.assign(n, 1);//设置size长度为n,初始值为1 parent.resize(n);//设置parent的长度为n for (int i = 0; i < n; ++i) parent[i] = i;//parent[elem] = set,初始化每个元素所在的集合}/************************************************************************//* 查找元素所在的集合 %参数int elem 输入元素*//************************************************************************/int DisjointSets::findSetByElem(int elem){//由于互斥集也是树形结构,所以需要向上递归到根节点,即元素所属的最终集合 int set = elem; while (set != parent[set])//如果元素的值与所属集合的值不相同,说明元素是经过集合合并过的,所以要继续向上递归 set = parent[set]; int next; while (elem != parent[elem])//将之前所有的递归过的元素的集合全改成最终的根节点集合 { next = parent[elem]; parent[elem] = set; elem = next; } return set;}/************************************************************************//* 合并两个集合%参数int set1,int set2 两个集合set1和set2*//************************************************************************/int DisjointSets::mergeSets(int set1, int set2){//比较两个集合的rank_,将rank_值小的集合合并到值大的集合中 if (rank_[set1] < rank_[set2]) { parent[set1] = set2; size[set2] += size[set1]; return set2; } if (rank_[set2] < rank_[set1]) { parent[set2] = set1; size[set1] += size[set2]; return set1; }//如果rank_相等,则默认将set1合并到set2中,set2的rank_值+1 parent[set1] = set2; rank_[set2]++; size[set2] += size[set1]; return set2;}模拟程序:
#include "astdio.h"#include "disjointset.h"#define conf_threshold 90#define num_images 10void main(){int max_comp = 0;int max_size = 0;vector<int> confident(num_images*num_images);DisjointSets comps(num_images);//使用随机数模拟多幅图像中每个图像相互匹配的置信度(0-100)//另外1与2的匹配置信度和2与1的置信度我们默认相同(实际中是不相同的)srand((unsigned)time(NULL));for (int i = 0;i<num_images;i++){cout<<endl;for (int j = 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来决定是否属于一个全景集合for (int i = 0; i < num_images; ++i){for (int j = 0; j < num_images; ++j){if (confident[i*num_images + j] < conf_threshold)continue;int comp1 = comps.findSetByElem(i);int comp2 = comps.findSetByElem(j);if (comp1 != comp2)comps.mergeSets(comp1, comp2);}}//找出包含图片最多的全景集合for (int i = 0;i< num_images;i++){if (i == 0){max_comp = 0;max_size = comps.size[i];}else if(comps.size[i]>max_size){max_comp = i;max_size = comps.size[i];}}//将该集合中的元素打印出来cout<<endl<<"images in the max_comp:"<<endl;int j = 0;for (int i = 0;i<num_images;i++){if (comps.findSetByElem(i) == max_comp){cout<<++j<<": "<< i<<endl;}}while(1);}
输出结果:
0 0
- 并查集(disjoint set)结构介绍
- 【数据结构】【计算机视觉】并查集(disjoint set)结构介绍
- Disjoint-Set并查集
- 【Panoramic stitching】并查集(disjoint set)结构及源码
- 并查集(disjoint-set forests)
- 并查集 (Disjoint Set)
- Disjoint set(并查集) data structure
- 并查集(Disjoint Set)
- 并查集(Disjoint Set)
- disjoint set (union-find set) (并查集)
- 编程算法 - 并查集(disjoint set) 代码(C)
- 数据结构 之 并查集(Disjoint Set)
- 【算法导论-36】并查集(Disjoint Set)详解
- 并查集(disjoint set)的实现及应用
- 并查集-Disjoint Set 和 图-Graph
- 并查集(disjoint)
- 利用并查集(Disjoint Set)解决一道算法题
- 重学数据结构系列之——森林之并查集(Disjoint set)
- Hibernate事务与并发问题处理
- 不容易啊
- JAVA之窗口和布局
- 三种东西永远不要放到数据库里
- 机器学习小结
- 并查集(disjoint set)结构介绍
- 【视频处理工程】4、DirectShow基本开发过程(二)
- 《Mali OpenCL SDK v1.1.0》教程样例之五“64位整数与原子操作”
- OpenGL: glEdgeFlag示例程序:
- oracle数据文件查询修改总结
- 文件系统损坏的修复过程
- 自定义 PopoverViewController
- inotify -- Linux 2.6 内核中的文件系统变化通知机制
- UIALertView的基本用法与UIAlertViewDelegate对对话框的事件处理方法