Skip to content

Commit 6120d1f

Browse files
authored
Median Filter with Metric Calculation
Median Filter is a good way to remove Salt and Pepper Noise. Better the Metrics Better the Quality Of Output Image
1 parent 5154127 commit 6120d1f

File tree

1 file changed

+187
-0
lines changed

1 file changed

+187
-0
lines changed
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
#include<stdio.h>
2+
#include<string.h>
3+
#include<math.h>
4+
#include<time.h>
5+
#define W_MAX 1
6+
#define ROW 512
7+
#define COL 512
8+
#define T1 15
9+
#define T2 25
10+
11+
double P[50]; double img[700][700]; double orig[512][512];
12+
13+
// Utility Function - Creates input image matrix
14+
double getImg(char *s){
15+
FILE *fp;
16+
int i, j, r, c; double d, MSE = 0, dim = ROW * COL;
17+
fp = fopen(s, "r");
18+
// Create Matrix
19+
for(i = W_MAX; i < ROW+W_MAX; i++){
20+
for(j = W_MAX; j < COL+W_MAX; j++){
21+
fscanf(fp, "%lf ", &d);
22+
img[i][j] = d;
23+
MSE += pow((orig[i-W_MAX][j-W_MAX] - img[i][j]), 2);
24+
// Padding
25+
if (i == W_MAX){
26+
for(r = i-1; r >= i-W_MAX; r--) img[r][j] = img[i][j];
27+
}
28+
if(i == W_MAX + ROW - 1){
29+
for(r = i+1; r <= i+W_MAX; r++) img[r][j] = img[i][j];
30+
}
31+
if(j == W_MAX){
32+
for(c = j-1; c >= j-W_MAX; c--) img[i][c] = img[i][j];
33+
}
34+
if(j == W_MAX + COL - 1){
35+
for(c = j+1; c <= j+W_MAX; c++) img[i][c] = img[i][j];
36+
}
37+
}
38+
}
39+
// Corner Padding
40+
// Upper Corners
41+
for(i = 0; i < W_MAX; i++){
42+
// Left Corner
43+
for(j = 0; j < W_MAX; j++)
44+
img[i][j] = img[W_MAX][W_MAX];
45+
// Right Corner
46+
for(j = W_MAX+ COL; j< W_MAX+COL+W_MAX;j++)
47+
img[i][j] = img[W_MAX][W_MAX+COL-1];
48+
}
49+
// Lower Corners
50+
for(i = W_MAX+ROW; i < W_MAX+ROW+W_MAX; i++){
51+
// Left Corner
52+
for(j = 0; j < W_MAX; j++)
53+
img[i][j] = img[W_MAX+ROW-1][W_MAX];
54+
// Right Corner
55+
for(j = W_MAX+ COL; j< W_MAX+COL+W_MAX;j++)
56+
img[i][j] = img[W_MAX+ROW-1][W_MAX+COL-1];
57+
}
58+
59+
fclose(fp);
60+
MSE /= dim;
61+
return MSE;
62+
}
63+
64+
// Utility Function - Saves output image
65+
double saveImg(char *s){
66+
FILE *fp;
67+
fp = fopen(s, "w");
68+
// Change According to size
69+
fprintf(fp, "P2 512 512 255\n");
70+
int i, j; double MSE = 0, dim = ROW*COL;
71+
for(i = W_MAX; i < ROW + W_MAX; i++){
72+
for(j = W_MAX; j< COL + W_MAX; j++){
73+
MSE += pow((orig[i-W_MAX][j-W_MAX] - img[i][j]), 2);
74+
fprintf(fp, "%d ", (int)img[i][j]);
75+
}
76+
}
77+
fclose(fp);
78+
MSE /= dim;
79+
return MSE;
80+
}
81+
82+
// Calculates Structural Similarity Index of Images
83+
double getSSIM(){
84+
double C1 = pow(0.01*255, 2), C2 = pow(0.03*255, 2), dim = ROW * COL;
85+
double Vx = 0, Vy = 0, COV = 0, SSIM, o, e;
86+
int i, j, ux = 0, uy = 0;
87+
for(i = W_MAX; i < ROW + W_MAX; i++){
88+
for(j = W_MAX; j< COL + W_MAX; j++){
89+
ux += orig[i-W_MAX][j-W_MAX];
90+
uy += img[i][j];
91+
}
92+
}
93+
ux /= dim; uy /= dim;
94+
for(i = W_MAX; i < ROW + W_MAX; i++){
95+
for(j = W_MAX; j< COL + W_MAX; j++){
96+
o = orig[i-W_MAX][j-W_MAX];
97+
e = img[i][j];
98+
Vx += pow((o-ux),2);
99+
Vy += pow((e-uy), 2);
100+
COV += (o-ux)*(e-uy);
101+
}
102+
}
103+
Vx /= dim; Vy /= dim;
104+
COV /= dim;
105+
SSIM = ((2*ux*uy + C1) * (2*COV + C2))/((pow(ux, 2) + pow(uy, 2) + C1) * (Vx + Vy + C2));
106+
return SSIM;
107+
}
108+
109+
// Utility - Returns median of first n numbers in P
110+
double Median(int n){
111+
int i, d; double t, ans;
112+
// Sort the array - Insertion sort
113+
for(i = 1; i < n; i++){
114+
d = i;
115+
while (d > 0 && P[d] < P[d-1]){
116+
t = P[d];
117+
P[d] = P[d-1];
118+
P[d-1] = t;
119+
d--;
120+
}
121+
}
122+
// If n odd return mid element
123+
if (n&1)
124+
ans = P[n/2];
125+
// Else retuen
126+
else
127+
ans = (P[n/2 - 1] + P[n/2])/2;
128+
return ans;
129+
}
130+
131+
// Filter - Median Filtering
132+
double Filter(int r, int c){
133+
int cnt = 0, i, j, w=1; double M;
134+
for(i = r-w; i <= r+w; i++){
135+
for(j = c-w; j <= c+w; j++){
136+
P[cnt++] = img[i][j];
137+
}
138+
}
139+
M = Median(cnt);
140+
return M;
141+
}
142+
143+
// Standard Median Filtering
144+
double SMF(char *s){
145+
int i, j; double MSE;
146+
for(i = W_MAX; i < ROW + W_MAX; i++){
147+
for(j = W_MAX; j < COL + W_MAX; j++){
148+
// if(img[i][j]==0 || img[i][j]==255)
149+
img[i][j] = Filter(i, j);
150+
}
151+
}
152+
// Metric Calculation
153+
MSE = saveImg(s);
154+
return MSE;
155+
}
156+
157+
int main() {
158+
int i, j;
159+
clock_t start, end; double CPU_TIME;
160+
double MAXINT = pow(255, 2), RMSE, MSE1, MSE2, PSNR, d, IEF, SSIM;
161+
162+
// Get Original Image for PSNR calculation
163+
FILE *fp;
164+
fp = fopen("Original_Image.pgm", "r");
165+
for(i = 0; i < ROW; i++){
166+
for(j = 0; j < COL; j++){
167+
fscanf(fp, "%lf ", &d);
168+
orig[i][j] = d;
169+
}
170+
}
171+
fclose(fp);
172+
173+
start = clock();
174+
// Replace this with the src image name and the dest image name where the image needs to be saved
175+
MSE1 = getImg("Src Image");
176+
MSE2 = SMF("Dest Image");
177+
end = clock();
178+
CPU_TIME = ((double) (end - start)) / CLOCKS_PER_SEC;
179+
// Peak Signal to Noise Ratio
180+
PSNR = 10 * log10(MAXINT/MSE2);
181+
// MSE1 (orig, noisy), MSE2 (orig, enhanced)
182+
IEF = MSE1/MSE2;
183+
RMSE = pow(MSE2, 0.5);
184+
SSIM = getSSIM();
185+
printf("RMSE = %.4lf\tPSNR = %.4lf\tSSIM = %lf\tIEF = %.4lf\tTIME = %.2lfs\n", RMSE, PSNR, SSIM, IEF, CPU_TIME);
186+
}
187+
}

0 commit comments

Comments
 (0)