离散余弦变换DCT实现Ç [英] Discrete Cosine Transform DCT implementation C

查看:229
本文介绍了离散余弦变换DCT实现Ç的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

林试图向前推行和逆离散余弦变换(DCT)C中的code是通过DCT()函数来transorm像素的变换矩阵的单个输入块,然后返回到原来的通过IDCT()函数的像素值。请参阅所附code。我的输出形成IDCT是244,116,244,116等来自IDCT值的外观,它并不像我的程序正在连续值..有人能帮助我,给我的是什么结果我的想法应该是每一个功能之后的期待呢?在IDCT后,很显然,我应该得到preTY接近原始输入矩阵。

感谢

 #包括LT&;&stdio.h中GT;
 #定义PI 3.14无效DCT(浮动[] []); //函数原型
无效IDCT(浮动[] []); //函数原型空隙DCT(浮动inMatrix [8] [8]){    双DCT,
    铜,
    和,
    简历;    INT I,
    Ĵ,
    U,
    H = 0,
    伏;    FILE *计划生育=的fopen(mydata.csv,W);    浮dctMatrix [8] [8],
    greyLevel;    对于(U = 0; U< 8; ++ U){
        为(V = 0; V族8 ++ⅴ){            如果(U == 0){
                铜= 1.0 / SQRT(2.0);
            }其他{
                铜= 1.0;
            }            如果(ⅴ== 0){
                CV = 1.0 / SQRT(2.0);
            }其他{
                铜=(1.0);
            }            总和= 0.0;            对于(i = 0; I< 8;我++){
                为(J = 0; J&下; 8; J ++){                    // 0左右水平
                    greyLevel = inMatrix [I] [J]。                    DCT = greyLevel * COS((2 * I + 1)* U * PI / 16.0)*
                        COS((2 * J + 1)* V * PI / 16.0);                    总和+ = DCT;                }
            }
            dctMatrix [U] [V] = 0.25 * *铜*简历总和;
            fprintf中(FP,\\ N%F,dctMatrix [U] [V]);
        }
        fprintf中(FP,\\ n);
    }
    IDCT(dctMatrix);
 }空隙IDCT(浮动dctMatrix [8] [8]){    双IDCT,
    铜,
    和,
    简历;    INT I,
    Ĵ,
    U,
    伏;    浮idctMatrix [8] [8],
    greyLevel;    FILE * FP =的fopen(mydata.csv,一个);    fprintf中(FP,\\ n逆DCT);    对于(I = 0; I&下; 8; ++ⅰ){
        为(J = 0; J&下; 8; ++ j)条{            总和= 0.0;        对于(U = 0; U< 8;ü++){
            为(V = 0; V族; 8; v ++){            如果(U == 0){
                铜= 1.0 / SQRT(2.0);
            }其他{
                铜= 1.0;
              }            如果(ⅴ== 0){
                CV = 1.0 / SQRT(2.0);
            }其他{
                铜=(1.0);
              }                    // 0左右水平
                greyLevel = dctMatrix [U] [V]                IDCT =(greyLevel * COS((2 * I + 1)* U * PI / 16.0)*
                        COS((2 * J + 1)* V * PI / 16.0));                总和+ = IDCT;                }
            }
            idctMatrix [I] [J] = 0.25 * *铜*简历总和;
            fprintf中(FP,\\ N%F,idctMatrix [I] [J]);
        }
        fprintf中(FP,\\ n);
    }
 }
诠释主(){   浮动
    testBlockA [8] [8] = {{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}},    testBlockB [8] [8] = {{255,0,255,0,255,0,255,0},
                        {0,255,0,255,0,255,0,255},
                        {255,0,255,0,255,0,255,0},
                        {0,255,0,255,0,255,0,255},
                        {255,0,255,0,255,0,255,0},
                        {0,255,0,255,0,255,0,255},
                        {255,0,255,0,255,0,255,0},
                        {0,255,0,255,0,255,0,255}};    DCT(testBlockB);
}


解决方案

有在CV恒分配至少两个错别字的if语句:

 如果(V == 0){
        CV = 1.0 / SQRT(2.0);
    }其他{
        铜=(1.0); //<<这应该是CV = 1.0
    }

