尝试实现 dct 8*8 矩阵的逆

发布于 2024-12-21 22:20:28 字数 1879 浏览 1 评论 0原文

我已经成功计算了 8*8 矩阵的 DCT,但在求逆时遇到了麻烦。谁能看一下这段代码并告诉我我现在在做什么。我应该得到与以前完全相同的值,但我得到不同的值。我正在读取 csv 文件的输入并将其输出到另一个 csv 文件中。它在c中编程

void idct_func(float inMatrix[8][8]){

double idct,
Cu,
sum,
Cv;

int i,
j,
u,
v;


float idctMatrix[8][8],
greyLevel;

FILE * fp = fopen("mydata.csv", "r");
FILE * wp = fopen("idct.csv", "w");
fprintf(fp, "\n Inverse DCT");                     

for (i = 0; i < 8; ++i) {
    for (j = 0; j < 8; ++j) { 
        sum = 0.0;  
        for (u = 0; u < 8; u++) {
            for (v = 0; v < 8; v++) {
            if (u == 0)
                Cu = 1.0 / sqrt(2.0);
            else
                Cu = 1.0;
            if (v == 0)
                Cv = 1.0 / sqrt(2.0);
            else
                Cv = (1.0);
            // Level around 0
            greyLevel = idctMatrix[u][v];
            idct = (greyLevel * cos((2 * i + 1) * u * M_PI / 16.0) *
                    cos((2 * j + 1) * v * M_PI / 16.0));
            sum += idct;
            }               
        }

        idctMatrix[i][j] = 0.25 * Cu * Cv * sum;
        fprintf(wp, "\n %f", idctMatrix[i][j]);         
    }
    fprintf(wp, "\n");
}

原始矩阵是:

{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255}};

dct是:

2040   0  -0   0   0   0  -0  -0
   0   0   0   0  -0   0  -0   0
  -0   0  -0   0   0   0   0   0
   0  -0  -0  -0   0  -0  -0   0
   0   0  -0   0  -0  -0  -0   0
   0  -0  -0  -0  -0   0  -0  -0
  -0  -0  -0   0   0   0   0  -0
  -0   0   0   0  -0   0  -0   0

计算出的idct应该与原始矩阵相同

I have managed to calculate the dct of an 8*8 matrix and I am having trouble doing the inverse. Can anyone have a look at this code and tell me what I am doing now. I should be getting the exact same values as before but im getting different values. I am reading in the input from a csv file and out putting it to anther csv file. Its programmed in c

void idct_func(float inMatrix[8][8]){

double idct,
Cu,
sum,
Cv;

int i,
j,
u,
v;


float idctMatrix[8][8],
greyLevel;

FILE * fp = fopen("mydata.csv", "r");
FILE * wp = fopen("idct.csv", "w");
fprintf(fp, "\n Inverse DCT");                     

for (i = 0; i < 8; ++i) {
    for (j = 0; j < 8; ++j) { 
        sum = 0.0;  
        for (u = 0; u < 8; u++) {
            for (v = 0; v < 8; v++) {
            if (u == 0)
                Cu = 1.0 / sqrt(2.0);
            else
                Cu = 1.0;
            if (v == 0)
                Cv = 1.0 / sqrt(2.0);
            else
                Cv = (1.0);
            // Level around 0
            greyLevel = idctMatrix[u][v];
            idct = (greyLevel * cos((2 * i + 1) * u * M_PI / 16.0) *
                    cos((2 * j + 1) * v * M_PI / 16.0));
            sum += idct;
            }               
        }

        idctMatrix[i][j] = 0.25 * Cu * Cv * sum;
        fprintf(wp, "\n %f", idctMatrix[i][j]);         
    }
    fprintf(wp, "\n");
}

the original matrix is:

{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255}};

the dct is :

2040   0  -0   0   0   0  -0  -0
   0   0   0   0  -0   0  -0   0
  -0   0  -0   0   0   0   0   0
   0  -0  -0  -0   0  -0  -0   0
   0   0  -0   0  -0  -0  -0   0
   0  -0  -0  -0  -0   0  -0  -0
  -0  -0  -0   0   0   0   0  -0
  -0   0   0   0  -0   0  -0   0

the idct calculated should be the same as the original

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

墨落画卷 2024-12-28 22:20:28

您尝试使用 idctMatrix[][] 作为输入和输出来就地计算 IDCT,因此在此过程中输入会被修改。那是错误的。您需要有一个单独的二维数组用于输入(或输出)。

看起来还与 u 和 v 相关的缩放因子 CuCv 应用于 u 和 v 循环之外。那也是错误的。

编辑:如果您无法理解这些单词,这是代码:

#include <stdio.h>
#include <math.h>

#ifndef M_PI
#define M_PI 3.14159265358979324
#endif

