Stitching模块中leaveBiggestComponent初步研究

简介: 在Stitching模块中以及原始论文《Automatic Panoramic Image Stitching using Invariant Features》3.2中,都有“根据已经匹配好的特征对,判断哪些图片是属于序列,那些图片是不属于序列”的这一步操作。
在Stitching模块中以及原始论文《Automatic Panoramic Image Stitching using Invariant Features》3.2中,都有“根据已经匹配好的特征对,判断哪些图片是属于序列,那些图片是不属于序列”的这一步操作。
论文解释为:
  img_b8a721aaba830f310fd4d38b147ca782.png

img_1896cf9f45fbf4a0d989f871203090a3.png

对应的函数为:
std::vector<int> leaveBiggestComponent(std::vector<ImageFeatures> &features,  std::vector<MatchesInfo> &pairwise_matches,float conf_threshold)
{
    const int num_images = static_cast<int>(features.size());
    DisjointSets comps(num_images);
    for (int i = 0; i < num_images; ++i)
    {
        for (int j = 0; j < num_images; ++j)
        {
            if (pairwise_matches[i*num_images + j].confidence < conf_threshold)
                continue;
            int comp1 = comps.findSetByElem(i);
            int comp2 = comps.findSetByElem(j);
            if (comp1 != comp2)
                comps.mergeSets(comp1, comp2);
        }
    }
    int max_comp = static_cast<int>(std::max_element(comps.size.begin(),comps.size.end()) - comps.size.begin());
    std::vector<int> indices;
    std::vector<int> indices_removed;
    for (int i = 0; i < num_images; ++i)
        if (comps.findSetByElem(i) == max_comp)
            indices.push_back(i);
        else
            indices_removed.push_back(i);
    std::vector<ImageFeatures> features_subset;
    std::vector<MatchesInfo> pairwise_matches_subset;
    for (size_t i = 0; i < indices.size(); ++i)
    {
        features_subset.push_back(features[indices[i]]);
        for (size_t j = 0; j < indices.size(); ++j)
        {
            pairwise_matches_subset.push_back(pairwise_matches[indices[i]*num_images + indices[j]]);
            pairwise_matches_subset.back().src_img_idx = static_cast<int>(i);
            pairwise_matches_subset.back().dst_img_idx = static_cast<int>(j);
        }
    }
    if (static_cast<int>(features_subset.size()) == num_images)
        return indices;
    LOG("Removed some images, because can't match them or there are too similar images: (");
    LOG(indices_removed[0+ 1);
    for (size_t i = 1; i < indices_removed.size(); ++i)
        LOG(", " << indices_removed[i]+1);
    LOGLN(").");
    LOGLN("Try to decrease the match confidence threshold and/or check if you're stitching duplicates.");
    features = features_subset;
    pairwise_matches = pairwise_matches_subset;
    return indices;
}
leaveBiggestComponent的主要目的可以描述为“寻找所有配对中肯定属于一幅全景图像的图片”,主要通过的方法是“并查集”
那什么是“并查集”了? 举个简单应用的例子。现在社交网站这么流行,假设现在想知道两个人之间是否存在间接好友关系(A和B为好友,B和C为好友,A和C为间接好友),有什么好方法呢?并查集就是用于这类查询问题的有效 数据结构 ,正如其名(disjoint set),并查集本质上是一个集合,集合的元素为树,因此并查集实际上表示了一个森林(disjoint-set forests)。它的特点是每棵树中的成员都可由根结点所代表,这样要知道两个结点是否属于集合的同一元素,只要看它们是否有同一“代表”。
为此,搜集资料,编写代码
#include "stdafx.h"
#include "opencv2/opencv_modules.hpp"
#include <opencv2/core/utility.hpp>
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/stitching/detail/autocalib.hpp"
#include "opencv2/stitching/detail/blenders.hpp"
#include "opencv2/stitching/detail/timelapsers.hpp"
#include "opencv2/stitching/detail/camera.hpp"
#include "opencv2/stitching/detail/exposure_compensate.hpp"
#include "opencv2/stitching/detail/matchers.hpp"
#include "opencv2/stitching/detail/motion_estimators.hpp"
#include "opencv2/stitching/detail/seam_finders.hpp"
#include "opencv2/stitching/detail/warpers.hpp"
#include "opencv2/stitching/warpers.hpp"
#define  conf_threshold 90  
#define  num_images 10  
using namespace std;
using namespace cv;
using namespace cv::detail;
void 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);  
}  
其中相关函数解释:
 comps.mergeSets(comp1, comp2); 
是将comp1和comp2合并起来。
最后得到的,就是在目前情况下,最大可能的符合条件的序列组合。
解析:
这里的理解可能有一些困难,关键是要把握在运算前有什么,运算后有什么?
在运算前,我们得到的是一个矩阵,那就是N*N的图片序列中,每一个图片和其他N-1个图片之间的特征匹配关系,也包括确信值
img_0d5c5250d5fbd70e64d3f558d59a197a.png
运算之后,需要获得的是在这些所有的关系中,所有对都符合条件的,但是相互之间不想交的对的集合。并且把最大的那个打印出来。

 




