【问题标题】:dct implementation in cc中的dct实现
【发布时间】:2022-03-10 21:34:48
【问题描述】:

所以我正在尝试在我的 c 代码中实现 DCT-ll 函数,但我不确定如何执行此操作? 我使用这个公式:https://i.stack.imgur.com/UeUBd.png

还有一个包含这些值的数组:

static float array[] = {0.35,
 0.35,
-0.37,
-0.335,
-0.285,
-0.23,
-0.215}

我似乎找不到任何关于如何做到这一点的帮助,我只在 MatLab 中做过,而且很容易

close all; clear all; clc ;
N=512; % signal length

M=120; %select the number of DCT coefficients

load mit200
%%
x=ecgsig(1:N,1);

%% DCT transform of signal
y=dct(x);

%% Select first M coefficients
y(M+1:end)=0;

%% reconstructed signal
xrec = idct(y);
plot(x);
hold on;
plot((xrec),'r.');
legend ( 'Original','Recovered');

我能找到的大部分帮助都是这样的:Discrete Cosine Transform DCT implementation C,但它总是使用 8x8 矩阵 --> inMatrix[8][8]?

这是我的代码

#include "contiki.h"

#include "math.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

//Define sizeof - macros
#define SHIFT_AMOUNT 2 // 2^16 = 65536
#define SHIFT_MASK ((1 << SHIFT_AMOUNT) - 1) // 65535 (all LSB set, all MSB clear)
#define pi 3.14
//double static signal[3] = {0.35,0.35,0.35};
//static int price = 500 << SHIFT_AMOUNT;
static int dec;
static int frac;
static float s = 0;
static float array[] = {0.35,0.35,0.35,0.35,0.35,0.35,0.35,0.35,0.35,0.02,-0.21,-0.33,-0.37,-0.335,-0.285,-0.23,-0.215,-0.2,-0.19,-0.2,-0.2,-0.21,-0.23,-0.25,-0.255,-0.245,-0.24,-0.215,-0.235,-0.23,-0.23,-0.205,
-0.18,-0.165,-0.195,-0.21,-0.215,-0.195,-0.17,-0.155,-0.175,-0.195,-0.21,-0.2,-0.195,-0.185,-0.185,-0.18,-0.175,-0.175,-0.165,
-0.14,-0.12,-0.115,-0.13,-0.155,-0.19,-0.19,-0.185,-0.18,-0.16,-0.14,-0.13,-0.11,-0.12,-0.13,-0.13,-0.125,-0.095,-0.095,-0.09,-0.08,-0.075,-0.07,-0.075,-0.065,-0.055,-0.06,-0.055,-0.04,-0.03,-0.02,-0.015,-0.015,-0.01,0.015,0.035,0.025,0.015,0.015,0.025,0.025,0.04,0.04,0.03,
0.015,0.02,0.035,0.045,0.05,0.025,0.02,0.02,0.01,0.01,0,-0.005,-0.025,-0.02,-0.03,-0.03,-0.035,-0.045,-0.055,-0.06,-0.065,-0.075,-0.08,-0.075,-0.075,-0.075,-0.07,
-0.075,-0.08,-0.09,-0.1,-0.095,-0.095,-0.085,-0.095,-0.1,-0.1,-0.115,-0.115,-0.13,-0.14,-0.15,-0.16,-0.145,-0.155,-0.16,-0.17,-0.185,-0.175,-0.17,-0.165,-0.17,-0.17,
-0.165,-0.18,-0.18,-0.2,-0.2,-0.215,-0.205,-0.21,-0.205,-0.21,-0.22,-0.225,-0.225,-0.24,-0.225,-0.21,-0.205,-0.195,-0.19,-0.2,-0.19,-0.19,-0.185,-0.17,-0.17,-0.175,-0.165,-0.165,-0.185,
-0.185,-0.205,-0.205,-0.21,-0.195,-0.195,-0.19,-0.195,-0.195,-0.195,-0.185,-0.175,-0.175,-0.2,-0.225,-0.25,-0.24,-0.24,-0.24,-0.25,-0.26,-0.27,-0.28,-0.305,-0.335,-0.35,
-0.34,-0.285,-0.205,-0.135,-0.095,-0.045,0.01,0.075,0.14,0.175,0.135,0.045,-0.155,-0.425,-0.71,-0.915,-1.09,-1255,-1395,-1465,-1505,-1.49,-1.45,-1.39,-1.34,-1.27,-1155,-1025,
-0.95,-0.93,-0.93,-0.91,-0.885,-0.865,-0.84,-0.8,-0.755,-0.715,-0.66,-0.63,-0.58,-0.54,-0.51,-0.465,-0.435,-0.395,-0.365,-0.315,-0.265,-0.2,-0.155,-0.09,-0.04,-0.015,
-0.01,0.005,0.03,0.055,0.08,0.085,0.09,0.11,0.11,0.13,0.15,0.155,0.15,0.18,0.185,0.205,0.22,0.235,0.235,0.255,0.27,0.29,0.29,0.3,0.3,0.305,0.325,0.315,
0.31,0.315,0.315,0.345,0.36,0.37,0.375,0.375,0.365,0.375,0.385,0.41,0.405,0.4,0.4,0.405,0.4,0.41,0.395,0.4,0.385,0.39,0.395,0.385,0.38,0.355,0.355,0.355,0.35,0.325,0.3,0.28,0.25,0.25,0.25,
0.25,0.235,0.21,0.175,0.165,0.16,0.145,0.14,0.145,0.13,0.1,0.08,0.04,0.015,-0.01,-0.025,-0.025,-0.03,-0.04,-0.045,-0.07,-0.105,-0.08,-0.075,-0.085,-0.09,-0.11,-0.13,-0.12,-0.115,-0.125,-0.15,-0.17,-0.16,-0.16,
-0.15,-0.155,-0.16,-0.17,-0.185,-0.18,-0.18,-0.19,-0.18,-0.17,-0.16,-0.14,-0.14,-0.145,-0.17,-0.18,-0.175,-0.16,-0.155,-0.155,-0.165,-0.15,-0.155,-0.15,-0.145,-0.145,-0.165,-0.195,-0.205,-0.19,-0.18,-0.165,-0.17,
-0.16,-0.17,-0.165,-0.17,-0.17,-0.17,-0.17,-0.185,-0.19,-0.18,-0.18,-0.18,-0.175,-0.2,-0.21,-0.2,-0.2,-0.21,-0.215,-0.21,-0.2,-0.175,-0.16,-0.145,-0.145,-0.135,-0.14,-0.135,-0.13,-0.12,-0.115,-0.11,
-0.105,-0.1,-0.095,-0.11,-0.14,-0.175,-0.18,-0.18,-0.18,-0.165,-0.175,-0.175,-0.175,-0.165,-0.165,-0.165,-0.175,-0.165,-0.16,-0.155,-0.15,-0.155,-0.16,-0.16,-0.155,-0.145,-0.15,-0.15,-0.185,-0.2,
-0.2,-0.195,-0.19,-0.19,-0.195,-0.2,-0.195,-0.185,-0.175,-0.175,-0.155,-0.17,-0.17,-0.165,-0.15,-0.16,-0.165,-0.175,-0.17,-0.17,-0.185,-0.215,-0.225,-0.19,-0.125,-0.04,0.05,0.125,0.215,0.32,0.415,0.5,
0.605,0.725,0.845,0.94,1.06,1.11,1.1,1005,0.86,0.615,0.24,-0.11,-0.335,-0.46,-0.515,-0.54,-0.51,-0.44,-0.385,-0.36,-0.35,-0.335,-0.32,-0.295,-0.3,-0.3,-0.325,-0.335,-0.335};
static int i;