没查过正常不过。使用href=\"http://de.wikipedia.org/wiki/Diskrete_Kosinustransformation\">约余弦德国Wikipedia 改造我不想花时间搞清楚你如何定义什么转换常数。
我猜你需要确保你使用正确的常量和反函数:

 的#include<&stdio.h中GT;
#包括LT&;&math.h中GT;
#包括LT&;&stdlib.h中GT;无效DCT(浮** DCTMatrix,浮**矩阵,整数N,INT M);
无效write_mat(FILE * FP,浮** testRes,整数N,INT M);
无效IDCT(浮球矩阵**,**浮动DCTMatrix,INT N,INT M);
浮** calloc_mat(INT dimX,诠释dimY);
无效free_mat(浮动** P);
浮** calloc_mat(INT dimX,诠释dimY){
    浮** M =释放calloc(dimX,sizeof的(浮动*));
    浮* P =释放calloc(dimX * dimY,sizeof的(浮动));
    INT I;
    对于(i = 0; I< dimX;我++){
    M [] =安培; P [我* dimY]    }
   返回米;
}无效free_mat(浮动** M){
  免费(M [0]);
  免费(米);
}无效write_mat(FILE * FP,浮** M,INT N,INT M){   INT I,J;
   对于(i = 0; I< N;我++){
    fprintf中(FP,%F,M [] [0]);
    为(J = 1; J&LT,M,J ++){
       fprintf中(FP,\\ t%F,M [] [J]);
        }
    fprintf中(FP,\\ n);
   }
   fprintf中(FP,\\ n);
}无效DCT(浮** DCTMatrix,浮**矩阵,INT N,INT M){    INT I,J,U,V;
    对于(U = 0; U< N ++ U){
        为(V = 0; V&下,M ++ⅴ){
        DCTMatrix [U] [V] = 0;
            对于(i = 0; I< N;我++){
                为(J = 0; J&下,M; J ++){
                    DCTMatrix [U] [V] + =矩阵[I] [J] * COS(M_PI /((浮点)N)*(我+ 1/2)* U)* COS(M_PI /((浮点)M )*第(j + 1/2)* v)中。;
                }
            }
        }
    }
 }无效IDCT(浮球矩阵**,**浮动DCTMatrix,INT N,INT M){
    INT I,J,U,V;    对于(U = 0; U< N ++ U){
        为(V = 0; V&下,M ++ⅴ){
          矩阵[U] [V] = 1/4 * DCTMatrix [0] [0];
          对于(i = 1; I< N;我++){
          矩阵[U] [V] + = 1/2 * DCTMatrix [I] [0];
           }
           为(J = 1; J&LT,M,J ++){
          矩阵[U] [V] + = 1/2 * DCTMatrix [0] [J]。
           }           对于(i = 1; I< N;我++){
                为(J = 1; J&LT,M,J ++){
                    矩阵[U] [V] + = DCTMatrix [I] [J] * COS(M_PI /((浮点)N)*(U + 1/2)* I)* COS(M_PI /((浮点)M )*(v + 1/2)* j)条。
                }
            }
        矩阵[U] [V] * = 2./((float)N)*2./((float)M);
        }
    }
 }诠释主(){   浮动
    testBlockA [8] [8] = {{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}},    testBlockB [8] [8] = {{255,0,255,0,255,0,255,0},
                        {0,255,0,255,0,255,0,255},
                        {255,0,255,0,255,0,255,0},
                        {0,255,0,255,0,255,0,255},
                        {255,0,255,0,255,0,255,0},
                        {0,255,0,255,0,255,0,255},
                        {255,0,255,0,255,0,255,0},
                        {0,255,0,255,0,255,0,255}};    FILE *计划生育=的fopen(mydata.csv,W);
    INT dimX = 8,dimY = 8;
    INT I,J;    浮** testBlock = calloc_mat(dimX,dimY);
    浮** testDCT = calloc_mat(dimX,dimY);
    浮** testiDCT = calloc_mat(dimX,dimY);    对于(i = 0; I< dimX;我++){
      为(J = 0; J< dimY; J ++){
        testBlock [I] [J] = testBlockB [I] [J]。
      }
    }    DCT(testDCT,testBlock,dimX,dimY);
    write_mat(FP,testDCT,dimX,dimY);    IDCT(testiDCT,testDCT,dimX,dimY);
    write_mat(FP,testiDCT,dimX,dimY);    FCLOSE(FP);
    free_mat(testBlock);
    free_mat(testDCT);
    free_mat(testiDCT);    返回0;
}