目前方向:图像拼接融合、图像识别 联系方式:jsxyhelu@foxmail.com
目录
相关文章
|
6月前
|
机器学习/深度学习 人工智能 测试技术
11种开源即插即用模块汇总 !!(附论文和代码)
11种开源即插即用模块汇总 !!(附论文和代码)
384 1
|
2月前
|
安全
工业机理模型的构建
工业机理模型的构建
62 7
|
4月前
|
机器学习/深度学习 人工智能
IBM推出创新框架用“黑盒”方式,评估大模型的输出
【7月更文挑战第17天】IBM研发的创新框架以“黑盒”方法评估大模型输出的可信度,通过观察输入和输出,不涉及模型内部。采用逻辑回归模型,基于四个特征(输出长度、多样性、一致性和新颖性)来估计可信度。在多个数据集上测试,显示优于其他“黑盒”方法,且具有可解释性。但仅适用于可访问的模型,可能忽略内部细节,不适用于所有场景。[[arXiv:2406.04370](https://arxiv.org/abs/2406.04370)]
55 4
|
3月前
|
机器学习/深度学习 算法 PyTorch
PyTorch Lightning:简化研究到生产的工作流程
【8月更文第29天】深度学习项目往往面临着从研究阶段到生产部署的挑战。研究人员和工程师需要处理大量的工程问题,比如数据加载、模型训练、性能优化等。PyTorch Lightning 是一个轻量级的封装库,旨在通过减少样板代码的数量来简化 PyTorch 的使用,从而让开发者更专注于算法本身而不是工程细节。
92 1
|
5月前
|
机器学习/深度学习 JSON 测试技术
CNN依旧能战:nnU-Net团队新研究揭示医学图像分割的验证误区,设定先进的验证标准与基线模型
在3D医学图像分割领域,尽管出现了多种新架构和方法,但大多未能超越2018年nnU-Net基准。研究发现,许多新方法的优越性未经严格验证,揭示了验证方法的不严谨性。作者通过系统基准测试评估了CNN、Transformer和Mamba等方法,强调了配置和硬件资源的重要性,并更新了nnU-Net基线以适应不同条件。论文呼吁加强科学验证,以确保真实性能提升。通过nnU-Net的变体和新方法的比较,显示经典CNN方法在某些情况下仍优于理论上的先进方法。研究提供了新的标准化基线模型,以促进更严谨的性能评估。
161 0
|
6月前
|
监控 数据挖掘
项目组合研究的问题
项目组合管理聚焦于组织如何高效管理多个项目以达成战略目标,在资源有限时最大化整体价值。关键问题包括:战略一致性(确保项目与组织战略匹配,选择驱动战略的项目)、优先级排序(基于标准确定项目优先级,权衡收益、风险和成本)、资源配置(合理分配有限资源,平衡项目需求和优化利用率)、风险管理(识别和管理项目风险,制定应对策略)、绩效监控(建立绩效指标体系,定期审查和调整组合)、决策支持工具(使用工具和技术进行数据分析和决策)、治理结构(设计适应组织的治理框架和决策流程)以及动态调整能力(灵活应对市场变化,基于实时信息调整项目组合)。需进一步研究与项目集管理的区别。【4月更文挑战第2天】
41 1
|
6月前
|
监控
项目集研究的问题
研究项目集管理时,关注点包括:战略一致性,确保项目目标与组织战略对齐;治理结构,建立协调利益相关者的机制;集成管理,跨项目整合资源,处理内部依赖;收益管理,量化投资回报并监控收益;风险管理,识别并降低重大风险;资源优化,有效分配有限资源;沟通与协作,保障信息传递和团队协作;以及绩效衡量与报告,设置KPIs并提供透明的进展报告。
36 1
|
6月前
|
存储 人工智能 JSON
【AI大模型应用开发】【LangChain系列】3. 一文了解LangChain的记忆模块(理论实战+细节)
本文介绍了LangChain库中用于处理对话会话记忆的组件。Memory功能用于存储和检索先前的交互信息,以便在对话中提供上下文。目前,LangChain的Memory大多处于测试阶段,其中较为成熟的是`ChatMessageHistory`。Memory类型包括:`ConversationBufferMemory`(保存对话历史数组)、`ConversationBufferWindowMemory`(限制为最近的K条对话)和`ConversationTokenBufferMemory`(根据Token数限制上下文长度)。
354 0
|
机器学习/深度学习 自然语言处理 算法
【网安AIGC专题10.25】论文7:Chatgpt/CodeX引入会话式 APR 范例+利用验证反馈+LLM 长期上下文窗口:更智能的反馈机制、更有效的信息合并策略、更复杂的模型结构、鼓励生成多样性
【网安AIGC专题10.25】论文7:Chatgpt/CodeX引入会话式 APR 范例+利用验证反馈+LLM 长期上下文窗口:更智能的反馈机制、更有效的信息合并策略、更复杂的模型结构、鼓励生成多样性
142 0
|
传感器 自动驾驶 测试技术
Study | 激光雷达性能如何统一量化?标准化测试最新研究发布
Study | 激光雷达性能如何统一量化?标准化测试最新研究发布
149 0
下一篇
无影云桌面