1.简述

在实现多图像无序输入的拼接中,我们先使用surf算法对任意两幅图像进行特征点匹配,每对图像的匹配都有一个置信度confidence参数,来衡量两幅图匹配的可信度,当confidence>conf_threshold,我们就认为这两幅图可以拼接,属于一个全景拼接的集合,然后扩展这个集合就可以确定最大的可拼接集合,排除一些无效的图像,然后进行后续的拼接。

并查集的定义就是并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。即将属于相同集合的元素合并起来,中间需要查找某个元素属于哪个集合,然后需要将两个元素或者集合进行合并处理。

2.结构体及函数定义

下面我们介绍opencv_stitching中使用的互斥集结构和函数的定义

[cpp] view
plain
 copy

  1. class  DisjointSets
  2. {
  3. public:
  4. //互斥集初始化,元素个数是elem_count
  5. DisjointSets(int elem_count = 0) { createOneElemSets(elem_count); }
  6. void createOneElemSets(int elem_count);//创建互斥集
  7. int findSetByElem(int elem);//查找元素所属的集合
  8. int mergeSets(int set1, int set2);//合并两个集合
  9. std::vector<int> parent;//元素所属集合 parent[elem] = set ,元素elem的集合是set
  10. std::vector<int> size;//集合的包含的元素个数 size[set] = set_size,集合set的元素数是set_size
  11. private:
  12. std::vector<int> rank_;//rank_[set] = rank,集合set标记
  13. };
[cpp] view
plain
 copy

  1. /************************************************************************/
  2. /*
  3. 创建一个互斥集,尺寸为n
  4. %参数 int n,输入互斥集的尺寸
  5. */
  6. /************************************************************************/
  7. void DisjointSets::createOneElemSets(int n)
  8. {
  9. rank_.assign(n, 0);//设置rank_长度为n,初始值为0
  10. size.assign(n, 1);//设置size长度为n,初始值为1
  11. parent.resize(n);//设置parent的长度为n
  12. for (int i = 0; i < n; ++i)
  13. parent[i] = i;//parent[elem] = set,初始化每个元素所在的集合
  14. }
  15. /************************************************************************/
  16. /*
  17. 查找元素所在的集合
  18. %参数int elem  输入元素
  19. */
  20. /************************************************************************/
  21. int DisjointSets::findSetByElem(int elem)
  22. {
  23. //由于互斥集也是树形结构,所以需要向上递归到根节点,即元素所属的最终集合
  24. int set = elem;
  25. while (set != parent[set])//如果元素的值与所属集合的值不相同,说明元素是经过集合合并过的,所以要继续向上递归
  26. set = parent[set];
  27. int next;
  28. while (elem != parent[elem])//将之前所有的递归过的元素的集合全改成最终的根节点集合
  29. {
  30. next = parent[elem];
  31. parent[elem] = set;
  32. elem = next;
  33. }
  34. return set;
  35. }
  36. /************************************************************************/
  37. /*
  38. 合并两个集合
  39. %参数int set1,int set2 两个集合set1和set2
  40. */
  41. /************************************************************************/
  42. int DisjointSets::mergeSets(int set1, int set2)
  43. {
  44. //比较两个集合的rank_,将rank_值小的集合合并到值大的集合中
  45. if (rank_[set1] < rank_[set2])
  46. {
  47. parent[set1] = set2;
  48. size[set2] += size[set1];
  49. return set2;
  50. }
  51. if (rank_[set2] < rank_[set1])
  52. {
  53. parent[set2] = set1;
  54. size[set1] += size[set2];
  55. return set1;
  56. }
  57. //如果rank_相等,则默认将set1合并到set2中,set2的rank_值+1
  58. parent[set1] = set2;
  59. rank_[set2]++;
  60. size[set2] += size[set1];
  61. return set2;
  62. }

模拟程序:

[cpp] view
plain
 copy

  1. #include "astdio.h"
  2. #include "disjointset.h"
  3. #define  conf_threshold 90
  4. #define  num_images 10
  5. void main()
  6. {
  7. int max_comp = 0;
  8. int max_size = 0;
  9. vector<int> confident(num_images*num_images);
  10. DisjointSets comps(num_images);
  11. //使用随机数模拟多幅图像中每个图像相互匹配的置信度(0-100)
  12. //另外1与2的匹配置信度和2与1的置信度我们默认相同(实际中是不相同的)
  13. srand((unsigned)time(NULL));
  14. for (int i  = 0;i<num_images;i++)
  15. {
  16. cout<<endl;
  17. for (int j = 0;j<num_images;j++)
  18. {
  19. if (!confident[i*num_images+j])
  20. {
  21. confident[i*num_images+j] = rand()%100;
  22. confident[j*num_images+i] = confident[i*num_images+j];
  23. }
  24. if (i == j)
  25. {
  26. confident[i*num_images+j] = 100;
  27. }
  28. cout<<"   "<<confident[i*num_images+j];
  29. }
  30. }
  31. //根据两幅图匹配置信度是否大于conf_threshold来决定是否属于一个全景集合
  32. for (int i = 0; i < num_images; ++i)
  33. {
  34. for (int j = 0; j < num_images; ++j)
  35. {
  36. if (confident[i*num_images + j] < conf_threshold)
  37. continue;
  38. int comp1 = comps.findSetByElem(i);
  39. int comp2 = comps.findSetByElem(j);
  40. if (comp1 != comp2)
  41. comps.mergeSets(comp1, comp2);
  42. }
  43. }
  44. //找出包含图片最多的全景集合
  45. for (int i = 0;i< num_images;i++)
  46. {
  47. if (i == 0)
  48. {
  49. max_comp = 0;
  50. max_size = comps.size[i];
  51. }
  52. else if(comps.size[i]>max_size)
  53. {
  54. max_comp = i;
  55. max_size = comps.size[i];
  56. }
  57. }
  58. //将该集合中的元素打印出来
  59. cout<<endl<<"images in the max_comp:"<<endl;
  60. int j = 0;
  61. for (int i = 0;i<num_images;i++)
  62. {
  63. if (comps.findSetByElem(i) == max_comp)
  64. {
  65. cout<<++j<<":  "<< i<<endl;
  66. }
  67. }
  68. while(1);
  69. }

