- 操作系統:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 編程語言:C++11
算法描述
cv::detail::MultiBandBlender 是 OpenCV 中用于圖像拼接(stitching)模塊的一個類,主要用于將多張重疊的圖像無縫地融合成一張全景圖。它實現了多頻帶融合算法,通過分解圖像的頻率成分來實現平滑的過渡效果。
主要功能與概念
-
多頻帶融合(Multi-Band Blending)
該算法將圖像分解為多個頻率帶(使用高斯金字塔和拉普拉斯金字塔)。
對每個頻率帶分別進行融合,然后重新組合成最終圖像。
這種方法可以有效減少拼接區域的可見接縫,并處理亮度差異。 -
融合流程
準備輸入圖像及其掩碼。
將圖像和掩碼送入融合器。
執行融合并生成最終結果。
常用成員函數
- 構造函數
cv::detail::MultiBandBlender(bool try_gpu = false);
- 參數:
try_gpu: 如果為 true,嘗試使用 GPU 加速(如果可用)。默認值為 false。
- 準備函數
void prepare(cv::Rect dst_roi);
- 用途: 初始化融合器,設置目標圖像的感興趣區域(ROI)。
- 參數:
dst_roi: 目標圖像中需要融合的區域。
- 添加圖像
void feed(const cv::Mat& img, const cv::Mat& mask, cv::Point tl);
- 用途: 向融合器中添加圖像及其掩碼。
- 參數:
img: 輸入圖像。
mask: 圖像的有效區域掩碼。
tl: 圖像在最終全景圖中的左上角位置。
- 執行融合
void blend(cv::Mat& dst, cv::Mat& dst_mask);
- 用途: 執行實際的融合操作,并輸出結果。
- 參數:
dst: 輸出的融合圖像。
dst_mask: 輸出的融合掩碼。
代碼示例
#include <opencv2/opencv.hpp>
#include <opencv2/stitching/detail/blenders.hpp>int main()
{// 創建 MultiBandBlender 對象cv::Ptr< cv::detail::MultiBandBlender > blender = cv::makePtr< cv::detail::MultiBandBlender >();// 加載圖像cv::Mat img1 = cv::imread( "/media/dingxin/data/study/OpenCV/sources/images/stich1.png" );cv::Mat img2 = cv::imread( "/media/dingxin/data/study/OpenCV/sources/images/stich2.png" );if ( img1.empty() || img2.empty() ){std::cerr << "Error: Failed to load images!" << std::endl;return -1;}// 調試:單獨顯示原始圖像cv::imshow( "Image1", img1 );cv::imshow( "Image2", img2 );// 確保為三通道if ( img1.channels() != 3 ){cv::cvtColor( img1, img1, cv::COLOR_GRAY2BGR );}if ( img2.channels() != 3 ){cv::cvtColor( img2, img2, cv::COLOR_GRAY2BGR );}// 創建掩碼cv::Mat mask1 = cv::Mat::ones( img1.size(), CV_8UC1 ) * 255;cv::Mat mask2 = cv::Mat::ones( img2.size(), CV_8UC1 ) * 255;// 設置ROI(假設兩圖水平拼接)int roi_width = img1.cols + img2.cols;int roi_height = std::max( img1.rows, img2.rows );cv::Rect roi( 0, 0, roi_width, roi_height );blender->prepare( roi );// 輸入圖像到融合器blender->feed( img1, mask1, cv::Point( 0, 0 ) ); // 左圖blender->feed( img2, mask2, cv::Point( img1.cols, 0 ) ); // 右圖// 融合cv::Mat result, result_mask;blender->blend( result, result_mask );// 處理結果if ( result.empty() ){std::cerr << "Error: Blending failed!" << std::endl;return -1;}if ( result.depth() == CV_32F ){result.convertTo( result, CV_8UC3, 255.0 ); // 轉為8位三通道}// 顯示和保存cv::imwrite( "panorama2.jpg", result );cv::Mat result_8u;result.convertTo( result_8u, CV_8U ); // 轉換為 8 位無符號整型?:ml-citation{ref="3,8" data="citationList"}cv::imshow( "全景圖", result_8u );cv::waitKey( 0 ); // 必須調用!return 0;
}
運行結果