饱和转换【OpenCV_C++_VS】
·
2.3.4饱和转换
在 OpenCV 中,饱和转换是一种重要的操作,它主要用于处理图像像素值在进行算术运算时超出数据类型表示范围的情况。当进行如加法、减法等操作时,像素值可能会超出其数据类型所能表示的最大值或最小值,饱和转换会确保像素值被限制在该数据类型的有效范围内,避免出现数据溢出导致的异常结果。
1.原理
不同的数据类型有不同的取值范围,例如:
uint8类型的取值范围是0 - 255。int16类型的取值范围是-32768 - 32767。
当进行算术运算时,如果结果超出了这个范围,饱和转换会将结果限制在该范围内。例如,对于 uint8 类型,如果运算结果小于 0,则将其设为 0;如果结果大于 255,则将其设为 255。
2.代码示例
在 C++ 里使用 OpenCV 进行图像像素运算时,也会遇到像素值超出数据类型范围的情况。OpenCV 提供了专门的函数来处理这种情况,通过饱和转换保证像素值处于数据类型允许的范围之内。例如对于CV_8U(等同于uint8)类型,其范围是0 - 255,当运算结果超出这个范围时,会将结果限制在这个区间内。
#include <opencv2/opencv.hpp>
#include <iostream>
int main() {
// 创建两个单通道的 1x1 图像
cv::Mat image1(1, 1, CV_8U, cv::Scalar(200));
cv::Mat image2(1, 1, CV_8U, cv::Scalar(100));
// 普通加法(会发生溢出)
cv::Mat normalAddition = image1 + image2;
std::cout << "普通加法结果: " << static_cast<int>(normalAddition.at<uchar>(0, 0)) << std::endl;
// 饱和加法(使用 cv::add 函数)
cv::Mat saturatedAddition;
cv::add(image1, image2, saturatedAddition);
std::cout << "饱和加法结果: " << static_cast<int>(saturatedAddition.at<uchar>(0, 0)) << std::endl;
return 0;
}
3.代码解释
-
包含必要的头文件
opencv2/opencv.hpp:这是 OpenCV 的主要头文件,包含了 OpenCV 库的所有功能。iostream:用于标准输入输出操作,方便我们输出结果。
-
创建图像矩阵
- 使用
cv::Mat类创建两个单通道的1x1图像image1和image2,数据类型为CV_8U(即uint8)。分别初始化为200和100。
- 使用
-
普通加法
- 直接使用
+运算符对两个cv::Mat对象进行加法运算。由于200 + 100 = 300超出了CV_8U类型的范围0 - 255,会发生溢出,结果将是300 % 256 = 44。 - 通过
at<uchar>(0, 0)访问矩阵中唯一的像素值,并使用static_cast<int>将其转换为整数进行输出。
- 直接使用
-
饱和加法
- 使用
cv::add函数进行饱和加法运算,该函数会自动处理溢出情况。 - 结果存储在
saturatedAddition矩阵中,最终将结果输出。由于结果超出了255,会被限制为255。
- 使用
普通加法 饱和加法 原理分析 普通加法直接对两个数值进行相加操作,不考虑数据类型的取值范围。当相加结果超出数据类型所能表示的最大值时,会发生溢出,结果会以数据类型的取值范围为模进行循环。例如,对于 uint8类型(取值范围是0 - 255),如果两个数相加结果为300,由于300 % 256 = 44,最终结果就会是44。饱和加法在进行加法运算时,会考虑数据类型的取值范围。当相加结果超出数据类型的最大值时,会将结果限制为该最大值;当结果小于数据类型的最小值时,会将结果限制为该最小值。例如,对于 uint8类型,如果相加结果大于255,则结果为255;如果结果小于0,则结果为0。应用场景
一般在不需要考虑数据溢出问题,或者后续有专门的处理机制来处理溢出结果时使用。例如,在某些算法中,可能会将数据类型扩大以避免溢出,然后再进行后续处理。 在图像处理中更为常用,因为它可以保证像素值始终在合理的范围内,避免图像出现异常的像素值。例如,在图像融合、亮度调整等操作中,饱和加法可以使图像的处理结果更加自然。
4.编译和运行
假设你已经安装好了 OpenCV 库,将上述代码保存为main.cpp,可以使用以下命令进行编译:
g++ main.cpp -o main `pkg-config --cflags --libs opencv4`
运行生成的可执行文件:
./main
5.其他饱和转换函数
除了
cv::add,OpenCV 还提供了其他用于饱和转换的函数:
cv::subtract:用于饱和减法运算。cv::multiply:用于饱和乘法运算。cv::divide:用于除法运算。使用方法和
cv::add类似,例如:cv::Mat subtracted; cv::subtract(image1, image2, subtracted);
补充:saturate_cast<>函数根据目标数据类型的取值范围,对输入的数值进行检查和调整:
- 如果输入值小于目标数据类型的最小值,则返回该最小值。
- 如果输入值大于目标数据类型的最大值,则返回该最大值。
- 如果输入值在目标数据类型的取值范围内,则直接返回该值。
通过这些函数,可以安全地对图像进行各种算术运算,避免数据溢出带来的问题。
更多推荐

所有评论(0)