OpenCV开发笔记(十三):OpenCV图像对比度、亮度的调整

若该文为原创文章,未经允许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/104427405
各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究

红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中...(点击传送门)

OpenCV开发专栏(点击传送门)

上一篇:《OpenCV开发笔记(十二):OpenCV编译支持Gpu(cuda) 加速开发之win-qt-msvc2015编译(opencv3.4.0、cuda9.0、VS2015)》

下一篇:《OpenCV开发笔记(十四):算法基础之线性滤波-方框滤波》

 

前言

      对图像本身的像素点进行对比和亮度的调整。

 

相关博客

      《OpenCV开发笔记(五):OpenCV读取与操作摄像头》中可以对摄像头采集的图像进行对比度、亮度、曝光度等的调整,但是需要摄像头硬件本身支持,而本篇是直接对图像进行处理。

 

Demo演示效果

 

对比度

对比度指的是一幅图像中明暗区域最亮的白和最暗的黑之间不同亮度层级的测量,差异范围越大代表对比越大,差异范围越小代表对比越小,好的对比率120:1就可容易地显示生动、丰富的色彩,当对比率高达300:1时,便可支持各阶的颜色。但对比率遭受和亮度相同的困境,现今尚无一套有效又公正的标准来衡量对比率,所以最好的辨识方式还是依靠使用者眼睛。

 

亮度

      亮度是指画面的明亮程度,单位是堪德拉每平米(cd/m2)或称nits,也就是每平方公尺分之烛光。当前提高显示屏亮度的方法有两种,一种是提高LCD面板的光通过率;另一种就是增加背景灯光的亮度。

      转换为RGB图像中对亮度的操作就是对每个值加一个固定值。

 

算子与计算对比度亮度计算公式

算子的概念

      一般的图像处理算子(我们理解为计算公式)都是一个函数,接收一个或多个输入图像,并产生输出图像。

      下面是算子的一般形式:

      g(x) = h( f(x) ) 或者 g(x) = h( f0(x) ……fn(x) )

对比度和亮度计算公式

      g(x, y) = f(x, y) * alpha + beta;

      其中:f(x, y)代表原图像某个点的像素颜色值;alpha代表对比度值;beta代表亮度值;

      此处因为在实际的开发过程中,需要根据实际调整的对比度和亮度的计算方法:

      g(x, y) = f(x, y) * (alpha / 100.0f) + beta

      对比度范围0~400(笔者选取的),分母为100.0f;

      亮度范围-255~255(笔者选取的),无分母(可认为分母为1.0f);

 

Demo源码

void OpenCVManager::testContrastAndBrightness()
{
    cv::Mat mat1;
    QString fileName1 = "E:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/1.jpg";
    mat1 = cv::imread(fileName1.toStdString());

    cv::String windowName = "openCVDemo v1.8.0";
    cvui::init(windowName);

    if(!mat1.data)
    {
        qDebug() << __FILE__ << __LINE__
                 << "Failed to load image:" << fileName1;
        return;
    }
    // 增强对比度
    float r;
    float g;
    float b;
    cv::Mat dstMat;
    dstMat = cv::Mat::zeros(mat1.size(), mat1.type());
    cv::Mat windowMat = cv::Mat(cv::Size(dstMat.cols * 2, dstMat.rows), CV_8UC3);
    int alpha = 100;    // 小于1,则降低对比度
    int beta = 0;     // 负数,则降低亮度
    cvui::window(windowMat, dstMat.cols, 0, dstMat.cols, dstMat.rows, "settings");
    while(true)
    {
        windowMat = cv::Scalar(0, 0, 0);
        cvui::printf(windowMat, 375, 40, "contrast");
        cvui::trackbar(windowMat, 375, 50, 165, &alpha, 0, 400);
        cvui::printf(windowMat, 375, 100, "brightness");
        cvui::trackbar(windowMat, 375, 110, 165, &beta, -255, 255);
#if 1
        for(int row = 0; row < mat1.rows; row++)
        {
            for(int col = 0; col < mat1.cols; col++)
            {
                b = mat1.at(row, col)[0];
                g = mat1.at(row, col)[1];
                r = mat1.at(row, col)[2];
#if 0
                // 改变背景色
                if(r > 200 && g > 200 && b > 200)
                {
                    r = 25/4.0;
                    g = 246.0f;
                    b = 197.0f;
                    dstMat.at(row, col)[0] = b;
                    dstMat.at(row, col)[1] = g;
                    dstMat.at(row, col)[2] = r;
                }
#endif
#if 1
                // 对比度、亮度计算公式 cv::saturate_cast(value):防止溢出
                dstMat.at(row, col)[0] = cv::saturate_cast(b * alpha / 100.0f + beta);
                dstMat.at(row, col)[1] = cv::saturate_cast(g * alpha / 100.0f + beta);
                dstMat.at(row, col)[2] = cv::saturate_cast(r * alpha / 100.0f + beta);
#else
                // 对比度、亮度计算公式 cv::saturate_cast(value):防止溢出
                dstMat.at(row, col)[0] = cv::saturate_cast(b * alpha / 100.0f + beta);
                dstMat.at(row, col)[1] = cv::saturate_cast(g * alpha / 100.0f + beta);
                dstMat.at(row, col)[2] = cv::saturate_cast(r * alpha / 100.0f + beta);
#endif
            }
        }
//        cvui::trackbar(windowMat, dstMat.cols, dstMat.rows / 3, dstMat.cols, &?alpha, 0, 100, );
        cv::Mat imageMat = windowMat(cv::Range(0, dstMat.rows), cv::Range(0, dstMat.cols));
        cv::addWeighted(imageMat, 0.0, dstMat, 1.0, 0.0f, imageMat);
#endif
        cvui::update();
        cv::imshow(windowName, windowMat);
        if(cv::waitKey(25) == 27)
        {
            break;
        }
    }
}

 

工程模板:对应版本号v1.8.0

      对应版本号v1.8.0

 

入坑

入坑一:滑块拽托不动

原因:

      没有留间隔循环获取。

解决方法:

OpenCV开发笔记(十三):OpenCV图像对比度、亮度的调整_第1张图片

 

上一篇:《OpenCV开发笔记(十二):OpenCV编译支持Gpu(cuda) 加速开发之win-qt-msvc2015编译(opencv3.4.0、cuda9.0、VS2015)》

下一篇:《OpenCV开发笔记(十四):算法基础之线性滤波-方框滤波》

 

原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/104427405

你可能感兴趣的:(#,OpenCV,图形图像处理)