1
+ Mat RGB2HSV (Mat src) {
2
+ int row = src.rows ;
3
+ int col = src.cols ;
4
+ Mat dst (row, col, CV_32FC3);
5
+ for (int i = 0 ; i < row; i++) {
6
+ for (int j = 0 ; j < col; j++) {
7
+ float b = src.at <Vec3b>(i, j)[0 ] / 255.0 ;
8
+ float g = src.at <Vec3b>(i, j)[1 ] / 255.0 ;
9
+ float r = src.at <Vec3b>(i, j)[2 ] / 255.0 ;
10
+ float minn = min (r, min (g, b));
11
+ float maxx = max (r, max (g, b));
12
+ dst.at <Vec3f>(i, j)[2 ] = maxx; // V
13
+ float delta = maxx - minn;
14
+ float h, s;
15
+ if (maxx != 0 ) {
16
+ s = delta / maxx;
17
+ }
18
+ else {
19
+ s = 0 ;
20
+ }
21
+ if (r == maxx) {
22
+ h = (g - b) / delta;
23
+ }
24
+ else if (g == maxx) {
25
+ h = 2 + (b - r) / delta;
26
+ }
27
+ else {
28
+ h = 4 + (r - g) / delta;
29
+ }
30
+ h *= 60 ;
31
+ if (h < 0 )
32
+ h += 360 ;
33
+ dst.at <Vec3f>(i, j)[0 ] = h;
34
+ dst.at <Vec3f>(i, j)[1 ] = s;
35
+ }
36
+ }
37
+ return dst;
38
+ }
39
+
40
+ Mat HSV2RGB (Mat src) {
41
+ int row = src.rows ;
42
+ int col = src.cols ;
43
+ Mat dst (row, col, CV_8UC3);
44
+ float r, g, b, h, s, v;
45
+ for (int i = 0 ; i < row; i++) {
46
+ for (int j = 0 ; j < col; j++) {
47
+ h = src.at <Vec3f>(i, j)[0 ];
48
+ s = src.at <Vec3f>(i, j)[1 ];
49
+ v = src.at <Vec3f>(i, j)[2 ];
50
+ if (s == 0 ) {
51
+ r = g = b = v;
52
+ }
53
+ else {
54
+ h /= 60 ;
55
+ int offset = floor (h);
56
+ float f = h - offset;
57
+ float p = v * (1 - s);
58
+ float q = v * (1 - s * f);
59
+ float t = v * (1 - s * (1 - f));
60
+ switch (offset)
61
+ {
62
+ case 0 : r = v; g = t; b = p; break ;
63
+ case 1 : r = q; g = v; b = p; break ;
64
+ case 2 : r = p; g = v; b = t; break ;
65
+ case 3 : r = p; g = q; b = v; break ;
66
+ case 4 : r = t; g = p; b = v; break ;
67
+ case 5 : r = v; g = p; b = q; break ;
68
+ default :
69
+ break ;
70
+ }
71
+ }
72
+ dst.at <Vec3b>(i, j)[0 ] = int (b * 255 );
73
+ dst.at <Vec3b>(i, j)[1 ] = int (g * 255 );
74
+ dst.at <Vec3b>(i, j)[2 ] = int (r * 255 );
75
+ }
76
+ }
77
+ return dst;
78
+ }
79
+
80
+ Mat work (Mat src) {
81
+ int row = src.rows ;
82
+ int col = src.cols ;
83
+ Mat now = RGB2HSV (src);
84
+ Mat H (row, col, CV_32FC1);
85
+ Mat S (row, col, CV_32FC1);
86
+ Mat V (row, col, CV_32FC1);
87
+ for (int i = 0 ; i < row; i++) {
88
+ for (int j = 0 ; j < col; j++) {
89
+ H.at <float >(i, j) = now.at <Vec3f>(i, j)[0 ];
90
+ S.at <float >(i, j) = now.at <Vec3f>(i, j)[1 ];
91
+ V.at <float >(i, j) = now.at <Vec3f>(i, j)[2 ];
92
+ }
93
+ }
94
+ int kernel_size = min (row, col);
95
+ if (kernel_size % 2 == 0 ) {
96
+ kernel_size -= 1 ;
97
+ }
98
+ float SIGMA1 = 15 ;
99
+ float SIGMA2 = 80 ;
100
+ float SIGMA3 = 250 ;
101
+ float q = sqrtf (2.0 );
102
+ Mat F (row, col, CV_32FC1);
103
+ Mat F1 (row, col, CV_32FC1);
104
+ Mat F2 (row, col, CV_32FC1);
105
+ Mat F3 (row, col, CV_32FC1);
106
+ GaussianBlur (V, F1, Size (kernel_size, kernel_size), SIGMA1 / q);
107
+ GaussianBlur (V, F2, Size (kernel_size, kernel_size), SIGMA2 / q);
108
+ GaussianBlur (V, F3, Size (kernel_size, kernel_size), SIGMA3 / q);
109
+ for (int i = 0 ; i < row; i++) {
110
+ for (int j = 0 ; j < col; j++) {
111
+ F.at <float >(i, j) = (F1.at <float >(i, j) + F2.at <float >(i, j) + F3.at <float >(i, j)) / 3.0 ;
112
+ }
113
+ }
114
+ float average = mean (F)[0 ];
115
+ Mat out (row, col, CV_32FC1);
116
+ for (int i = 0 ; i < row; i++) {
117
+ for (int j = 0 ; j < col; j++) {
118
+ float gamma = powf (0.5 , (average - F.at <float >(i, j)) / average);
119
+ out.at <float >(i, j) = powf (V.at <float >(i, j), gamma );
120
+ }
121
+ }
122
+ vector <Mat> v;
123
+ v.push_back (H);
124
+ v.push_back (S);
125
+ v.push_back (out);
126
+ Mat merge_;
127
+ merge (v, merge_);
128
+ Mat dst = HSV2RGB (merge_);
129
+ return dst;
130
+ }
0 commit comments