1+ #include " opencv2/opencv.hpp"
2+ #include " iostream"
3+ #include " algorithm"
4+ #include " vector"
5+ using namespace std ;
6+ using namespace cv ;
7+
8+ Mat AutoLevel (Mat src, double LowCut, double HighCut){
9+ int rows = src.rows ;
10+ int cols = src.cols ;
11+ int totalPixel = rows * cols;
12+ // 统计每个通道的直方图
13+ uchar Pixel[256 *3 ] = {0 };
14+ vector <Mat> rgb;
15+ split (src, rgb);
16+ Mat HistBlue, HistGreen, HistRed;
17+ int histSize = 256 ;
18+ float range[] = {0 , 255 };
19+ const float * histRange = {range};
20+ bool uniform = true ;
21+ bool accumulate = false ;
22+ calcHist (&rgb[0 ], 1 , 0 , Mat (), HistRed, 1 , &histSize, &histRange, uniform, accumulate);
23+ calcHist (&rgb[1 ], 1 , 0 , Mat (), HistGreen, 1 , &histSize, &histRange, uniform, accumulate);
24+ calcHist (&rgb[2 ], 1 , 0 , Mat (), HistBlue, 1 , &histSize, &histRange, uniform, accumulate);
25+ // 分别计算各通道按照给定的参数所确定的上下限值
26+ int MinBlue = 0 , MaxBlue = 0 ;
27+ int MinRed = 0 , MaxRed = 0 ;
28+ int MinGreen = 0 , MaxGreen = 0 ;
29+
30+ // Blue Channel
31+ float sum = 0 ;
32+ sum = 0 ;
33+ for (int i = 0 ; i < 256 ; i++){
34+ sum += HistBlue.at <float >(i);
35+ if (sum >= totalPixel * LowCut * 0.01 ){
36+ MinBlue = i;
37+ break ;
38+ }
39+ }
40+ sum = 0 ;
41+ for (int i = 255 ; i >= 0 ; i--){
42+ sum = sum + HistBlue.at <float >(i);
43+ if (sum >= totalPixel * HighCut * 0.01 ){
44+ MaxBlue = i;
45+ break ;
46+ }
47+ }
48+ // Red channel
49+ for (int i = 0 ; i < 256 ; i++){
50+ sum += HistRed.at <float >(i);
51+ if (sum >= totalPixel * LowCut * 0.01 ){
52+ MinRed = i;
53+ break ;
54+ }
55+ }
56+ sum = 0 ;
57+ for (int i = 255 ; i >= 0 ; i--){
58+ sum = sum + HistRed.at <float >(i);
59+ if (sum >= totalPixel * HighCut * 0.01 ){
60+ MaxRed = i;
61+ break ;
62+ }
63+ }
64+ // Green channel
65+ sum = 0 ;
66+ for (int i = 0 ; i < 256 ; i++){
67+ sum += HistGreen.at <float >(i);
68+ if (sum >= totalPixel * LowCut * 0.01 ){
69+ MinGreen = i;
70+ break ;
71+ }
72+ }
73+ sum = 0 ;
74+ for (int i = 255 ; i >= 0 ; i--){
75+ sum = sum + HistGreen.at <float >(i);
76+ if (sum >= totalPixel * HighCut * 0.01 ){
77+ MaxGreen = i;
78+ break ;
79+ }
80+ }
81+ printf (" %d %d %d %d %d %d\n " , MinGreen, MaxGreen, MinBlue, MaxBlue, MinRed, MaxRed);
82+ // 自动色阶:按照我们刚刚计算出的MinBlue/MaxBlue构建一个隐射表
83+ for (int i = 0 ; i < 256 ; i++){
84+ if (i <= MinBlue){
85+ Pixel[i*3 +2 ] = 0 ;
86+ }else {
87+ if (i > MaxBlue){
88+ Pixel[i*3 +2 ] = 255 ;
89+ }else {
90+ float temp = (float )(i - MinBlue) / (MaxBlue - MinBlue);
91+ Pixel[i*3 +2 ] = (uchar)(temp*255 );
92+ }
93+ }
94+ if (i <= MinGreen){
95+ Pixel[i*3 +1 ] = 0 ;
96+ }else {
97+ if (i > MaxGreen){
98+ Pixel[i*3 +1 ] = 255 ;
99+ }else {
100+ float temp = (float )(i - MinGreen) / (MaxGreen - MinGreen);
101+ Pixel[i*3 +1 ] = (uchar)(temp*255 );
102+ }
103+ }
104+ if (i <= MinRed){
105+ Pixel[i*3 ] = 0 ;
106+ }else {
107+ if (i > MaxRed){
108+ Pixel[i*3 ] = 255 ;
109+ }else {
110+ float temp = (float )(i - MinRed) / (MaxRed - MinRed);
111+ Pixel[i*3 ] = (uchar)(temp*255 );
112+ }
113+ }
114+ }
115+ Mat dst;
116+ Mat TMP (1 , 256 , CV_8UC3, Pixel);
117+ LUT (src, TMP, dst);
118+ return dst;
119+ }
120+
121+ Mat AutoContrast (Mat src, double LowCut, double HighCut){
122+ int rows = src.rows ;
123+ int cols = src.cols ;
124+ int totalPixel = rows * cols;
125+ // 统计每个通道的直方图
126+ uchar Pixel[256 *3 ] = {0 };
127+ vector <Mat> rgb;
128+ split (src, rgb);
129+ Mat HistBlue, HistGreen, HistRed;
130+ int histSize = 256 ;
131+ float range[] = {0 , 255 };
132+ const float * histRange = {range};
133+ bool uniform = true ;
134+ bool accumulate = false ;
135+ calcHist (&rgb[0 ], 1 , 0 , Mat (), HistRed, 1 , &histSize, &histRange, uniform, accumulate);
136+ calcHist (&rgb[1 ], 1 , 0 , Mat (), HistGreen, 1 , &histSize, &histRange, uniform, accumulate);
137+ calcHist (&rgb[2 ], 1 , 0 , Mat (), HistBlue, 1 , &histSize, &histRange, uniform, accumulate);
138+ // 分别计算各通道按照给定的参数所确定的上下限值
139+ int MinBlue = 0 , MaxBlue = 0 ;
140+ int MinRed = 0 , MaxRed = 0 ;
141+ int MinGreen = 0 , MaxGreen = 0 ;
142+
143+ // Blue Channel
144+ float sum = 0 ;
145+ sum = 0 ;
146+ for (int i = 0 ; i < 256 ; i++){
147+ sum += HistBlue.at <float >(i);
148+ if (sum >= totalPixel * LowCut * 0.01 ){
149+ MinBlue = i;
150+ break ;
151+ }
152+ }
153+ sum = 0 ;
154+ for (int i = 255 ; i >= 0 ; i--){
155+ sum = sum + HistBlue.at <float >(i);
156+ if (sum >= totalPixel * HighCut * 0.01 ){
157+ MaxBlue = i;
158+ break ;
159+ }
160+ }
161+ // Red channel
162+ for (int i = 0 ; i < 256 ; i++){
163+ sum += HistRed.at <float >(i);
164+ if (sum >= totalPixel * LowCut * 0.01 ){
165+ MinRed = i;
166+ break ;
167+ }
168+ }
169+ sum = 0 ;
170+ for (int i = 255 ; i >= 0 ; i--){
171+ sum = sum + HistRed.at <float >(i);
172+ if (sum >= totalPixel * HighCut * 0.01 ){
173+ MaxRed = i;
174+ break ;
175+ }
176+ }
177+ // Green channel
178+ sum = 0 ;
179+ for (int i = 0 ; i < 256 ; i++){
180+ sum += HistGreen.at <float >(i);
181+ if (sum >= totalPixel * LowCut * 0.01 ){
182+ MinGreen = i;
183+ break ;
184+ }
185+ }
186+ sum = 0 ;
187+ for (int i = 255 ; i >= 0 ; i--){
188+ sum = sum + HistGreen.at <float >(i);
189+ if (sum >= totalPixel * HighCut * 0.01 ){
190+ MaxGreen = i;
191+ break ;
192+ }
193+ }
194+ int minn = min (MinBlue, min (MinGreen, MinRed));
195+ int maxx = max (MaxBlue, max (MaxGreen, MaxRed));
196+ // 自动对比度
197+ for (int i = 0 ; i < 256 ; i++){
198+ if (i <= minn){
199+ Pixel[i*3 +2 ] = 0 ;
200+ }else {
201+ if (i > maxx){
202+ Pixel[i*3 +2 ] = 255 ;
203+ }else {
204+ float temp = (float )(i - minn) / (maxx - minn);
205+ Pixel[i*3 +2 ] = (uchar)(temp*255 );
206+ }
207+ }
208+ if (i <= minn){
209+ Pixel[i*3 +1 ] = 0 ;
210+ }else {
211+ if (i > maxx){
212+ Pixel[i*3 +1 ] = 255 ;
213+ }else {
214+ float temp = (float )(i - minn) / (maxx - minn);
215+ Pixel[i*3 +1 ] = (uchar)(temp*255 );
216+ }
217+ }
218+ if (i <= minn){
219+ Pixel[i*3 ] = 0 ;
220+ }else {
221+ if (i > maxx){
222+ Pixel[i*3 ] = 255 ;
223+ }else {
224+ float temp = (float )(i - minn) / (maxx - minn);
225+ Pixel[i*3 ] = (uchar)(temp*255 );
226+ }
227+ }
228+ }
229+ Mat dst;
230+ Mat TMP (1 , 256 , CV_8UC3, Pixel);
231+ LUT (src, TMP, dst);
232+ return dst;
233+ }
234+
235+ int main (){
236+ Mat src = imread (" ../3.png" );
237+ Mat dst = AutoLevel (src, 0.005 , 0.005 );
238+ imshow (" origin" , src);
239+ imshow (" result" , dst);
240+ waitKey (0 );
241+ }
0 commit comments