原文:

http://blog.csdn.net/skeeee/article/details/20471949

1.简述

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

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

2.结构体及函数定义

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

/************************************************************************/
/*创建一个互斥集,尺寸为n%参数 int n,输入互斥集的尺寸
*/
/************************************************************************/
void DisjointSets::createOneElemSets(int n)
{rank_.assign(n, 0);//设置rank_长度为n,初始值为0size.assign(n, 1);//设置size长度为n,初始值为1parent.resize(n);//设置parent的长度为nfor (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_值+1parent[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);}

输出结果:

全景视频拼接(三)--并查集法及源码分析相关推荐

  1. Android10.0 日志系统分析(三)-logd、logcat读写日志源码分析-[Android取经之路]

    摘要:本节主要来讲解Android10.0 logd.logcat读写日志源码内容 阅读本文大约需要花费20分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Andro ...

  2. Java类集框架 —— LinkedList源码分析

    在JDK1.7之前,LinkedList是采用双向环形链表来实现的,在1.7及之后,Oracle将LinkedList做了优化,将环形链表改成了线性链表.本文对于LinkedList的源码分析基于JD ...

  3. Redis集群模式源码分析

    目录 1 主从复制模式 2 Sentinel(哨兵)模式 3 Cluster模式 4.参考文档 1 主从复制模式 主库负责读写操作,从库负责数据同步,接受来自主库的同步命令.通过分析Redis的客户端 ...

  4. Java类集框架 —— LinkedHashMap源码分析

    前言 我们知道HashMap底层是采用数组+单向线性链表/红黑树来实现的,HashMap在扩容或者链表与红黑树转换过程时可能会改变元素的位置和顺序.如果需要保存元素存入或访问的先后顺序,那就需要采用L ...

  5. Java的三种代理模式【附源码分析】

    Java的三种代理模式&完整源码分析 代理模式分为两种,静态代理和动态代理,动态代理包括JDK动态代理和Cglib动态代理. 静态代理 静态代理在使用时,需要定义接口或者父类,被代理对象与代理 ...

  6. Bytom Dapp 开发笔记(三):Dapp Demo前端源码分析

    本章内容会针对比原官方提供的dapp-demo,分析里面的前端源码,分析清楚整个demo的流程,然后针对里面开发过程遇到的坑,添加一下个人的见解还有解决的方案. 储蓄分红合约简述 为了方便理解,这里简 ...

  7. Java类集框架 —— HashMap源码分析

    HashMap是基于Map的键值对映射表,底层是通过数组.链表.红黑树(JDK1.8加入)来实现的. HashMap结构 HashMap中存储元素,是将key和value封装成了一个Node,先以一个 ...

  8. Kylin源码分析系列三—rowKey编码

    Kylin源码分析系列三-rowKey编码 注:Kylin源码分析系列基于Kylin的2.5.0版本的源码,其他版本可以类比. 1. 相关概念 前面介绍了Kylin中Cube构建的流程,但Cube数据 ...

  9. 一种基于FPGA 的1080p 高清多摄像头全景视频拼接的泊车(机)

    < > 一种基于FPGA 的1080p 高清多摄像头全景视频拼接的泊车(机)实时影像系统 一.本发明要解决的实际问题 1. 汽车左右反光镜及后视镜的视角有限,导致车身周围存在盲区,在特殊驾 ...

最新文章

  1. tensorflow-tensorboard 0.4.0rc3 has requirement bleach==1.5.0, but you'll have bleach 2.0.0 which is
  2. dma访问主存时_STM32F103单片机(五)——DMA
  3. jsp页面内引入静态html,JSP技术实现动态页面到静态页面的方法
  4. Swift @escaping @noescape
  5. msg_p!=(void*) 0 --消息邮箱(点滴学习)
  6. linux下VScode开发ESP32,VsCode设置ESP32工具链+刨根问底点灯
  7. mysql 升序_MySQL“自古以来”都有一个神秘的HANDLER命令
  8. 「管理数学基础」3.3 凸分析:凸函数的极值和凸规划
  9. .NET Micro Framework开发板用户简明手册(v3.0)
  10. 【iOS越狱开发】如何将应用打包成.ipa文件
  11. 【数学建模】基于matlab计划生育政策调整对人口数量、结构及其影响的研究【含Matlab源码 749期】
  12. 系统中 用户操作日志管理
  13. LaTeX 常用符号命令大全
  14. python使用给定字符密码_使用python生成一个指定长度的字符串(随机密码),要求包括数字、字母、特殊符号(string库解析)...
  15. 【歌词】ASIAN KUNG-FU GENERATION - ムスタング(mix for 芽衣子)
  16. 如何判断一个PCIe的capability是哪个capability
  17. 计算机网络第三章数据链路层习题答案
  18. Vue中实现图片下载到本地功能和导出(下载)excel文件功能:
  19. Karl Klein 2D 56 K30-2 W OL/S 45W/2750RPM
  20. “希希敬敬对”团队作业——敏捷冲刺6

热门文章

  1. Ubunbtu18.04报错:No rule to make target ‘kernel/include/linux/netfilter/xt_CONNMARK.h‘
  2. Android O HIDL的使用例子 -- 蓝牙HCI 服务进程
  3. UE4之wgs84坐标系
  4. 深度学习自学(七):腾讯移动端开源框架ncnn学习总结
  5. linux的多任务编程-线程池,Linux的多任务编程-线程池
  6. linux发布成服务,linux服务简单部署
  7. windows bat脚本编写_怎样在 txt 中用 2 行代码写出一个锁屏休息提醒脚本?
  8. python unicode函数_python 中的unicode详解
  9. 你可以退部的,不必说抱歉
  10. springBoot 注入@Slf4j,框架中的方法无法调用。。。