【图像处理OpenCV(C++版)】——4.4 对比度增强之伽马变换
前言:
😊😊😊欢迎来到本博客😊😊😊
🌟🌟🌟 本专栏主要结合OpenCV和C++来实现一些基本的图像处理算法并详细解释各参数含义,适用于平时学习、工作快速查询等,随时更新。
😊😊😊 具体食用方式:可以点击本专栏【OpenCV快速查找(更新中)】–>搜索你要查询的算子名称或相关知识点,或者通过这篇博客👉通俗易懂OpenCV(C++版)详细教程——OpenCV函数快速查找(不断更新中)]查阅你想知道的知识,即可食用。
🎁🎁🎁支持:如果觉得博主的文章还不错或者您用得到的话,可以悄悄关注一下博主哈,如果三连收藏支持就更好啦!这就是给予我最大的支持!😙😙😙
学习目标
- 熟悉伽马变换概念及原理
- C++实现伽马变换案例
一、概念及原理
假设输入图像为I
,高为H
、宽为W
,伽马变换需要对输入图像进行归一化处理(对于8位图而言,除以255即可),I(r,c)
代表归一化后第r行第c列的灰度值,输出图像记作O(r,c)
。伽马变换原理如下:
![](https://img-blog.csdnimg.cn/9d2c369768cd4a4ca71d9da327b5998c.png)
r
为灰度图像的归一化后输入值,取值范围为[0,1]。s
为经过伽马变换后的灰度输出值。c
为灰度缩放系数,通常取1。γ
为伽马因子大小。控制了整个变换的缩放程度。如下图所示:
![](https://img-blog.csdnimg.cn/ad7434647fd04de8ad9f9fcf6d9c03a5.png)
当γ=1
时,图像不变。如果图像整体或者感兴趣区域较暗,则令0<γ<1
可以增加图像对比度;相反,如果图像整体或者感兴趣区域较亮,则令γ<1
可以降低图像对比度。
二、代码实现
OpenCV提供了函数,对每个值进行幂运算:
void pow(InputArray src,double power,OutputArray dst)
src:输入
power:指数值,即γ值
dst:输出,类型与输入一致
我们来看一个简单案例:
#include <iostream>
#include <opencv2/opencv.hpp>
# include <opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace std;
using namespace CV ;
int main() {
Mat I = (Mat_ <float>(2, 2) << 0,180, 120, 35) ;
Mat 0;
pow(I,2, 0) ;
cout<< "0:" << 0 << endl;
return 0;
![](https://img-blog.csdnimg.cn/781354f969734ea0bb735a648493b610.png)
因为I
的数据类型是CV_32F
,所以O
的数据类型也是CV_32F
,计算出来的值会超过255。
如果将I
的数据类型换成CV_8U
,代码如下:
#include <iostream>
#include <opencv2/opencv.hpp>
# include <opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace std;
using namespace CV ;
int main() {
Mat I = (Mat_ <uchar>(2, 2) << 0,180, 120, 35) ;
Mat 0;
pow(I,2, 0) ;
cout<< "0:" << 0 << endl;
return 0;
![](https://img-blog.csdnimg.cn/68feec8012fd4a129da15af45f44245b.png)
如果原矩阵是CV_8U
类型的,那么在进行幂运算时,大于255的值会自动截断为255。
如果想对图像进行伽马变换时,先将图像的灰度值归一化到[0,1]
范围,然后再进行幂运算。代码如下:
#include <iostream>
#include <opencv2/opencv.hpp>
# include <opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace std;
using namespace CV ;
int main() {
Mat I = imread("D:/VSCodeFile/OpenCV_CSDN/image/logo.jpeg",IMREAD_COLOR);
//归一化
Mat FI;
I.convertTo(FI,CV_64F,1.0/255,0)
//伽马变换
double gamma = 0.1;
Mat Out;
pow(FI,gamma,Out);//Out与FI有相同数据类型
//效果图展示
imshow("原图", I);
imshow("After Gamma",Out);
waitKey(0);
return 0;
}
![](https://img-blog.csdnimg.cn/aec98b14b27e4899bfdc059d5b712e09.png)
如果想本地保存O
,则还需要将灰度值变为在[0,255]
之间且转换为CV_8U
类型。如果没有数据类型转换,则直接保存浮点型的O
,这样虽然不会报错,但是保存后图像呈现黑色,看不到任何信息。代码如下:
#include <iostream>
#include <opencv2/opencv.hpp>
# include <opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace std;
using namespace CV ;
int main() {
Mat I = imread("D:/VSCodeFile/OpenCV_CSDN/image/logo.jpeg",IMREAD_COLOR);
//归一化
Mat FI;
I.convertTo(FI,CV_64F,1.0/255,0)
//伽马变换
double gamma = 0.1;
Mat Out;
pow(FI,gamma,Out);//Out与FI有相同数据类型
//效果图展示
imshow("原图", I);
imshow("After Gamma",Out);
//===================
imwrite("D:/VSCodeFile/OpenCV__CSDN/image/BeforeConvert_logo.jpeg", Out);
Out.convertTo(Out,CV_8U,255,0)
imwrite("D:/VSCodeFile/OpenCV__CSDN/image/after_Gamma_logo.jpeg", Out);
//===================
waitKey(0);
return 0;
}
![](https://img-blog.csdnimg.cn/fcbe3aef2402472e9d33b1df0c4f1d3f.png)
函数介绍:
convertTo(dst, type, scale, shift)
作用:把一个矩阵从一种数据类型转换到另-种数据类型,同时可以带上缩放因子和增量
dst:目的矩阵,如果dst在运算前没有合适的尺寸或类型,将被重新分配。
type:需要的输出矩阵类型,或者更明确的,是输出矩阵的深度,如果是负值(常用-1)则输出矩阵和输入矩阵类型相同
scale:尺度变换因子(可选)。默认值是1。即把原矩阵中的每一个元素都乘以scale。
shift:附加到尺度变换后的值上的偏移量(可选) 。默认值是0。即把原矩阵中的每一个元素都乘以scale,再加上shift。
计算方式:dst=src*scale+shift
示例:Input.convertTo(tmp,CV_8U,255,255);
注释:将矩阵Input转换为CV_8U类型的矩阵tmp: tmp(x,y)= Input(x,y)*255+255.这样,将图像做线性变换。
使值为-1的像素变为0 (-1*255+255=0)。值大于255的像素将赋值为255,这是因为CV32S转换为无符号CV_8U时,应用了饱和度运算。
伽马变换在提升对比度上有比较好的效果,但是需要手动调节γ
值。下一节将会介绍更为方便的方法自动调节图像对比度。
五、 总结
最后,长话短说,大家看完就好好动手实践一下,切记不能三分钟热度、三天打鱼,两天晒网。OpenCV是学习图像处理理论知识比较好的一个途径,大家也可以自己尝试写写博客,来记录大家平时学习的进度,可以和网上众多学者一起交流、探讨,有什么问题希望大家可以积极评论交流,我也会及时更新,来督促自己学习进度。希望大家觉得不错的可以点赞、关注、收藏。
![](https://img-blog.csdnimg.cn/e7f067b35749483d9b44b346822e2a53.gif)
相关文章
- C++学习——c++逗号操作符说明(附加全部运算符优先级)
- OpenCV进行人脸识别(Python)
- pycharm配置opencv-Python_pycharm环境安装
- 使用C++ OpenCV实现椭圆区域检测与Aruco码的生成与检测并估计位姿
- c++语言截取字符串,详解C++ string常用截取字符串方法
- 使用C++ OpenCV实现椭圆区域检测与Aruco码的生成与检测并估计位姿
- Py之cv2:cv2库(OpenCV,opencv-python)的简介、安装、使用方法(常见函数、方法等)最强详细攻略[通俗易懂]
- OpenCV-Python (Sobel算子)[通俗易懂]
- Opencv学习笔记(九)光流法
- Opencv cvCircle()函数[通俗易懂]
- c++获取子类窗口句柄位置_C++中各种获取窗口句柄的方法「建议收藏」
- 深入理解C++11_c++ string char
- POSIT算法的原理–opencv 3D姿态估计[通俗易懂]
- Opencv 图像处理:数字图像的必会知识
- openCV._imread opencv
- opencv remap matlab,如何使用OpenCV的remap函数?
- 【1】windows下安装OpenCV(4.3)+VS2017安装+opencv_contrib4.3.0配置
- 实战 | 基于OpenCV的停车场空余车位实时监测系统(详细步骤 + 源码)
- c++的链表-链表入门(C++)
- C++ 下 Halcon 与 OpenCV 图像的转换
- OpenCV 畸变矫正映射
- opencv加载显示图像详解程序员
- Python3 识别验证码(opencv-python)详解编程语言
- 一步步搭建Linux环境并安装OpenCV(linux安装opencv)