“明度”(Brightness)原来用做光度测定术语照度和(错误的)用于辐射测定术语辐射度的同义词。按美国联邦通信术语表(FS-1037C)的规定,明度现在只应用于非定量的提及对光的生理感觉和感知。[1]
一个给定目标亮度在不同的场景中可以引起不同的明度感觉;比如White错觉和Wertheimer-Benary错觉。
在 RGB 色彩空间中,明度可以被认为是 R(红色),G(绿色)和B(蓝色)座标的算术平均 μ(尽管这三个成分中的某个要比其他看起来更明亮,但这可以被某些显示
系统自动补偿):
\mu = {R + G + B \over 3 } 。
即: dst[i] = (src[i + 0] + src[i + 1] + src[i + 2]) / 3 (三通道图片)
明度也是 HSB 或 HSV 色彩空间(色相,饱和度和明度)中的颜色坐标,它的值是这个颜色的 R,G 和 B 三者中的极大值。
对比度,具体的概念解释可以参考Wiki或者百度百科。简单的讲对比度反应了图片上亮区域和暗区域的层次感。而反应到图像编辑上,调整对比度就是在保证平均亮度不变的情况下,扩大或缩小亮的点和暗的点的差异。既然是要保证平均亮度不变,所以对每个点的调整比例必须作用在该值和平均亮度的差值之上,这样才能够保证计算后的平均亮度不变,故有调整公式:
Out = Average + (In – Average) * ( 1 + percent)
其中In表示原始像素点亮度,Average表示整张图片的平均亮度,Out表示调整后的亮度,而percent即调整范围[-1,1]。证明这个公式的正确性相当简单:
设图上有n个像素点,各个点亮度为Ai,平均亮度为A,变化率为alpha,则有:
CodeCogsEqn (1)
但是实际处理中,并没有太多的必要去计算一张图的平均亮度:一来耗时间,二来在平均亮度上的精确度并不会给图像的处理带来太多的好处—-一般就假设一张图的平均亮度为128,即一半亮度,而一张正常拍照拍出来的图平均亮度应该是在[100,150]。在肉眼看来两者基本没有任何区别,而如果真实地去计算平均亮度还会带来很大的计算量。、
即: dst[i] = 128 + (src[i] – 128) * (nPercent) // nPercent = 1 + percent
简单示例:
#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;
}
