压缩编码算法评价 PSNR

MSE: 均方误差

峰值信噪比: PSNR

假定图像大小为NxN

MSE = 1/(N*N) sum((xi- x)*(xi-x))

PSNR = 10 * log10(255*255/MSE)

 

具体C代码如下:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <math.h>
  4
  5 typedef unsigned char uint8_t;
  6
  7 typedef struct{
  8     uint8_t *y;
  9     uint8_t *u;
 10     uint8_t *v;
 11 }image_t;
 12
 13 #define MALLC_AND_CHECK(p, size) p = malloc(size);/
 14     if (p == NULL)/
 15     {/
 16     printf("malloc "#p" error/n");/
 17     goto error_out;/
 18     }
 19
 20 #define CHECK_AND_FREE(p) if (p != NULL)/
 21     {/
 22         free(p);/
 23     }
 24
 25 double calc_mse(image_t *img_org, image_t *img_dec, int width, int height)
 26 {
 27     int i, j;
 28     double sum;
 29     uint8_t *py_org, *py_dec;
 30     uint8_t *pu_org, *pu_dec;
 31     uint8_t *pv_org, *pv_dec;
 32     int diff_val;
 33
 34     py_org = img_org->y;
 35     py_dec = img_dec->y;
 36     pu_org = img_org->u;
 37     pu_dec = img_dec->u;
 38     pv_org = img_org->v;
 39     pv_dec = img_dec->v;
 40
 41     sum = 0;
 42     for (i = 0; i < height; i++)
 43     {
 44         for (j = 0; j < width; j++)
 45         {
 46             diff_val = *py_org - *py_dec;
 47             sum += diff_val * diff_val;
 48             py_org++;
 49             py_dec++;
 50         }
 51     }
 52     for (i = 0; i < height/2; i++)
 53     {
 54         for (j = 0; j < width/2; j++)
 55         {
 56             diff_val = *pu_org - *pu_dec;
 57             sum += diff_val * diff_val;
 58             diff_val = *pv_org - *pv_dec;
 59             sum += diff_val * diff_val;
 60             pu_org++;
 61             pu_dec++;
 62             pv_org++;
 63             pv_dec++;
 64         }
 65     }
 66     sum = sum / (3 * width * height / 2);
 67     return sum;
 68 }
 69
 70 double psnr(double mse)
 71 {
 72     return 10 * log10f(255.0 * 255.0 / mse);
 73 }
 74
 75 int main(int argc, char **argv)
 76 {
 77     image_t *img_org;
 78     image_t *img_dec;
 79     int width, height;
 80     FILE *fp_org;
 81     FILE *fp_dec;
 82     int i;
 83     int ret_val;
 84     int frame_cnt = 0;
 85     double mse;
 86     double psnr_sum = 0;
 87
 88     if (argc < 7)
 89     {
 90         printf("Not enough parameters!/n");
 91         printf("/tUseage: calc_psnr -w 352 -h 288 infile1 infile2/n");
 92         printf("/t-w: width/n");
 93         printf("/t-h: height/n");
 94         return -1;
 95     }
 96
 97     width = 0;
 98     height = 0;
 99     fp_org = NULL;
100     fp_dec = NULL;
101     for (i = 1; i < 7; i++)
102     {
103         if (strcmp(argv[i], "-w") == 0)
104         {
105             width = atoi(argv[i+1]);
106             i++;
107             continue;
108         }
109         else if (strcmp(argv[i], "-h") == 0)
110         {
111             height = atoi(argv[i+1]);
112             i++;
113             continue;
114         }
115         else if (fp_org == NULL)
116         {
117             fp_org = fopen(argv[i], "rb");
118             if (fp_org == NULL)
119             {
120                 printf("can't open file %s/n", argv[i]);
121                 goto error_out;
122             }
123         }
124         else if (fp_dec == NULL)
125         {
126             fp_dec = fopen(argv[i], "rb");
127             if (fp_dec == NULL)
128             {
129                 printf("can't open file %s./n", argv[i]);
130                 goto error_out;
131             }
132         }
133     }
134
135     if (width < 0 || width > 2048)
136     {
137         printf("illeagle width!/n");
138         goto error_out;
139     }
140     if (height < 0 || height > 2048)
141     {
142         printf("illedgle height!/n");
143         goto error_out;
144     }
145
146     MALLC_AND_CHECK(img_org, sizeof(image_t));
147     MALLC_AND_CHECK(img_dec, sizeof(image_t));
148     MALLC_AND_CHECK(img_org->y, width*height);
149     MALLC_AND_CHECK(img_org->u, width*height/4);
150     MALLC_AND_CHECK(img_org->v, width*height/4);
151     MALLC_AND_CHECK(img_dec->y, width*height);
152     MALLC_AND_CHECK(img_dec->u, width*height/4);
153     MALLC_AND_CHECK(img_dec->v, width*height/4);
154
155     while (1)
156     {
157         ret_val = fread(img_org->y, 1, width * height, fp_org);
158         if (ret_val != width * height)
159         {
160             break;
161         }
162         ret_val = fread(img_org->u, 1, width * height / 4, fp_org);
163         if (ret_val != width * height / 4)
164         {
165             break;
166         }
167         ret_val = fread(img_org->v, 1, width * height /4, fp_org);
168         if (ret_val != width * height / 4)
169         {
170             break;
171         }
172         ret_val = fread(img_dec->y, 1, width * height, fp_dec);
173         if (ret_val != width * height)
174         {
175             break;
176         }
177         ret_val = fread(img_dec->u, 1, width * height / 4, fp_dec);
178         if (ret_val != width * height / 4)
179         {
180             break;
181         }
182         ret_val = fread(img_dec->v, 1, width * height /4, fp_dec);
183         if (ret_val != width * height / 4)
184         {
185             break;
186         }
187         frame_cnt++;
188         mse = calc_mse(img_org, img_dec, width, height);
189         psnr_sum += psnr(mse);
190     }
191     printf("frame_cnt = %d./n", frame_cnt);
192     printf("average psnr = %f/n", psnr_sum/frame_cnt);
193
194 error_out:
195     if (fp_org != NULL)
196     {
197         fclose(fp_org);
198     }
199     if (fp_dec != NULL)
200     {
201         fclose(fp_dec);
202     }
203     
204     CHECK_AND_FREE(img_org->y);
205     CHECK_AND_FREE(img_org->u);
206     CHECK_AND_FREE(img_org->v);
207     CHECK_AND_FREE(img_dec->y);
208     CHECK_AND_FREE(img_dec->u);
209     CHECK_AND_FREE(img_dec->v);
210     CHECK_AND_FREE(img_org);
211     CHECK_AND_FREE(img_dec);
212
213     return 0;
214 }
215

 

 

你可能感兴趣的:(压缩编码算法评价 PSNR)