VC编程实现对位图图像自动色阶处理
来源:互联网 发布:知有儿童挑促织 编辑:程序博客网 时间:2024/05/22 02:31
VC编程实现对位图图像自动色阶处理
VC编程实现位图拷贝、切除空白边介绍了VC实现位图图像拷贝,切除二值图空白边,本文继续介绍位图处理类CImageUtility的其它成员方法,着重介绍VC编程实现位图图像自动色阶的功能。
根据互联网搜索的结果,位图图像自动色阶算法主要包含两种方案,一种是拉开LAB色彩空间的L(亮度)分量,使图像的亮度区域拉开,第二种是讲图像的RGB各分量值的区域拉开。第一种方案效果较好,但是计算比较复杂,需要用到前面介绍的色彩空间转换,第二种方案计算简单,但是效果不如前一种方案,下面列出具体的VC实现源码和处理效果,读者可以根据实际需要进行选用。
1. VC源代码
1
2
3
4
5
6
7
8
9
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// 自动色阶
// gType 自动色阶的算法
// darkLimen 暗调阈值
// brightLimen 高光阈值
void
CImageUtility::ImageAutoGradationProcess(AutoGradationType gType,
double
darkLimen,
double
brightLimen){
// 目前只处理24位以上的位图
if
(nPixBytes <3)
return
;
//临时保存像素点的颜色
int
nRGB[3]={0,0,0};
switch
(gType){
case
g_L_VALUE:{
//通过LAB中的L分量自动色阶
//保存每个亮度分量的像素个数
unsigned
long
gradation[101];
for
(
size_t
i=0;i<101;i++)
gradation[i]=0;
//保存亮度最多的像素个数
unsigned
long
maxPixle=0;
// 暗调阈值序号
int
darkPos=0;
// 高光阈值序号
int
lightPos=0;
double
LAB[3]={0.0,0.0,0.0};
for
(
long
nHeight=0; nHeight<bmSrcInfo.bmHeight; nHeight++)
{
for
(
long
nWidth=0; nWidth<bmSrcInfo.bmWidth; nWidth++)
{
//获取对应像素点得颜色
getPixelColor(nRGB,nHeight,nWidth);
//转换颜色到LAB色彩空间
CColorUtility::_cie_rgb2lab(nRGB,LAB);
//对应亮度的像素点个数加1
gradation[(
int
)(LAB[0]+0.5)]++;
//LAB中的L分量【0.0-100.0】
if
(maxPixle<gradation[(
int
)(LAB[0]+0.5)])
maxPixle=gradation[(
int
)(LAB[0]+0.5)];
}
}
//分析直方图
// 暗调位置
for
(
size_t
i=0;i<101;i++){
if
(((
long
double
)(gradation[i]))/maxPixle>darkLimen){
darkPos=i;
break
;
}
}
// 高光位置
for
(
size_t
i=100;i>=0;i--){
if
(((
long
double
)(gradation[i]))/maxPixle>brightLimen){
lightPos=i;
break
;
}
}
//对像素进行处理
double
offsetLight=(lightPos+darkPos)/2-50.0;
//中间亮度偏移
double
quotiety=100.0/(lightPos-darkPos);
//亮度缩放系数
for
(
long
nHeight=0; nHeight<bmSrcInfo.bmHeight; nHeight++)
{
for
(
long
nWidth=0; nWidth<bmSrcInfo.bmWidth; nWidth++)
{
//获取对应像素点得颜色
getPixelColor(nRGB,nHeight,nWidth);
//转换颜色到LAB色彩空间
CColorUtility::_cie_rgb2lab(nRGB,LAB);
//移动当前亮度的中心到自动色阶后亮度的中心
LAB[0]=LAB[0]-offsetLight;
//计算当前亮度与中心的距离
LAB[0]-=50;
//将距离乘于系数加上中心位置及时当前亮度最终的位置
LAB[0]=quotiety*LAB[0]+50;
//重新给像素点赋值
CColorUtility::_cie_lab2rgb(LAB,nRGB);
//设置像素点颜色
setPixelColor(nRGB,nHeight,nWidth);
}
}
break
;
}
// 还有问题,有待研究
case
g_RGB:{
//通过RGB自动色阶
//保存每个亮度分量的像素个数
unsigned
long
gradation[3][256];
for
(
size_t
i=0;i<3;i++)
for
(
size_t
j=0;j<256;j++)
gradation[i][j]=0;
//保存亮度最多的像素个数
unsigned
long
maxPixle[3]={0,0,0};
// 暗调阈值序号
int
darkPos[3]={0,0,0};
// 高光阈值序号
int
lightPos[3]={0,0,0};
for
(
long
nHeight=0; nHeight<bmSrcInfo.bmHeight; nHeight++)
{
for
(
long
nWidth=0; nWidth<bmSrcInfo.bmWidth; nWidth++)
{
//获取对应像素点得颜色
getPixelColor(nRGB,nHeight,nWidth);
for
(
int
i=0;i<3;i++){
//保存每种颜色分量的像素个数
gradation[i][nRGB[i]]++;
//保存每种颜色分量最大的像素个数
if
(maxPixle[i]<gradation[i][nRGB[i]])
maxPixle[i]=gradation[i][nRGB[i]];
}
}
}
//分析直方图
// 暗调位置
for
(
size_t
i=0;i<3;i++){
for
(
size_t
j=0;j<256;j++){
if
(((
long
double
)(gradation[i][j]))/maxPixle[i]>darkLimen){
darkPos[i]=j;
break
;
}
}
}
// 高光位置
for
(
size_t
i=0;i<3;i++){
for
(
size_t
j=255;j>=0;j--){
if
(((
long
double
)(gradation[i][j]))/maxPixle[i]>brightLimen){
lightPos[i]=j;
break
;
}
}
}
//对像素进行处理
int
offsetLight[3]={0,0,0};
for
(
int
i=0;i<3;i++)
offsetLight[i]=(lightPos[i]+darkPos[i])/2-128;
//中间亮度偏移
double
quotiety[3]={0.0,0.0,0.0};
for
(
int
i=0;i<3;i++)
quotiety[i]=255.0/(lightPos[i]-darkPos[i]);
//亮度缩放系数
for
(
long
nHeight=0; nHeight<bmSrcInfo.bmHeight; nHeight++)
{
for
(
long
nWidth=0; nWidth<bmSrcInfo.bmWidth; nWidth++)
{
//获取对应像素点得颜色
getPixelColor(nRGB,nHeight,nWidth);
for
(
int
i=0;i<3;i++){
//移动当前亮度的中心到自动色阶后亮度的中心
nRGB[i]=nRGB[i]-offsetLight[i];
//计算当前亮度与中心的距离
nRGB[i]-=128;
//将距离乘于系数加上中心位置及时当前亮度最终的位置
nRGB[i]=(
int
)(quotiety[i]*nRGB[i])+128;
}
//设置像素点颜色
setPixelColor(nRGB,nHeight,nWidth);
}
}
break
;
}
}
//switch over
bmpSrc->SetBitmapBits(dwBmByteSize, pBmBits);
}
2. 效果对比
2.1 LAB亮度分量实现自动色阶:
2.2 RGB实现自动色阶:
对于RGB色彩空间与LAB色彩空间的转换,读者可以参考:VC编程实现色彩空间RGB与XYZ相互转换、VC编程实现色彩空间XYZ与LAB相互转换。
0 0
- VC编程实现对位图图像自动色阶处理
- VC编程实现对位图图像自动色阶处理
- VC编程实现位图图像二值化、反相
- VC编程实现位图图像二值化、反相
- VC编程实现位图处理类(显示位图、加载位图、获取/设置像素点颜色)
- VC编程实现位图处理类(显示位图、加载位图、获取/设置像素点颜色)
- VC编程使用3种方案实现位图图像灰度化
- VC编程使用3种方案实现位图图像灰度化
- VC++实现Contourlet图像处理
- VC++实现Contourlet图像处理
- VC++图像处理编程讲座之二
- VC++图像处理编程讲座之三
- 自动色阶图像处理算法
- VC++实现对退化图像的恢复
- VC编程实现位图拷贝、切除空白边
- VC编程实现位图拷贝、切除白边
- 位图(图像处理入门)
- 图像处理之-位图
- Ubuntu14.0 下Hadoop启动报Error: JAVA_HOME is not set and could not be found解决办法
- Hibernate Search
- poj 3070 Fibonacci 矩阵快速幂
- JPush极光推送个人理解
- Groovy笔记-关于joda-time和excel-import插件适用的grails版本问题
- VC编程实现对位图图像自动色阶处理
- 使用surfaceview画贝塞尔曲线+旋转背景图片
- iOS笔记(常用的一些知识点)
- 图片文件不是项目一部分或其"生成操作"属性未设置为“资源”
- Meteor Shower 广搜
- linux下RAID磁盘阵列说明
- java获得内部类对象的方法
- 应届大学毕业生户口迁移须知
- JSTL表达式在项目中的使用