zoukankan      html  css  js  c++  java
  • 图像亮度变化

    由于毕设的关系,开始折腾计算机视觉
    双目测距的具体实现,现在刚有点眉目而已
    看了下图像亮度/对比度的变换的资料
    结果又发现漫山遍野的都是同一份代码
    而且几乎没有什么解释
    原本决定等Harris角点那些弄完再写篇文章
    现在想想
    还是先记下这份简单的笔记并加以讲解下

    那些计算机科班出身的人就不用看这篇了
    这只是给我们这些物理/电子系中没有学过”数字图像处理“这门课的人看的

    术语解释

    亮度(Brightness)

    也叫亮度,中文翻译不同而已,你可以看Wikipedia
    在 RGB 色彩空间中,明度可以被认为是R(红色),G(绿色)和B(蓝色)座标的算术平均 μ(尽管这三个成分中的某个要比其他看起来更明亮,但这可以被某些显示系统自动补偿):

     \mu = {R + G + B \over 3 }

    对比度(Contrast)

    我实在google不到满意的解释
    大概上来说
    灰度图像的对比度指的是图像中的最黑与最白的点,他们灰度值的比值关系
    彩色图像由于有3种通道,我的理解是各个通道中的灰度值的比值关系,确切的定义还望有人指教

    实现思路

    知道明度跟对比度的定义,接下来
    要修改亮度,就把图像的通道的灰度值一起增加或者减少就可以
    要修改对比度,需要把图像的通道的灰度值以一个值为临界点,往相反两个方向变化
    比如,取128为阈值,要增强对比度,低于128的值修改得比原来更小,高于128的值再修改得更大,要降低对比度就反向操作

    下面给出我自己写的一份代码,演示明度以及对比度的调整
    对比度的公式参考自Photoshop的公式:
    nRGB = RGB + (RGB – Threshold) * Contrast / 255

    源代码

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    #include "highgui.h"
    #pragma comment(lib,"cv200d.lib")
    #pragma comment(lib,"cxcore200d.lib")
    #pragma comment(lib,"highgui200d.lib")
     
    int BrightnessAdjust(const IplImage* srcImg,
                         IplImage* dstImg,
                         float brightness)
    {
        assert(srcImg != NULL);
        assert(dstImg != NULL);
     
        int x,y,i;
        float val;
        for (i = 0; i < 3; i++)//彩色图像需要处理3个通道,灰度图像这里可以删掉
        {
            for (y = 0; y < srcImg->height; y++)
            {
                for (x = 0; x < srcImg->width; x++)
                {
     
                    val = ((uchar*)(srcImg->imageData + srcImg->widthStep*y))[x*3+i];
                    val += brightness;
                    //对灰度值的可能溢出进行处理
                    if(val>255)    val=255;
                    if(val<0) val=0;
                    ((uchar*)(dstImg->imageData + dstImg->widthStep*y))[x*3+i] = (uchar)val;
                }
            }
        }
     
        return 0;
    }
     
    int ContrastAdjust(const IplImage* srcImg,
                       IplImage* dstImg,
                       float nPercent)
    {
        assert(srcImg != NULL);
        assert(dstImg != NULL);
     
        int x,y,i;
        float val;
        for (i = 0; i < 3; i++)//彩色图像需要处理3个通道,灰度图像这里可以删掉
        {
            for (y = 0; y < srcImg->height; y++)
            {
                for (x = 0; x < srcImg->width; x++)
                {
     
                    val = ((uchar*)(srcImg->imageData + srcImg->widthStep*y))[x*3+i];
                    val = 128 + (val - 128) * nPercent;
                    //对灰度值的可能溢出进行处理
                    if(val>255) val=255;
                    if(val<0) val=0;
                    ((uchar*)(dstImg->imageData + dstImg->widthStep*y))[x*3+i] = (uchar)val;
                }
            }
        }
        return 0;
    }
     
    int main(int argc, char** argv)
    {
        IplImage* srcImg = cvLoadImage("lena.jpg");
        assert( srcImg != NULL );
     
        IplImage* brightnessImg = cvCloneImage(srcImg);
        //亮度变换,最后数值取值为正时变亮,负则变暗
        BrightnessAdjust(srcImg, brightnessImg, 80.0f);
     
        IplImage* contrastImg = cvCloneImage(srcImg);
        //对比度变换,数值小于1降低对比度,大于1增强对比度
        ContrastAdjust(srcImg, contrastImg, 1.3f);
     
        cvNamedWindow("Source",CV_WINDOW_AUTOSIZE);
        cvNamedWindow("BrightnessAdjust",CV_WINDOW_AUTOSIZE);
        cvNamedWindow("ContrastAdjust",CV_WINDOW_AUTOSIZE);
        cvShowImage("Source",srcImg);
        cvShowImage("BrightnessAdjust",brightnessImg);
        cvShowImage("ContrastAdjust",contrastImg);
        cvWaitKey(0);
        cvReleaseImage(&srcImg);
        cvReleaseImage(&brightnessImg);
        cvReleaseImage(&contrastImg);
        cvDestroyWindow("Source");
        cvDestroyWindow("BrightnessAdjust");
        cvDestroyWindow("ContrastAdjustrast");
     
        return 0;
    }

    对新手提示几句,运行这个代码请在工程文件的目录下放一个图片,名字是lena.jpg
    另外,对彩色通道的处理,循环只有3次,这种循环最好放在最外围,因为图像的长宽一般都远大于这个值
    如果你把小循环放最里面,频繁的循环切换,效率会低不少
    这只是程序编写技巧上的小提示

    本代码在Visual Studio 2008+OpenCV 2.0下运行通过,效果如下


    并且与photoshop的调整效果对比过
    亮度变换与ps旧版效果一致,貌似ps对亮度变换的公式进行过调整,新版不是这么单纯的加减灰度值
    对比度就几乎都差不多了

    更多资料

    关于OpenCV的安装、配置以及基础学习,可以在OpenCV中文官网查得
    官网的入门说明异常详细,各种平台各种IDE都有介绍,我就不多废话了

    下次再说说Harris角点的事情吧

  • 相关阅读:
    Window7中Eclipse运行MapReduce程序报错的问题
    Hadoop以及其外围生态系统的安装参考
    《node.js开发指南》第五章与新版Node变化太大的一些问题
    打造开发React Native的Sublime
    幸福
    近日阅读记录
    react中属性默认值是true?
    git撤销操作总结
    React Native中的DeviceEventEmitter.addListener与DeviceEventEmitter.emit
    React父子组件的一个混淆点
  • 原文地址:https://www.cnblogs.com/mysunnyday/p/2343930.html
Copyright © 2011-2022 走看看