- 操作系統: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)