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ソース実装:
コードパス:https://github.com/DyLanCao/DCT.git
参照ドキュメント:
1 https://stackoverflow.com/questions/8310749/discrete-cosine-transform-dct-implementation-c
離散コサイン変換(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