1
+ #include " opencv2/opencv.hpp"
2
+ #include " opencv2/imgproc/imgproc.hpp"
3
+ #include " iostream"
4
+ #include " algorithm"
5
+ #include " vector"
6
+ #include " stdio.h"
7
+ #include " map"
8
+ #include " unordered_map"
9
+ using namespace std ;
10
+ using namespace cv ;
11
+
12
+ #define PI 3.14159265
13
+ Mat work (Mat src){
14
+ int row = src.rows ;
15
+ int col = src.cols ;
16
+ Mat dst (row, col, CV_8UC3);
17
+ // RGB2HSI
18
+ Mat H = Mat (row, col, CV_64FC1);
19
+ Mat S = Mat (row, col, CV_64FC1);
20
+ Mat I = Mat (row, col, CV_64FC1);
21
+ int mp[256 ]={0 };
22
+ double mp2[256 ]={0.0 };
23
+ for (int i = 0 ; i < row; i++){
24
+ for (int j = 0 ; j < col; j++){
25
+ double h, s, newi, th;
26
+ double B = (double )src.at <Vec3b>(i, j)[0 ] / 255.0 ;
27
+ double G = (double )src.at <Vec3b>(i, j)[1 ] / 255.0 ;
28
+ double R = (double )src.at <Vec3b>(i, j)[2 ] / 255.0 ;
29
+ double mi, mx;
30
+ if (R > G && R > B){
31
+ mx = R;
32
+ mi = min (G, B);
33
+ }
34
+ else {
35
+ if (G > B){
36
+ mx = G;
37
+ mi = min (R, B);
38
+ }else {
39
+ mx = B;
40
+ mi = min (R, G);
41
+ }
42
+ }
43
+ newi = (R + G + B) / 3.0 ;
44
+ if (newi < 0 ) newi = 0 ;
45
+ else if (newi > 1 ) newi = 1.0 ;
46
+ if (newi == 0 || mx == mi){
47
+ s = 0 ;
48
+ h = 0 ;
49
+ }else {
50
+ s = 1 - mi / newi;
51
+ th = (R - G) * (R - G) + (R - B) * (G - B);
52
+ th = sqrt (th)+1e-5 ;
53
+ th = acos (((R-G+R-B)*0.5 )/th);
54
+ if (G >= B) h = th;
55
+ else h = 2 * PI - th;
56
+ }
57
+ h = h / (2 *PI);
58
+ H.at <double >(i, j) = h;
59
+ S.at <double >(i, j) = s;
60
+ I.at <double >(i, j) = newi;
61
+ mp[(int )((src.at <Vec3b>(i, j)[0 ] + src.at <Vec3b>(i, j)[1 ] + src.at <Vec3b>(i, j)[2 ]) / 3 )]++;
62
+ }
63
+ }
64
+ for (int i = 0 ; i < 256 ; i++){
65
+ mp2[i] = (double )mp[i] / (double )(row * col);
66
+ }
67
+ double mI = 0 ;
68
+ for (int i = 0 ; i < 256 ; i++){
69
+ mI += (i / 255.0 ) * mp2[i];
70
+ }
71
+ printf (" mI: %.5f\n " , mI );
72
+ double var = 0 ;
73
+ double ThresHold = 0 ;
74
+ for (int i = 0 ; i < 256 ; i++){
75
+ double T = 1.0 * i / 256 ;
76
+ double P1 = 0.0 ;
77
+ double mT = 0.0 ;
78
+ for (int j = 0 ; j <= i; j++){
79
+ P1 += mp2[j];
80
+ mT += (double )(j / 255.0 ) * mp2[j];
81
+ }
82
+ if (P1 == 0 ) continue ;
83
+ if (((mI *P1 - mT )*(mI *P1 - mT ) / (P1*(1 -P1))) > var){
84
+ var = (mI *P1 - mT )*(mI *P1 - mT ) / (P1*(1 -P1));
85
+ ThresHold = T;
86
+ // printf("%d %.5f\n", i, ThresHold);
87
+ }
88
+ }
89
+ printf (" Thres: %.5f\n " , ThresHold);
90
+ int k = 50 ;
91
+ int cnt = 0 ;
92
+ for (int i = 0 ; i < row; i++){
93
+ for (int j = 0 ; j < col; j++){
94
+ if (I.at <double >(i, j) <= ThresHold){
95
+ cnt++;
96
+ }
97
+ }
98
+ }
99
+ printf (" cnt: %d\n " , cnt);
100
+ double A = (double )k * sqrt ((double )cnt / (double )(row * col - cnt));
101
+ printf (" A: %.5f\n " , A);
102
+ for (int i = 0 ; i < row; i++){
103
+ for (int j = 0 ; j < col; j++){
104
+ double D, C;
105
+ if (I.at <uchar>(i, j) <= ThresHold){
106
+ D = A;
107
+ C = 1.0 / log2 (D+1 );
108
+ }else {
109
+ D = (double )(ThresHold * A - ThresHold) / double ((1 - ThresHold) * (I.at <double >(i, j))) - (double )(ThresHold * A - 1 ) / (1 - ThresHold);
110
+ C = 1.0 / log2 (D+1 );
111
+ }
112
+ I.at <double >(i, j) = (C * log2 (D * (double )I.at <double >(i, j) + 1 ));
113
+ }
114
+ }
115
+ for (int i = 0 ; i < row; i++){
116
+ for (int j = 0 ; j < col; j++){
117
+ double preh = H.at <double >(i, j);
118
+ double pres = S.at <double >(i, j);
119
+ double prei = I.at <double >(i, j);
120
+ // printf("H: %.5f S: %.5f I: %.5f\n", preh, pres, prei);
121
+ double r = 0 , g = 0 , b = 0 ;
122
+ if (prei == 0.0 ){
123
+ r = 0 ;
124
+ g = 0 ;
125
+ b = 0 ;
126
+ }
127
+ else {
128
+ if (pres == 0.0 ){
129
+ r = g = b = prei;
130
+ }
131
+ double t1, t2, t3;
132
+ t1 = (1.0 - pres) / 3.0 ;
133
+ t2 = pres * cos (preh);
134
+ if (preh >= 0 && preh < (PI * 2 / 3 )){
135
+ b = t1;
136
+ t3 = cos (PI/3 - preh);
137
+ r = (1 + t2 / t3) / 3 ;
138
+ g = 1.0 - r - b;
139
+ r = 3 * prei * r;
140
+ g = 3 * g * prei;
141
+ b = 3 * prei * b;
142
+ }else if (preh >= (PI * 2 / 3 ) && preh < (PI * 4 / 3 )){
143
+ r = t1;
144
+ t3 = cos (PI - preh);
145
+ g = (1 + t2 / t3) / 3 ;
146
+ b = 1 - r - g;
147
+ r = 3 * prei * r;
148
+ g = 3 * g * prei;
149
+ b = 3 * prei * b;
150
+ }else if (preh >= (PI * 4 / 3 ) && preh < (PI * 2 )){
151
+ g = t1;
152
+ t3 = cos (PI * 5 / 3 - preh);
153
+ b = (1 + t2 / t3) / 3 ;
154
+ r = 1 - g - b;
155
+ r = 3 * prei * r;
156
+ g = 3 * g * prei;
157
+ b = 3 * prei * b;
158
+ }
159
+ }
160
+ // printf("%d %d %d\n", (int)(r*255), (int)(g*255), (int)(b*255));
161
+ dst.at <Vec3b>(i, j)[0 ] = (int )(b*255 );
162
+ dst.at <Vec3b>(i, j)[1 ] = (int )(g*255 );
163
+ dst.at <Vec3b>(i, j)[2 ] = (int )(r*255 );
164
+ }
165
+ }
166
+ return dst;
167
+ }
168
+
169
+ // 自适应对比度增强算法,C表示对高频的直接增益系数,n表示滤波半径,maxCG表示对CG做最大值限制
170
+ Mat ACE (Mat src, int C = 3 , int n = 3 , float MaxCG = 7.5 ){
171
+ int row = src.rows ;
172
+ int col = src.cols ;
173
+ Mat meanLocal; // 图像局部均值
174
+ Mat varLocal; // 图像局部方差
175
+ Mat meanGlobal; // 全局均值
176
+ Mat varGlobal; // 全局标准差
177
+ blur (src.clone (), meanLocal, Size (n, n));
178
+ Mat highFreq = src - meanLocal;
179
+ varLocal = highFreq.mul (highFreq);
180
+ varLocal.convertTo (varLocal, CV_32F);
181
+ for (int i = 0 ; i < row; i++){
182
+ for (int j = 0 ; j < col; j++){
183
+ varLocal.at <float >(i, j) = (float )sqrt (varLocal.at <float >(i, j));
184
+ }
185
+ }
186
+ meanStdDev (src, meanGlobal, varGlobal);
187
+ Mat gainArr = varGlobal / varLocal; // 增益系数矩阵
188
+ for (int i = 0 ; i < row; i++){
189
+ for (int j = 0 ; j < col; j++){
190
+ if (gainArr.at <float >(i, j) > MaxCG){
191
+ gainArr.at <float >(i, j) = MaxCG;
192
+ }
193
+ }
194
+ }
195
+ printf (" %d %d\n " , row, col);
196
+ gainArr.convertTo (gainArr, CV_8U);
197
+ gainArr = gainArr.mul (highFreq);
198
+ Mat dst1 = meanLocal + gainArr;
199
+ Mat dst2 = meanLocal + C * highFreq;
200
+ return dst1;
201
+ }
202
+
203
+ int main (){
204
+ Mat src = imread (" ../test.png" );
205
+ vector <Mat> now;
206
+ split (src, now);
207
+ int C = 4 ;
208
+ int n = 50 ;
209
+ float MaxCG = 5 ;
210
+ Mat dst1 = ACE (now[0 ], C, n, MaxCG);
211
+ Mat dst2 = ACE (now[1 ], C, n, MaxCG);
212
+ Mat dst3 = ACE (now[2 ], C, n, MaxCG);
213
+ now.clear ();
214
+ Mat dst;
215
+ now.push_back (dst1);
216
+ now.push_back (dst2);
217
+ now.push_back (dst3);
218
+ cv::merge (now, dst);
219
+ imshow (" origin" , src);
220
+ imshow (" result" , dst);
221
+ imwrite (" ../result.jpg" , dst);
222
+ waitKey (0 );
223
+ return 0 ;
224
+ }
0 commit comments