当前位置: 首页 > news >正文

OpenCV旋转估计(3)帮助构建一个最大生成树(Maximum Spanning Tree)函数findMaxSpanningTree()

  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

算法描述

cv::detail::findMaxSpanningTree 是 OpenCV 中用于图像拼接工作流的一个函数,它帮助构建一个最大生成树(Maximum Spanning Tree),这在图像拼接中用于确定图像之间的最佳连接方式。这个函数特别适用于处理多个图像间的匹配信息,并基于这些信息来构建一个图结构,从而为后续的图像拼接步骤提供基础。

函数原型

void cv::detail::findMaxSpanningTree 	
(
	 	int  	num_images,
		const std::vector< MatchesInfo > &  	pairwise_matches,
		Graph &  	span_tree,
		std::vector< int > &  	centers 
	) 	

参数

  • num_images: 图像的数量。
  • pairwise_matches: 包含每对图像之间匹配信息的向量。每个 MatchesInfo 结构体包含了两个图像之间的匹配点、置信度等信息。
  • span_tree: 输出参数,表示由函数计算得到的最大生成树。这个图结构描述了如何以最优的方式将所有图像连接起来。
  • centers: 输出参数,包含可能作为拼接中心的图像索引列表。在全景拼接中,通常选择一个或几个中心图像来开始拼接过程。

代码示例

#include <opencv2/opencv.hpp>
#include <opencv2/stitching/detail/matchers.hpp>
#include <opencv2/stitching/detail/util.hpp>

#include <iostream>
#include <vector>

using namespace cv;
using namespace cv::detail;

int main() {
    // 加载图像(此处仅作示意,实际应用中需要加载真实图像)
    std::vector<std::string> img_filenames = {
        "/media/dingxin/data/study/OpenCV/sources/images/left01.jpg",
        "/media/dingxin/data/study/OpenCV/sources/images/right01.jpg",
        "/media/dingxin/data/study/OpenCV/sources/images/right01.jpg"
    };

    std::vector<cv::Mat> imgs;
    for (const auto& filename : img_filenames) {
        cv::Mat img = cv::imread(filename);
        if (img.empty()) {
            std::cerr << "无法加载图像: " << filename << std::endl;
            return -1;
        }
        imgs.push_back(img);
    }

    // 初始化特征检测器和描述符提取器
    Ptr<Feature2D> detector = ORB::create();
    BestOf2NearestMatcher matcher(false, 0.3f);

    // 计算每张图像的特征点
    std::vector<ImageFeatures> features(imgs.size());
    for (size_t i = 0; i < imgs.size(); ++i) {
        detector->detectAndCompute(imgs[i], Mat(), features[i].keypoints, features[i].descriptors);
    }

    // 匹配特征点
    std::vector<MatchesInfo> pairwise_matches;
    matcher(features, pairwise_matches);

    // 构建最大生成树
    Graph span_tree;
    std::vector<int> centers;
    findMaxSpanningTree(imgs.size(), pairwise_matches, span_tree, centers);

    // 打印中心图像索引
    std::cout << "Centers: ";
    for (int center : centers) {
        std::cout << center << " ";
    }
    std::cout << std::endl;

    // 手动重建最大生成树的边
    std::vector<bool> visited(imgs.size(), false);
    for (int center : centers) {
        std::cout << "Starting from center: " << center << std::endl;
        visited[center] = true;
        for (size_t i = 0; i < pairwise_matches.size(); ++i) {
            const MatchesInfo& match_info = pairwise_matches[i];
            if (match_info.confidence > 0 && !visited[match_info.src_img_idx] && !visited[match_info.dst_img_idx]) {
                std::cout << "(" << match_info.src_img_idx << ", " << match_info.dst_img_idx << ")" << std::endl;
                visited[match_info.src_img_idx] = true;
                visited[match_info.dst_img_idx] = true;
            }
        }
    }

    return 0;
}

运行结果

Centers: 2 
Starting from center: 2
(0, 1)

相关文章:

  • 聊聊langchain4j的HTTP Client
  • 关于MTU的使用(TCP/IP网络下载慢可能与此有关)
  • HJ C++11 Day6
  • Spring事务管理
  • 数据仓库的 DWD 分层架构:构建高效数据平台的基石
  • 科技重构旗舰SUV:腾势N9上市38.98万起
  • C++红黑树实现
  • 深度学习2-线性回归表示
  • 【读书笔记】华为《从偶然到必然》
  • SMBus协议(二):与I2C协议的对比
  • 5、linux c 线程 - 上
  • 基于STM32的两路电压测量仿真设计Proteus仿真+程序设计+设计报告+讲解视频
  • 使用LVS的 NAT 模式实现 3 台RS的轮询访问
  • (学习总结30)Linux 进程优先级、进程切换和环境变量
  • 使用LLM 构建MCP服务端和客户端
  • 信息安全和病毒防护——防火墙的作用
  • SFT和RLHF是什么意思?
  • Axure项目实战:智慧城市APP(四)医疗信息(动态面板、选中交互应用)
  • Jboss中间件漏洞攻略
  • java学习笔记6
  • 被围观的“英之园”,谁建了潮汕天价违建?
  • 大陆非遗项目打铁花、英歌舞将在台演出
  • 泽连斯基:乌代表团已启程,谈判可能于今晚或明天举行
  • 中办、国办关于持续推进城市更新行动的意见
  • 上海静安将发放七轮文旅消费券,住宿券最高满800元减250元
  • 中国乒协坚决抵制恶意造谣,刘国梁21日将前往多哈参加国际乒联会议