修改
该DCT是基于公式DCT-II在wiki上的双重交叉。
的IDCT是基于式的DCT-III的交叉积与归一化因子每个维度2 / N(因为这是在文中提到的逆DCT的二)。
修改
我pretty确保在逆DCT的系数应(2)中的版本SQRT(2),而不是1 /平方根

Im trying to implement a forward and inverse Discrete Cosine Transform (DCT) in C. The code is to transorm a single input block of pixels to the transformation matrix via the dct() function and then back to the original pixel values via the idct() function. Please see the attached code. My output form the idct are consecutive values of 244, 116, 244, 116 etc. From the look of the idct values, it doesnt look like my program is working.. Could someone help me out and give me an idea of what results i should be expecting after each function? Obviously after the idct, i should be getting prety close to the original input Matrix.

Thanks

 # include <stdio.h>
 # define PI 3.14

void dct(float [][]);       // Function prototypes
void idct(float [][]);     // Function prototypes

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

    double dct,
    Cu,
    sum,
    Cv;

    int i,
    j,
    u,
    h = 0,
    v;

    FILE * fp = fopen("mydata.csv", "w");

    float dctMatrix[8][8],
    greyLevel;                       

    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 {
                Cu = (1.0);
            }   

            sum = 0.0;  

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

                    // Level around 0
                    greyLevel = inMatrix[i][j];

                    dct = greyLevel * cos((2 * i + 1) * u * PI / 16.0) *
                        cos((2 * j + 1) * v * PI / 16.0);

                    sum += dct;

                }               
            }
            dctMatrix[u][v] = 0.25 * Cu * Cv * sum;
            fprintf(fp, "\n %f", dctMatrix[u][v]);          
        }
        fprintf(fp, "\n");
    }  
    idct(dctMatrix);  
 }

