DCT(離散コサイン変換)アルゴリズムの原理とソースコード(python)

17775 ワード

原理:
離散コサイン変換(DCT for Discrete Cosine Transform)は、離散フーリエ変換(DFT for Discrete Fourier Transform)に類似するフーリエ変換に関連する変換であるが、実数のみが用いられる.離散コサイン変換は1つの長さの約2倍の離散フーリエ変換に相当し,この離散フーリエ変換は1つの実双関数に対して行われる(1つの実双関数のフーリエ変換は依然として1つの実双関数であるため),一部の変形では、入力または出力の位置を半単位移動する必要があります(DCTには8種類の標準タイプがあり、そのうち4種類が一般的です).
シーンを使用:
離散コサイン変換、特にその第2のタイプは、信号処理および画像処理によってよく用いられ、静止画像および動き画像を含む信号および画像の損失データ圧縮に用いられる.同様の変換,改良された離散コサイン変換を,高度なオーディオ符号化(AAC for Advanced Audio Coding),VorbisおよびMP 3オーディオ圧縮に用いた.
pythonソース実装:
#include 
#include 
#include 

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 ){
        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, "
"); } fprintf(fp, "
"); } 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){ for(j = 0; 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; }

コードパス:https://github.com/DyLanCao/DCT.git
参照ドキュメント:
1 https://stackoverflow.com/questions/8310749/discrete-cosine-transform-dct-implementation-c