输出结果:

【数据结构】【计算机视觉】并查集(disjoint set)结构介绍的更多相关文章

  1. 【算法与数据结构】并查集 Disjoint Set

    并查集(Disjoint Set)用来判断已有的数据是否构成环. 在构造图的最小生成树(Minimum Spanning Tree)时,如果采用 Kruskal 算法,每次添加最短路径前,需要先用并查 ...

  2. 数据结构 之 并查集(Disjoint Set)

    一.并查集的概念:     首先,为了引出并查集,先介绍几个概念:     1.等价关系(Equivalent Relation)     自反性.对称性.传递性.     如果a和b存在等价关系,记 ...

  3. 数据结构之并查集Union-Find Sets

    1.  概述 并查集(Disjoint set或者Union-find set)是一种树型的数据结构,常用于处理一些不相交集合(Disjoint Sets)的合并及查询问题. 2.  基本操作 并查集 ...

  4. 并查集(Disjoint Set)

    在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中.这一类问题其特点是看似并不复杂, ...

  5. 数据结构09—— 并查集(Union-Find)

    一.关于并查集 并查集(Union-Find)是一种树型的数据结构,常用于处理一些不相交集合(Disjoint Sets)的合并及查询问题.并查集(Union-Find)从名字可以看出,主要它涉及两种 ...

  6. 【算法导论-36】并查集(Disjoint Set)具体解释

    WiKi Disjoint是"不相交"的意思.Disjoint Set高效地支持集合的合并(Union)和集合内元素的查找(Find)两种操作,所以Disjoint Set中文翻译 ...

  7. 【基本数据结构】并查集-C++

    并查集,在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中.这一类问题近几年来反复出 ...

  8. 并查集(Disjoint Set Union,DSU)

    定义: 并查集是一种用来管理元素分组情况的数据结构. 作用: 查询元素a和元素b是否属于同一组 合并元素a和元素b所在的组 优化方法: 1.路径压缩 2.添加高度属性 拓展延伸: 分组并查集 带权并查 ...

  9. 数据结构(并查集||树链剖分):HEOI 2016 tree

    [注意事项] 为了体现增强版,题目限制和数据范围有所增强: 时间限制:1.5s 内存限制:128MB 对于15% 的数据,1<=N,Q<=1000. 对于35% 的数据,1<=N,Q ...

随机推荐

  1. SVN客户端安装

    1.安装客户端 双击运行: 点击[next] 点击[next] 选择好路径后,点击[next] 点击[install]安装 点击[finish]完成安装.安装完成后重启计算机. 2.客户端访问SVN服 ...

  2. json解析常见异常

    (1) : org.json.JSONException: Expected a ',' or '}' at 80 [character 81 line 1]   原因:出现乱码了, 导致json格式 ...

  3. English--音标拼读

    English|音标拼读 音标拼读主要内容是,如何使用音标进行单词的拼读,并且会有相应的语音现象,最关键的还是自己多加练习,多听~ 前言 目前所有的文章思想格式都是:知识+情感. 知识:对于所有的知识 ...

  4. 用chrome的snippets片段功能创建页面js外挂程序,从控制台创建js小脚本

    用chrome的snippets片段功能创建页面js外挂程序,从控制台创建js小脚本 Chrome的snippets是小脚本,还可以创作并在Chrome DevTools的来源面板中执行.可以访问和从 ...

  5. 基础系列(1)-- html

    (随笔杂谈,自己做的笔记) 网页的组成 结构  ------  xhtml,xml 表现  ------  css 行为  ------  bom,dom,ECMAScript html5结构 < ...

  6. 监控微信小程序中的慢HTTP请求

    摘要: 请求时间太长,影响用户体验,使用 Fundebug 监控慢请求. Fundebug 的微信小程序监控插件在 0.5.0 版本已经支持监控 HTTP 请求错误,在小程序中通过wx.request ...

  7. 0,'0','\0',NULL的区别

    0,'0','\0',NULL的区别 1,0是一个值,可以是char ,int ,float,double等类型: 2,'0'是一个字符(char)类型,它的ASCII码值是48: 3,'\0'也是一 ...

  8. Linux下getopt()函数

    from https://www.cnblogs.com/qingergege/p/5914218.html 最近在弄Linux C编程,本科的时候没好好学啊,希望学弟学妹们引以为鉴. 好了,虽然啰嗦 ...

  9. eclipse IDE 32位汉化方法及常用软件汉化包寻找办法

    今天听说小组开发人员遇到安装eclipse不能汉化问题.了解到其他同事用的都是64位操作系统,这个同事用的32位系统.通常情况下常用软件都有各路大神发的成熟汉化包,不会出现无法安装汉化包的情况. 先找 ...

  10. sublimeText3和phpstrom使用

    一.sublimtext3 下载地址:http://www.sublimetext.com/3 1.1      安装package control 插件,用来获取和管理插件(sublime包管理工具 ...