void idct(float dctMatrix[8][8]){

    double idct,
    Cu,
    sum,
    Cv;

    int i,
    j,
    u,
    v;

    float idctMatrix[8][8],
    greyLevel;

    FILE * fp = fopen("mydata.csv", "a");

    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 {
                Cu = (1.0);
              }   

                    // Level around 0
                greyLevel = dctMatrix[u][v];

                idct = (greyLevel * cos((2 * i + 1) * u * PI / 16.0) *
                        cos((2 * j + 1) * v * PI / 16.0));

                sum += idct;

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


int main() {

   float    
    testBlockA[8][8] = { {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} },

    testBlockB[8][8] = {{255, 0, 255, 0, 255, 0, 255, 0},
                        {0, 255, 0, 255, 0, 255, 0, 255},
                        {255, 0, 255, 0, 255, 0, 255, 0},
                        {0, 255, 0, 255, 0, 255, 0, 255},
                        {255, 0, 255, 0, 255, 0, 255, 0},
                        {0, 255, 0, 255, 0, 255, 0, 255},
                        {255, 0, 255, 0, 255, 0, 255, 0},
                        {0, 255, 0, 255, 0, 255, 0, 255} };

    dct(testBlockB);
}

解决方案

There are at least two typos in the Cv constant assignment at the if statements:

    if (v == 0) {
        Cv = 1.0 / sqrt(2.0);
    } else {
        Cu = (1.0); // << this should be Cv = 1.0
    }   

Didn't check too properly though. Using the german wikipedia about cosine transform, following code works... I didn't want to spent time on figuring out how you defined what conversion constant. I guess you need to make sure that you use the correct constants and inverse functions:

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

void dct(float **DCTMatrix, float **Matrix, int N, int M);
void write_mat(FILE *fp, float **testRes, int N, int M);
void idct(float **Matrix, float **DCTMatrix, int N, int M);
float **calloc_mat(int dimX, int dimY);
void free_mat(float **p);


float **calloc_mat(int dimX, int dimY){
    float **m = calloc(dimX, sizeof(float*));
    float *p = calloc(dimX*dimY, sizeof(float));
    int i;
    for(i=0; i <dimX;i++){
    m[i] = &p[i*dimY];

    }
   return m;
}

void free_mat(float **m){
  free(m[0]);
  free(m);
}

void write_mat(FILE *fp, float **m, int N, int M){

   int i, j;
   for(i =0; i< N; i++){
    fprintf(fp, "%f", m[i][0]);
    for(j = 1; j < M; j++){
       fprintf(fp, "\t%f", m[i][j]);
        }   
    fprintf(fp, "\n");
   }
   fprintf(fp, "\n");
}

void dct(float **DCTMatrix, float **Matrix, int N, int M){

    int i, j, u, v;
    for (u = 0; u < N; ++u) {
        for (v = 0; v < M; ++v) {
        DCTMatrix[u][v] = 0;
            for (i = 0; i < N; i++) {
                for (j = 0; j < M; j++) {
                    DCTMatrix[u][v] += Matrix[i][j] * cos(M_PI/((float)N)*(i+1./2.)*u)*cos(M_PI/((float)M)*(j+1./2.)*v);
                }               
            }
        }
    }  
 }

void idct(float **Matrix, float **DCTMatrix, int N, int M){
    int i, j, u, v;

    for (u = 0; u < N; ++u) {
        for (v = 0; v < M; ++v) {
          Matrix[u][v] = 1/4.*DCTMatrix[0][0];
          for(i = 1; i < N; i++){
          Matrix[u][v] += 1/2.*DCTMatrix[i][0];
           }
           for(j = 1; j < M; j++){
          Matrix[u][v] += 1/2.*DCTMatrix[0][j];
           }

           for (i = 1; i < N; i++) {
                for (j = 1; j < M; j++) {
                    Matrix[u][v] += DCTMatrix[i][j] * cos(M_PI/((float)N)*(u+1./2.)*i)*cos(M_PI/((float)M)*(v+1./2.)*j);
                }               
            }
        Matrix[u][v] *= 2./((float)N)*2./((float)M);
        }
    }  
 }



int main() {

   float    
    testBlockA[8][8] = { {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} },

    testBlockB[8][8] = {{255, 0, 255, 0, 255, 0, 255, 0},
                        {0, 255, 0, 255, 0, 255, 0, 255},
                        {255, 0, 255, 0, 255, 0, 255, 0},
                        {0, 255, 0, 255, 0, 255, 0, 255},
                        {255, 0, 255, 0, 255, 0, 255, 0},
                        {0, 255, 0, 255, 0, 255, 0, 255},
                        {255, 0, 255, 0, 255, 0, 255, 0},
                        {0, 255, 0, 255, 0, 255, 0, 255} };

    FILE * fp = fopen("mydata.csv", "w");
    int dimX = 8, dimY = 8;
    int i, j;

    float **testBlock = calloc_mat(dimX, dimY);
    float **testDCT = calloc_mat(dimX, dimY);
    float **testiDCT = calloc_mat(dimX, dimY);

    for(i = 0; i<dimX; i++){
      for(j = 0; j<dimY; j++){
        testBlock[i][j] = testBlockB[i][j];
      }
    }

    dct(testDCT, testBlock, dimX, dimY);
    write_mat(fp, testDCT, dimX, dimY);

    idct(testiDCT, testDCT, dimX, dimY);
    write_mat(fp, testiDCT, dimX, dimY);

    fclose(fp);
    free_mat(testBlock);
    free_mat(testDCT);
    free_mat(testiDCT);

    return 0;
}

Edit the dct is based on the crossproduct of formula DCT-II in the wiki. the idct is based on the crossproduct of formula DCT-III with the normalization factor 2/N per dimension (since this is the inverse to DCT-II as mentioned in the text). Edit I am pretty sure that the factor in the inverse dct should sqrt(2) and not 1/sqrt(2) in your version.

这篇关于离散余弦变换DCT实现Ç的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