2

512*512のRAW画像でDCT/IDCTを実行しています。

しかし、私のプログラムはPSNR17.54dbしかない画像を出力できました。

私は自分の数式を数回チェックしましたが、誰かがこれについて私を助けてくれますか?

これは元の写真です

IDCT後

#include <stdio.h>
#include <math.h>
#define N 512

double COS[8][8], C[8];
unsigned char pic[N][N];
double dct[N][N], idct[N][N];

void init() {
  int i, j;
  for (i = 0; i < 8; i++) {
    for (j = 0; j < 8; j++)
      COS[i][j] = cos((2 * i + 1) * j * acos(-1) / 16.0);
    if (i) C[i] = 1;
    else C[i] = 1 / sqrt(2);
  }
}

void DCT() {
  freopen("dct.raw", "wb", stdout);
  int r, c, i, j, x, y;
  for (r = 0; r < 64; r++)
    for (c = 0; c < 64; c++)
      for (i = 0; i < 8; i++)
        for (j = 0; j < 8; j++) {
          double sum = 0;
          for (x = 0; x < 8; x++)
            for (y = 0; y < 8; y++)
              sum += (pic[r * 8 + x][c * 8 + y] - 128) * COS[x][i] * COS[y][j];
          sum *= C[i] * C[j] * 0.25;
          if (sum < 0) sum = 0;
          if (sum > 255) sum = 255;
          dct[r * 8 + i][c * 8 + j] = sum;
      }
  for (r = 0; r < N; r++)
    for (c = 0; c < N; c++)
      putchar(dct[r][c]);
}

void IDCT() {
  freopen("idct.raw", "wb", stdout);
  int r, c, i, j, x, y;
  for (r = 0; r < 64; r++)
    for (c = 0; c < 64; c++)
      for (i = 0; i < 8; i++)
        for (j = 0; j < 8; j++) {
          double sum = 0;
          for (x = 0; x < 8; x++)
            for (y = 0; y < 8; y++)
              sum += C[x] * C[y] * dct[r * 8 + x][c * 8 + y] * COS[i][x] * COS[j][y];
          sum *= 0.25;
          sum += 128;
          if (sum < 0) sum = 0;
          if (sum > 255) sum = 255;
          idct[r * 8 + i][c * 8 + j] = sum;
      }
  for (r = 0; r < N; r++)
    for (c = 0; c < N; c++)
      putchar(idct[r][c]);
}

int main() {
  freopen("Lena.raw", "rb", stdin);
  int r, c;
  for (r = 0; r < N; r++)
    for (c = 0; c < N; c++)
      scanf("%c", &pic[r][c]);
  init();
  DCT();
  IDCT();
  return 0;
}
4

1 に答える 1

2

問題は、DCT コードのこれらの行です。

      if (sum < 0) sum = 0;
      if (sum > 255) sum = 255;

DCT 値を 0 <= 値 <= 255 にクランプしています

そうではないかもしれません。たとえば、負の係数があります。これらの行を削除してみて、役立つかどうかを確認してください

于 2012-12-08T09:29:32.560 に答える