图像对比度和亮度

Posted fcfc940503

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图像对比度和亮度相关的知识,希望对你有一定的参考价值。

图像亮度通俗理解便是图像的明暗程度,数字图像 f(x,y) = i(x,y) r(x, y) ,如果灰度值在[0,255]之间,则 f 值越接近0亮度越低,f 值越接近255亮度越高。而且我们也要把亮度和对比度区分开来,正如上述提的对比度指的是最高和最低灰度级之间的灰度差。

饱和度指的是图像颜色种类的多少, 上面提到图像的灰度级是[Lmin,Lmax],则在Lmin、Lmax 的中间值越多,便代表图像的颜色种类多,饱和度也就更高,外观上看起来图像会更鲜艳,调整饱和度可以修正过度曝光或者未充分曝光的图片。使图像看上去更加自然

 

对于数字图像变换,设原像素灰度为 f(i,j),转化后的像素灰度为 g(i,j),则常用的线性变换是 g(i,j)= af(i,j) + b, 其中系数 a 影响图像的对比度,系数 b 影响图像的亮度,具体如下:
(1) a=1时是原图;
(2) a>1时对比度增强,图像看起来更加清晰;
(3) a<1时对比度减弱,图像看起来变暗;
(4) b影响图像的亮度,随着增加b (b>0)和减小b (b>0),图像整体的灰度值上移或者下移, 也就是图像整体变亮或者变暗, 不会改变图像的对比度

 常用代码:

在opencv中图像数据是存放在Mat数据类型中,我们知道一个像素有rgb构成,所以Mat是个三维数组,一下就是简单的获取mat中图像像素。

技术图片
//三个for循环,执行运算 new_image(i,j) =a*image(i,j) + b
       for(int y = 0; y < image.rows; y++ )
       
              for(int x = 0; x < image.cols; x++ )
              
                     for(int c = 0; c < 3; c++ )
                     
                            new_image.at<Vec3b>(y,x)[c]= saturate_cast<uchar>( (g_nContrastValue*0.01)*(image.at<Vec3b>(y,x)[c] ) + g_nBrightValue );
                     
              
       
技术图片//g_nContrastValue是对比度, g_nBrightValu是亮度;及对应g(i,j)= af(i,j) + b, 其中系数 a 影响图像的对比度,系数 b 影响图像的亮度;

上述代码中image.at<Vec3b>(y,x)[c] 其中,y是像素所在的行, x是像素所在的列, c是R、G、B(对应0、1、2)其中之一。

saturate_cast为了安全转换,运算结果可能超出像素取值范围(溢出),还可能是非整数(如果是浮点数的话),用saturate_cast对结果进行转换,以确保它为有效值。

代码如下:

//-----------------------------------【头文件包含部分】---------------------------------------
//  描述:包含程序所依赖的头文件
//---------------------------------------------------------------------------------------------- 
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>

//-----------------------------------【命名空间声明部分】---------------------------------------
//  描述:包含程序所使用的命名空间
//-----------------------------------------------------------------------------------------------   
using namespace std;
using namespace cv;

//-----------------------------------【全局函数声明部分】--------------------------------------
//  描述:全局函数声明
//-----------------------------------------------------------------------------------------------
static void ContrastAndBright(int, void *);

//-----------------------------------【全局变量声明部分】--------------------------------------
//  描述:全局变量声明
//-----------------------------------------------------------------------------------------------
int g_nContrastValue; //对比度值
int g_nBrightValue;  //亮度值
Mat g_srcImage, g_dstImage;
//-----------------------------------【main( )函数】--------------------------------------------
//  描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main()

    //改变控制台前景色和背景色
    system("color 2F");
    // 读入用户提供的图像
    g_srcImage = imread("E:\\\\VS2015Opencv\\\\vs2015\\\\project\\\\picture\\\\cat.jpg");
    if (!g_srcImage.data)  printf("读取g_srcImage图片错误~! \\n"); return false; 
    g_dstImage = Mat::zeros(g_srcImage.size(), g_srcImage.type());

    //设定对比度和亮度的初值
    g_nContrastValue = 80;
    g_nBrightValue = 80;

    //创建窗口
    namedWindow("【效果图窗口】", 1);

    //创建轨迹条
    createTrackbar("对比度:", "【效果图窗口】", &g_nContrastValue, 300, ContrastAndBright);
    createTrackbar("亮   度:", "【效果图窗口】", &g_nBrightValue, 200, ContrastAndBright);

    //调用回调函数
    ContrastAndBright(g_nContrastValue, 0);
    ContrastAndBright(g_nBrightValue, 0);

    //输出一些帮助信息
    cout << endl << "\\t运行成功,请调整滚动条观察图像效果\\n\\n"
        << "\\t按下“q”键时,程序退出\\n";

    //按下“q”键时,程序退出
    while (char(waitKey(1)) != q) 
    return 0;


//-----------------------------【ContrastAndBright( )函数】------------------------------------
//  描述:改变图像对比度和亮度值的回调函数
//-----------------------------------------------------------------------------------------------
static void ContrastAndBright(int, void *)


    // 创建窗口
    namedWindow("【原始图窗口】", 1);

    // 三个for循环,执行运算 g_dstImage(i,j) = a*g_srcImage(i,j) + b
    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);

效果图:

技术图片

 

以上是关于图像对比度和亮度的主要内容,如果未能解决你的问题,请参考以下文章

求图像处理算法中,调整亮度、对比度、饱和度的算法!

更改图像的亮度和对比度

如何使用opencv均衡图像的对比度和亮度?

OpenCV图像线性变换(图像线性混合亮度和对比度增强线性变换API)

9.调整图像的对比度和亮度

使用滑块更改图像的对比度和亮度