-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDenoisingAlgorithm.cpp
107 lines (96 loc) · 3.4 KB
/
DenoisingAlgorithm.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include "pch.h"
#include "DenoisingAlgorithm.h"
#define MAX_KERNEL_SIZE 100
double gaussianSpatialLUT[MAX_KERNEL_SIZE];
//double gaussianRangeLUT[256];
double gaussianRangeLUT[4096];
inline unsigned short saturate_12bit(int v)
{
if (v > 4095) v = 4095;
else if (v < 0) v = 0;
return v;
}
//// 创建空间高斯查找表
//void createGaussianSpatialLUT(double sigma, int radius)
//{
// for (int i = 0; i <= radius; i++) {
// gaussianSpatialLUT[i] = exp(-(i * i) / (2.0 * sigma * sigma));
// }
//}
//
//// 创建强度高斯查找表
//void createGaussianRangeLUT(double sigma)
//{
// for (int i = 0; i < 256; i++) {
// gaussianRangeLUT[i] = exp(-(i * i) / (2.0 * sigma * sigma));
// }
//}
//
//// 双边滤波
//void bilateralFilter(unsigned char* src, unsigned char* dst, int width, int height, int radius, double sigmaI, double sigmaS)
//{
// createGaussianSpatialLUT(sigmaS, radius);
// createGaussianRangeLUT(sigmaI);
//
// for (int i = 0; i < height; i++) {
// for (int j = 0; j < width; j++) {
// double val = 0.0;
// double sum = 0.0;
// for (int k = -radius; k <= radius; k++) {
// for (int l = -radius; l <= radius; l++) {
// int x = j + l;
// int y = i + k;
// if (x >= 0 && x < width && y >= 0 && y < height) {
// double gs = gaussianSpatialLUT[abs(k)] * gaussianSpatialLUT[abs(l)];
// int intensityDiff = abs(src[y * width + x] - src[i * width + j]);
// double gr = gaussianRangeLUT[intensityDiff];
// double w = gs * gr;
// val += src[y * width + x] * w;
// sum += w;
// }
// }
// }
// dst[i * width + j] = (unsigned char)(sum == 0 ? 0 : (val / sum));
// }
// }
//}
// 创建空间高斯查找表
void createGaussianSpatialLUT(double sigma, int radius)
{
for (int i = 0; i <= radius; i++) {
gaussianSpatialLUT[i] = exp(-(i * i) / (2.0 * sigma * sigma));
}
}
// 创建强度高斯查找表
void createGaussianRangeLUT(double sigma)
{
for (int i = 0; i < 4096; i++) {
gaussianRangeLUT[i] = exp(-(i * i) / (2.0 * sigma * sigma));
}
}
void bilateralFilter(int width, int height, int radius, double sigmaI, double sigmaS, unsigned short* inputImg, unsigned short* outputImg)
{
createGaussianSpatialLUT(sigmaS, radius);
createGaussianRangeLUT(sigmaI);
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
double val = 0.0;
double sum = 0.0;
for (int k = -radius; k <= radius; k++) {
for (int l = -radius; l <= radius; l++) {
int x = j + l;
int y = i + k;
if (x >= 0 && x < width && y >= 0 && y < height) {
double gs = gaussianSpatialLUT[abs(k)] * gaussianSpatialLUT[abs(l)];
int intensityDiff = abs(inputImg[y * width + x] - inputImg[i * width + j]);
double gr = gaussianRangeLUT[intensityDiff];
double w = gs * gr;
val += inputImg[y * width + x] * w;
sum += w;
}
}
}
outputImg[i * width + j] = saturate_12bit(sum == 0 ? 0 : (val / sum));
}
}
}