图像亮度变化
由于毕设的关系,开始折腾计算机视觉
双目测距的具体实现,现在刚有点眉目而已
看了下图像亮度/对比度的变换的资料
结果又发现漫山遍野的都是同一份代码
而且几乎没有什么解释
原本决定等Harris角点那些弄完再写篇文章
现在想想
还是先记下这份简单的笔记并加以讲解下
那些计算机科班出身的人就不用看这篇了
这只是给我们这些物理/电子系中没有学过”数字图像处理“这门课的人看的
术语解释
亮度(Brightness)
也叫亮度,中文翻译不同而已,你可以看Wikipedia
在 RGB 色彩空间中,明度可以被认为是R(红色),G(绿色)和B(蓝色)座标的算术平均 μ(尽管这三个成分中的某个要比其他看起来更明亮,但这可以被某些显示系统自动补偿):

对比度(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角点的事情吧
浙公网安备 33010602011771号