static const int SIZE = 512;


void calcTest(){
  float array2[SIZE];
  for (i = 0; i < SIZE; i++) {
    s = array[i];
    array2[i] = (s * cosf(pi/SIZE * (i + .5) * 1);

    //Print array
    if (s < 0){
      dec = s;
      frac = -(s - dec) * 1000;
      if (dec == 0)
      {
        printf("\n Temp1: -%d.%02u\n", dec, frac);
      }else{
        printf("\n Temp1: %d.%02u\n", dec, frac);
      }           
    }else{
      dec = s;
      frac = (s - dec) * 1000;     
      printf("\n Temp2: %d.%02u\n", dec, (unsigned int)frac);
    }

    //Print array2 which contains the DCT values
    if (s < 0){
      dec = array2[i];
      frac = -(array2[i] - dec) * 1000;
      if (dec == 0)
      {
        printf("\n *Temp1: -%d.%02u\n", dec, frac);
      }else{
        printf("\n *Temp1: %d.%02u\n", dec, frac);
      }           
    }else{
      dec = array2[i];
      frac = (array2[i] - dec) * 1000;     
      printf("\n *Temp2: %d.%02u\n", dec, (unsigned int)frac);
    }
  }
}



//Defining two processors, one for making the 'knock' and one to listen
PROCESS(data_comp, "data_comp");
AUTOSTART_PROCESSES(&data_comp);

/*---------------------------------------------------------------------------*/


PROCESS_THREAD(data_comp, ev, data)
{
  static struct etimer timer;

  PROCESS_BEGIN();  
  
  /* Setup a periodic timer that expires after 10 seconds. */
  etimer_set(&timer, CLOCK_SECOND * 10);
  
  while(1) {
    calcTest();
     /* Wait for the periodic timer to expire and then restart the timer. */
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timer));
    etimer_reset(&timer);
  }

  PROCESS_END();
}