void Compute8x8Dct(const double in[8][8], double out[8][8])
{
  int i, j, u, v;
  double s;

  for (i = 0; i < 8; i++)
    for (j = 0; j < 8; j++)
    {
      s = 0;

      for (u = 0; u < 8; u++)
        for (v = 0; v < 8; v++)
          s += in[u][v] * cos((2 * u + 1) * i * M_PI / 16) *
                          cos((2 * v + 1) * j * M_PI / 16) *
               ((i == 0) ? 1 / sqrt(2) : 1) *
               ((j == 0) ? 1 / sqrt(2) : 1);

      out[i][j] = s / 4;
    }
}

void Compute8x8Idct(const double in[8][8], double out[8][8])
{
  int i, j, u, v;
  double s;

  for (i = 0; i < 8; i++)
    for (j = 0; j < 8; j++)
    {
      s = 0;

      for (u = 0; u < 8; u++)
        for (v = 0; v < 8; v++)
          s += in[u][v] * cos((2 * i + 1) * u * M_PI / 16) *
                          cos((2 * j + 1) * v * M_PI / 16) *
               ((u == 0) ? 1 / sqrt(2) : 1.) *
               ((v == 0) ? 1 / sqrt(2) : 1.);

      out[i][j] = s / 4;
    }
}

void Print8x8(const char* title, const double in[8][8])
{
  int i, j;

  printf("%s\n", title);

  for (i = 0; i < 8; i++)
  {
    for (j = 0; j < 8; j++)
      printf("%8.3f ", in[i][j]);
    printf("\n");
  }
}

int main(void)
{
  double pic1[8][8], dct[8][8], pic2[8][8];
  int i, j;

  for (i = 0; i < 8; i++)
    for (j = 0; j < 8; j++)
#if 01
      pic1[i][j] = 255;
#else
      pic1[i][j] = (i ^ j) & 1;
#endif
  Print8x8("pic1:", pic1);
  Compute8x8Dct(pic1, dct);
  Print8x8("dct:", dct);
  Compute8x8Idct(dct, pic2);
  Print8x8("pic2:", pic2);

  return 0;
}

这是其输出:

pic1:
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
dct:
2040.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000 
   0.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000 
   0.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000 
   0.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000 
   0.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000 
   0.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000 
   0.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000 
   0.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000 
pic2:
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 

You're trying to calculate the IDCT in-place, using idctMatrix[][] as both input and output and hence the input is being modified in the process. That's wrong. You need to have a separate 2-dimensional array for input (or output).

It also appears that the u- and v-dependent scaling factors Cu and Cv are applied outside of the u- and v- loops. That would be wrong too.

EDIT: Here's the code if you can't understand the words:

#include <stdio.h>
#include <math.h>

#ifndef M_PI
#define M_PI 3.14159265358979324
#endif

void Compute8x8Dct(const double in[8][8], double out[8][8])
{
  int i, j, u, v;
  double s;

  for (i = 0; i < 8; i++)
    for (j = 0; j < 8; j++)
    {
      s = 0;

      for (u = 0; u < 8; u++)
        for (v = 0; v < 8; v++)
          s += in[u][v] * cos((2 * u + 1) * i * M_PI / 16) *
                          cos((2 * v + 1) * j * M_PI / 16) *
               ((i == 0) ? 1 / sqrt(2) : 1) *
               ((j == 0) ? 1 / sqrt(2) : 1);

      out[i][j] = s / 4;
    }
}

void Compute8x8Idct(const double in[8][8], double out[8][8])
{
  int i, j, u, v;
  double s;

  for (i = 0; i < 8; i++)
    for (j = 0; j < 8; j++)
    {
      s = 0;

      for (u = 0; u < 8; u++)
        for (v = 0; v < 8; v++)
          s += in[u][v] * cos((2 * i + 1) * u * M_PI / 16) *
                          cos((2 * j + 1) * v * M_PI / 16) *
               ((u == 0) ? 1 / sqrt(2) : 1.) *
               ((v == 0) ? 1 / sqrt(2) : 1.);

      out[i][j] = s / 4;
    }
}

void Print8x8(const char* title, const double in[8][8])
{
  int i, j;

  printf("%s\n", title);

  for (i = 0; i < 8; i++)
  {
    for (j = 0; j < 8; j++)
      printf("%8.3f ", in[i][j]);
    printf("\n");
  }
}

int main(void)
{
  double pic1[8][8], dct[8][8], pic2[8][8];
  int i, j;

  for (i = 0; i < 8; i++)
    for (j = 0; j < 8; j++)
#if 01
      pic1[i][j] = 255;
#else
      pic1[i][j] = (i ^ j) & 1;
#endif
  Print8x8("pic1:", pic1);
  Compute8x8Dct(pic1, dct);
  Print8x8("dct:", dct);
  Compute8x8Idct(dct, pic2);
  Print8x8("pic2:", pic2);

  return 0;
}

Here's its output:

pic1:
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
dct:
2040.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000 
   0.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000 
   0.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000 
   0.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000 
   0.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000 
   0.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000 
   0.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000 
   0.000    0.000    0.000    0.000    0.000    0.000    0.000    0.000 
pic2:
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
 255.000  255.000  255.000  255.000  255.000  255.000  255.000  255.000 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文