Skip to content

Commit b953540

Browse files
committed
Update AutoLevelAndAutoContrast
1 parent 4a089d3 commit b953540

File tree

2 files changed

+242
-0
lines changed

2 files changed

+242
-0
lines changed

AutoLevelAndAutoContrast.cpp

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
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+
}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- Local Color Correction.cpp C++复现了《Local Color Correction》论文,详情请参考:https://blog.csdn.net/just_sort/article/details/84539295
99
- PartialcolorJudge.cpp C++复现了《基于图像分析的偏色检测及颜色校正方法》论文,实现快速判断图片是否存在偏色,详情请看:https://blog.csdn.net/just_sort/article/details/84897976
1010
- Optimized contrast enhancement for real-time image and video dehazin.cpp 复现了《Optimized contrast enhancement for real-time image and video dehazin》这篇论文,相对于He Kaiming的暗通道去雾,对天空具有天然的免疫力。详情请看:https://blog.csdn.net/just_sort/article/details/84932848
11+
- AutoLevelAndAutoContrast.cpp C++复现了自动色阶调整和自动对比度调整,其中自动色阶调整可以用于去雾和水下图像恢复,算法原理请看:https://www.cnblogs.com/Imageshop/archive/2011/11/13/2247614.html
1112

1213
# ImageFiletering实现了各种滤波算法
1314

0 commit comments

Comments
 (0)