- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
该算法将图像转换为中值阈值位图(Median Threshold Bitmap,MTB):
1.位图生成:
- 计算图像亮度中值作为全局阈值2
- 亮度高于中值的像素标记为1,否则标记为0,形成二值位图
2.位操作对齐:
- 通过位移(bit-shifting)和异或(XOR)等位运算对齐不同图像的MTB位图,计算最小差异偏移量
3.技术特性:
- 曝光不变性:基于中值阈值而非绝对亮度值,无需依赖曝光参数或相机响应曲线
- 边界处理:对齐后的新增区域默认填充0(黑色)
4.应用场景:
- 多曝光图像对齐(HDR成像预处理)
- 动态场景下的快速图像配准(如移动端摄影)
5.关联文献: - 详细实现参考论文 [290]
算法流程示意图
输入图像 → 2. 灰度化 → 3. 计算中值亮度 → 4. 生成MTB位图 → 5. 位运算对齐 → 6. 输出对齐结果
cv::AlignMTB 是 OpenCV 库中用于对齐不同曝光图像的具体实现类,它继承自 cv::AlignExposures 抽象基类。这个类利用基于中值阈值位图(Median Threshold Bitmap, MTB)的方法来对齐图像,这种方法不依赖于图像的亮度信息,因此非常适合用于高动态范围(HDR)成像中的曝光对齐。
主要功能
- 对齐曝光图像:cv::AlignMTB 能够处理一系列具有不同曝光设置的图像,并将它们对齐以便进行后续的 HDR 合成或其他处理。
接口概览
以下是 cv::AlignMTB 类的一些重要成员函数和属性:
构造函数
- AlignMTB(): 默认构造函数。
- AlignMTB(int max_bits, bool exclude_range, int cut): 带参数的构造函数,允许用户指定最大位数、是否排除中间亮度范围以及切割点。
成员函数 - void process(InputArrayOfArrays src_images, std::vector& dst_images, const std::vector& times, const Mat& response):
处理输入的图像序列并生成对齐后的输出图像。此函数覆盖了基类中的虚函数。
参数包括源图像序列、目标(对齐后)图像序列、每个图像的曝光时间列表以及相机响应函数。 - void computeBitmaps(const Mat& img, Mat& tb, Mat& eb) const:
计算给定图像的阈值位图(tb)和曝光位图(eb)。 - void align(const std::vector& src_images, std::vector& dst_images, std::vector& shifts) const:
对齐输入图像序列,并返回每张图像相对于第一张图像的位移。 - void calculateShift(const Mat& img0, const Mat& img1, Point& shift):
计算两张图像之间的位移。 - void shiftMat(const Mat& src, Mat& dst, const Point& shift):
根据给定的位移调整图像的位置。
属性
- int max_bits_:用于计算MTB的最大位数,默认为6。
- bool exclude_range_:是否排除中间亮度范围,默认为真。
- int cut_:切割点,用于决定如何分割亮度范围,默认为0。
代码示例
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/photo.hpp>
#include <vector>
using namespace cv;
using namespace std;
int main()
{
// 1. 读取不同曝光的图像序列
vector< Mat > images;
vector< String > img_paths = { "exposure1.jpg", "exposure2.jpg", "exposure3.jpg" };
for ( const auto& path : img_paths )
{
Mat img = imread( path );
if ( img.empty() )
{
cerr << "Error: 无法读取图像 " << path << endl;
return -1;
}
images.push_back( img );
}
// 2. 创建 AlignMTB 对齐器:ml-citation{ref="1" data="citationList"}
Ptr< AlignMTB > align = createAlignMTB();
vector< Mat > aligned_images;
// 3. 执行对齐操作:ml-citation{ref="1,3" data="citationList"}
align->process( images, aligned_images );
// 4. 显示原始图像和对齐结果:ml-citation{ref="2" data="citationList"}
for ( size_t i = 0; i < images.size(); ++i )
{
imshow( "原始图像 " + to_string( i ), images[ i ] );
imshow( "对齐结果 " + to_string( i ), aligned_images[ i ] );
}
waitKey( 0 );
destroyAllWindows();
return 0;
}
运行结果
感觉没啥变化呀