数字图像处理中,其数据类型一般为无符号类型,实际计算过程中会经常出现数据溢出现象,在无符号数据中如果其值出现小于0 则称之为向下溢出underflow,当计算结果大于其该数据类型能表示的最大值时称之为overflow时,比如 当为符号8位一个字节时,如果计算结果出现小于0 则称为underfow,计算结果大于0,称为overflow.

在实际的C/C++语言中,对于无符号类型,其出现反转时,将会按照循环处理反转重新计数。

比如一个 uchar类型 设Vxy 为10 则表达式((10 - 128) * 2 + 128) 中(10 - 128)会被重新认为是有符号,最终结果为-108,如果将其结果重新赋值给uchar将会发生反转,从0开始反转重新计算其结果为(-108+256)=148.

如果Vxy+255重新反转计算结果还是10.

uchar Vxy = 10;uchar result = ((10 - 128) * 2 + 128);
char result3 = (Vxy + 256);printf("result: %d\n", result);
printf("result2: %d\n", result2);
printf("result3: %d\n", result3);

结果为:

result: 148
result3: 10

上述场景在opencv中称之为saturation casting,在图像算法结果中数值的结果溢出造成反转会对实际结果造成影响,比如会造成图像过亮影响实际计算结果。

opencv支持cv::saturate_cast<>(),来解决数据溢出问题,当数据出现underflow时,其结果不反转直接取该数据类型支持的最小值,当数据出现overflow时,结果直接去该数据类型最大值,比如:

uchar Vxy = 10;uchar result2 = cv::saturate_cast<uchar>((Vxy - 128) * 2 + 128);
uchar result4 = cv::saturate_cast<uchar>((Vxy + 256));printf("result2: %d\n", result2);
printf("result4: %d\n", result4);

结果:

result2: 0
result4: 255

saturate_cast在算法中都非常有用,比如改变图像的亮度和对比度,其公式如下:

当a和b过大时很容易造成其计算结果溢出,造成图像过亮:

用例,使用lena图像,通过调整对比度和亮度:

#include <stdio.h>
#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"using namespace cv;
using namespace std;int  g_nContrastValue;
int g_nBrightValue;
Mat g_srcImage, g_dstImage;static void on_ContrastAndBright(int, void*) {namedWindow("【原始图像窗口】", 1);for (int y = 0; y < g_srcImage.rows; y++){for (int x = 0; x < g_srcImage.cols; x++){for (int c = 0; c < 3; c++){g_dstImage.at<Vec3b>(y, x)[c] = saturate_cast<uchar>((g_nContrastValue*0.01)*(g_srcImage.at<Vec3b>(y, x)[c]) + g_nBrightValue);}}}imshow("【原始图像窗口】", g_srcImage);imshow("【效果图窗口】", g_dstImage);
}void main()
{g_srcImage = imread("len_top.jpg");int alpha = 10;int gama = 10;//imshow("Src", g_srcImage);//waitKey(0);g_dstImage = Mat::zeros(g_srcImage.size(), g_srcImage.type());g_nContrastValue = 80;g_nBrightValue = 80;namedWindow("【效果图窗口】", 1);createTrackbar("对比度:", "【效果图窗口】", &g_nContrastValue, 300, on_ContrastAndBright);createTrackbar("亮  度:", "【效果图窗口】", &g_nBrightValue, 200, on_ContrastAndBright);on_ContrastAndBright(g_nContrastValue, 0);on_ContrastAndBright(g_nBrightValue, 0);while (char(waitKey(1)) != 'q') {}
}

原图为:

默认对比度和亮度都是80,其效果图:

对比度为163和亮度为138时,可以看到很多部分都已经变白,其实很多数据有已经溢出,其值变为了255,达到了最亮

不使用 saturate_cast功能对数据溢出进行截取时,其用例为:

#include <stdio.h>
#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"using namespace cv;
using namespace std;int  g_nContrastValue;
int g_nBrightValue;
Mat g_srcImage, g_dstImage;static void on_ContrastAndBright(int, void*) {namedWindow("【原始图像窗口】", 1);for (int y = 0; y < g_srcImage.rows; y++){for (int x = 0; x < g_srcImage.cols; x++){for (int c = 0; c < 3; c++){g_dstImage.at<Vec3b>(y, x)[c] = ((g_nContrastValue*0.01)*(g_srcImage.at<Vec3b>(y, x)[c]) + g_nBrightValue);}}}imshow("【原始图像窗口】", g_srcImage);imshow("【效果图窗口】", g_dstImage);
}void main()
{g_srcImage = imread("len_top.jpg");int alpha = 10;int gama = 10;//imshow("Src", g_srcImage);//waitKey(0);g_dstImage = Mat::zeros(g_srcImage.size(), g_srcImage.type());g_nContrastValue = 80;g_nBrightValue = 80;namedWindow("【效果图窗口】", 1);createTrackbar("对比度:", "【效果图窗口】", &g_nContrastValue, 300, on_ContrastAndBright);createTrackbar("亮  度:", "【效果图窗口】", &g_nBrightValue, 200, on_ContrastAndBright);on_ContrastAndBright(g_nContrastValue, 0);on_ContrastAndBright(g_nBrightValue, 0);while (char(waitKey(1)) != 'q') {}
}

