|
| 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