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 高光阈值
voidCImageUtility::ImageAutoGradationProcess(AutoGradationType gType,doubledarkLimen,doublebrightLimen){
    // 目前只处理24位以上的位图
    if(nPixBytes <3)
        return;
    //临时保存像素点的颜色
    intnRGB[3]={0,0,0};
    switch(gType){
        caseg_L_VALUE:{    //通过LAB中的L分量自动色阶
            //保存每个亮度分量的像素个数
            unsignedlonggradation[101];
            for(size_ti=0;i<101;i++)
                gradation[i]=0;
            //保存亮度最多的像素个数
            unsignedlongmaxPixle=0;
            // 暗调阈值序号
            intdarkPos=0;
            // 高光阈值序号
            intlightPos=0;        
            doubleLAB[3]={0.0,0.0,0.0};
            for(longnHeight=0; nHeight<bmSrcInfo.bmHeight; nHeight++)  
            {      
                for(longnWidth=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_ti=0;i<101;i++){
                if(((longdouble)(gradation[i]))/maxPixle>darkLimen){
                    darkPos=i;
                    break;
                }
            }
            // 高光位置
            for(size_ti=100;i>=0;i--){
                if(((longdouble)(gradation[i]))/maxPixle>brightLimen){
                    lightPos=i;
                    break;
                }
            }
            //对像素进行处理
            doubleoffsetLight=(lightPos+darkPos)/2-50.0;        //中间亮度偏移
            doublequotiety=100.0/(lightPos-darkPos);            //亮度缩放系数
            for(longnHeight=0; nHeight<bmSrcInfo.bmHeight; nHeight++)  
            {      
                for(longnWidth=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;                       
        }
        // 还有问题,有待研究
        caseg_RGB:{        //通过RGB自动色阶
            //保存每个亮度分量的像素个数
            unsignedlonggradation[3][256];
            for(size_ti=0;i<3;i++)
                for(size_tj=0;j<256;j++)
                    gradation[i][j]=0;
            //保存亮度最多的像素个数
            unsignedlongmaxPixle[3]={0,0,0};
            // 暗调阈值序号
            intdarkPos[3]={0,0,0};    
            // 高光阈值序号
            intlightPos[3]={0,0,0};            
            for(longnHeight=0; nHeight<bmSrcInfo.bmHeight; nHeight++)  
            {      
                for(longnWidth=0; nWidth<bmSrcInfo.bmWidth; nWidth++)  
                {
                    //获取对应像素点得颜色
                    getPixelColor(nRGB,nHeight,nWidth);
                    for(inti=0;i<3;i++){
                        //保存每种颜色分量的像素个数
                        gradation[i][nRGB[i]]++;
                        //保存每种颜色分量最大的像素个数
                        if(maxPixle[i]<gradation[i][nRGB[i]])
                            maxPixle[i]=gradation[i][nRGB[i]];
                    }
                }             
            }
            //分析直方图
            // 暗调位置
            for(size_ti=0;i<3;i++){
                for(size_tj=0;j<256;j++){
                    if(((longdouble)(gradation[i][j]))/maxPixle[i]>darkLimen){
                        darkPos[i]=j;
                        break;
                    }
                }
            }
            // 高光位置
            for(size_ti=0;i<3;i++){
                for(size_tj=255;j>=0;j--){
                    if(((longdouble)(gradation[i][j]))/maxPixle[i]>brightLimen){
                        lightPos[i]=j;
                        break;
                    }
                }
            }
            //对像素进行处理
            intoffsetLight[3]={0,0,0};
            for(inti=0;i<3;i++)
                offsetLight[i]=(lightPos[i]+darkPos[i])/2-128;        //中间亮度偏移
            doublequotiety[3]={0.0,0.0,0.0};
            for(inti=0;i<3;i++)
                quotiety[i]=255.0/(lightPos[i]-darkPos[i]);            //亮度缩放系数
            for(longnHeight=0; nHeight<bmSrcInfo.bmHeight; nHeight++)  
            {      
                for(longnWidth=0; nWidth<bmSrcInfo.bmWidth; nWidth++)  
                {
                    //获取对应像素点得颜色
                    getPixelColor(nRGB,nHeight,nWidth);    
                    for(inti=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亮度分量实现自动色阶:

VC实现位图自动色阶算法

2.2 RGB实现自动色阶:

VC实现位图自动色阶功能

对于RGB色彩空间与LAB色彩空间的转换,读者可以参考:VC编程实现色彩空间RGB与XYZ相互转换、VC编程实现色彩空间XYZ与LAB相互转换。

0 0
原创粉丝点击