对比度为123和亮度为80时,其数据已经出现溢出,此时图形已经不对:

可以看到使用cv::saturate_cast<>()对数据进行截取,可以有效防止数据溢出造成图像显示失真问题

OpenCV防止数据溢出saturate_cast相关推荐

  1. 【opencv-c++】cv::saturate_cast<uchar>防止数据溢出

    [opencv-c++]cv::saturate_cast防止数据溢出 1.背景 2.示例 1.背景 在图像像素的算术操作的过程中,我们会观察到颜色溢出的问题. 通常会使用cv::saturate_c ...

  2. OpenCV—矩阵数据类型转换cv::convertTo

    OpenCV-矩阵数据类型转换cv::convertTo 函数 [cpp] view plaincopy void convertTo( OutputArray m, int rtype, doubl ...

  3. access 一亿条数据_循环运算数据溢出

    本文讲解了循环运算时数据溢出的解决方法. 对于循环语句在运行过程中数据溢出,可以用下面一行代码搞定. DAO.DBEngine.SetOption dbMaxLocksPerFile, 9999999 ...

  4. OpenCV图像数据访问,查询表和时间消耗测试

    OpenCV图像数据访问, 查询表和时间消耗测试 代码示例 #include <opencv2/core.hpp> #include <opencv2/core/utility.hp ...

  5. c语言变量名必须用小写 常量用大写,day02 -C语言 常量 变量 数据类型 进制转换 数据溢出...

    常量 - 不会变化的数据 "hello" 'A' 10 3.14 #define PI 3.14 //采用宏定义的方法 定义一个常量 const int a = 10; 求圆的面积 ...

  6. java编程数据溢出问题_Java数据溢出代码详解

    Java数据溢出代码详解 发布时间:2020-10-05 15:08:31 来源:脚本之家 阅读:103 作者:Pony小马 java是一门相对安全的语言,那么数据溢出时它是如何处理的呢? 看一段代码 ...

  7. JAVA中整数类型数据溢出问题研究

    Java中的数值类型都是有符号类型,最高位表示符号位.这里我们以byte类型为例,探讨整型的数据溢出问题. 基本数据类型 对应的包装类 所占bit位 取值范围 byte Byte 8 -2^7 ~ 2 ...

  8. java 数据溢出和编译错误的差别

    int a=100000000000;编译错误,超出int范围 int a=2100000000; int b=a*12020200;数据溢出,a并未溢出,但b在通过a计算后的数据溢出 long e= ...

  9. 【C语言】Pillow(数据溢出问题)

    nxx床上有n个抱枕,而他的床长为x, 宽为y, 假设这n个抱枕均为长方体,给出每个抱枕的长宽高,抱枕可以以任意一个面为底摆放.摆放完所有抱枕后,问nxx床上最多还剩多少面积的地方能让他睡觉 .数据保 ...

最新文章

  1. 你知道吗?OAuth2客户端有两种,认证方式有七种。
  2. c++类对象的创建方式
  3. ios 跨域_如何在iOS和Android中建立跨域通信桥
  4. ionic2/cordova自定义插件集成aar包
  5. i=i+1,i+=1与i++的区别
  6. C++14::lambda函数的类型
  7. 北京python程序员求职_想找python程序员的工作,但发现稍微好点的职位都集中在北京。我非常想当python程序员,北京值得去吗?...
  8. Java集合框架总结
  9. Flask知识点串烧(三)--- JInjia2模板
  10. LaiCode 376. Ascending Triple I
  11. Bootstrap可视化布局系统
  12. linux学习课程从入门到精通:Linux基本操作和服务器硬件选购指南
  13. 微信小程序写动画 一闪一闪亮晶晶
  14. MySQL常见错误:Starting MySQL...The server quit without updating PID file (/usr/local/mysql/data/localhos
  15. jsp无图片时显示默认图片解决方案
  16. QML实现闹钟的时间选择器
  17. 植物神经紊乱的影响,你知道有哪些吗?
  18. mysql 主备切换关于虚拟ip理解
  19. 循环队列 (顺序存储)
  20. 软件工程复试——十三、软件项目管理

热门文章

  1. JEECG新版UI规划,主要提供H5方案(采用主流技术)
  2. 【jeecg移动开发能力】Jeecg 重磅来袭,强大移动报表配置能力,一次配置七种展现风格
  3. 安装 Nexus——war版本
  4. UI标签库专题一:JEECG智能开发平台 BaseTag(样式表和JS引入标签)
  5. java批量执行多条Sql语句
  6. SpringBoot2.0 基础案例(10):整合Mybatis框架,集成分页助手插件
  7. Eclipse使用总结【更新中】
  8. --专访雷果国: 从1.5K到18K 一个程序员的5年成长之路--
  9. 技术专家:为什么我们最终选择Apache Pulsar替代Kafka?
  10. 2019.5.18-5.19 ACM-ICPC 全国邀请赛(西安)赛后总结