Skip to content

Commit 051f21c

Browse files
committed
Add ACE.cpp
1 parent 1e7e8c1 commit 051f21c

File tree

3 files changed

+226
-1
lines changed

3 files changed

+226
-1
lines changed

Correction algorithm/ACE.cpp

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

Correction algorithm/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44

55
- HistograEqualization.cpp 直方图均衡化C++实现。原理请看:https://blog.csdn.net/just_sort/article/details/85013803
66

7+
- ACE.cpp 对《Real-time adptive contrast enhancement for imaging sensors》论文的C++复现,也就是自适应局部对比度增强。原理请看:https://blog.csdn.net/just_sort/article/details/85208124

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
## 3. Feature Extraction 复现了一些图像特征提取算法
88

9-
## 4. 大家有数字图像需要复现的论文可以在ISSUE提问,在本人能力范围内,我可以免费复现开源
9+
## 4. 有意思的论文可以在ISSUE发出来,在本人能力范围内,可以复现并开源
1010

1111
- Retinex MSRCR.cpp 带色彩恢复的多尺度视网膜增强算法。 算法原理请看:http://www.cnblogs.com/Imageshop/archive/2013/04/17/3026881.html
1212
- ImageDataIncrease.cpp 常见的图片数据扩充。包括一些PS算法 具体为旋转,添加高斯,椒盐噪声,增加老照片效果,增加和降低图像饱和度,对原图缩放,亮度增强,对比度增强,磨皮美白,偏色矫正,同态滤波,过曝,灰度化,轮换通道,图像错切,运动模糊,钝化蒙版,PS滤镜算法之球面化 (凸出和凹陷效果)

0 commit comments

Comments
 (0)