【问题讨论】:

    标签: c matlab contiki dct


    【解决方案1】:

    要使用公式实现 DCT-II,只需计算公式即可:

    #include <stdio.h>
    #include <math.h>
    
    
    #define NumberOf(a) (sizeof (a) / sizeof *(a))
    
    
    static void DCTII(size_t N, float *y, const float *x)
    {
        static const float Pi = 0x3.243f6a8885a308d313198a2e03707344ap0f;
    
        for (size_t k = 0; k < N; ++k)
        {
            float sum = 0;
            for (size_t n = 0; n < N; ++n)
                sum += x[n] * cosf(Pi/N * (n + .5) * k);
            y[k] = sum;
        }
    }
    
    
    int main(void)
    {
        float array[] = {0.35, 0.35, -0.37, -0.335, -0.285, -0.23, -0.215};
        float result[NumberOf(array)];
    
        DCTII(NumberOf(array), result, array);
    
        for (size_t i = 0; i < NumberOf(result); ++i)
            printf("y[%zu] = %g.\n", i, result[i]);
    }
    

    对于更大的长度,这不是最有效的实现方式。

    【讨论】:

    • 由于作者在这个问题上使用了“contiki”标签 - 对于嵌入式设备,最好预先计算特定参数值上的 cos 函数值并将它们存储在查找表中在设备的闪存中。然后在运行时,可以使用简单的表查找代替cos 计算。
    • 是的,正如@kfx 所说,这是针对嵌入式设备的
    • @WRDBAC:您具体需要哪些帮助?是cos 函数吗?您知道如何计算公式中所需的cos 函数的值,将它们放入一个数组中,然后使用该数组代替cos 函数吗?
    • @EricPostpischil 现在我收到错误:Undefined error to 'cos',但我已经包含了#include &lt;math.h&gt;
    • @WRDBAC:你能写一个程序来计算你需要的cos函数的值吗?您知道如何让该程序准确打印值吗?您知道如何将这些值放入定义数组的 C 源代码中吗?您知道如何使用该数组来获取 DCT-II 函数中所需的值吗?
    猜你喜欢
    • 2012-01-08
    • 2014-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多