【问题标题】:Trying to implement The inverse of a dct 8*8 matrix尝试实现 dct 8*8 矩阵的逆
【发布时间】:2016-08-25 14:15:26
【问题描述】:

我设法计算了一个 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应该和原来的一样

【问题讨论】:

  • 请给出一个失败的输入示例,以及预期输出和实际输出。另外,通过在调试器中运行它你学到了什么?
  • 此外,DCT (en.wikipedia.org/wiki/…) 的定义也很多。你要哪一个?
  • 您应该更深入地了解代码。我们不会一步一步来。中间结果正确吗?输出值是否与您期望的值大致相等?
  • 我更新了原始矩阵是什么以及我计算的 dct 的样子
  • 您的问题标题谈到矩阵逆,但内容似乎是关于 dct 逆。

标签: c trigonometry dct


【解决方案1】:

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

似乎依赖于 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 

【讨论】:

  • 抱歉,alex 我在我的代码中遗漏了一行,它包含 inMatrix[8][8] 并且输出矩阵是 idctMatrix[8][8],无论如何感谢您的帮助跨度>
  • 看来您完全忽略了我的回答,至少我没有看到代码中有任何更改以解决指示的问题。干得好,继续努力。
  • 我没有忽略你的回答,它似乎不正确。我以为是
  • 查看更新答案中的代码。代码准确地反映了最初的答案。
  • 非常感谢亚历克斯,我更了解您的代码
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多