离散余弦变换DCT实现C

2023-11-26

我试图在 C 中实现正向和反向离散余弦变换(DCT)。代码是通过 dct() 函数将单个输入像素块变换为变换矩阵,然后通过 idct( ) 功能。请参阅随附的代码。我的 idct 输出是 244、116、244、116 等连续值。从 idct 值的外观来看,我的程序似乎不起作用。有人可以帮助我并告诉我我的结果吗?每个功能之后应该期待吗?显然,在 idct 之后,我应该非常接近原始输入矩阵。

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);
}

if 语句中的 Cv 常量赋值至少有两个拼写错误:

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

但没有检查得太正确。使用德语维基百科关于余弦变换,以下代码有效... 我不想花时间去弄清楚如何定义什么转换常量。 我想您需要确保使用正确的常量和反函数:

#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;
}

EditDCT 基于 wiki 中公式 DCT-II 的叉积。 idct 基于公式 DCT-III 与每维归一化因子 2/N 的叉积(因为这是文中提到的 DCT-II 的逆)。Edit我非常确定在您的版本中,逆 dct 中的因子应该是 sqrt(2) 而不是 1/sqrt(2) 。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

离散余弦变换DCT实现C 的相关文章

随机推荐

  • jQuery 中的类名更改事件

    当元素类更改时 有没有办法在 jQuery 中触发事件 例子 img class selected into img class selected newclass 触发事件 And img class selected into img
  • pyodbc 和 mySQL

    我无法使用 pyodbc 连接到 mySQl 数据库 这是我的脚本的片段 import pyodbc import csv cnxn pyodbc connect DRIVER MySQL ODBC 3 51 Driver SERVER l
  • MacOS“配置:错误:无法运行 C 编译的程序”

    我对 MacOS 环境相当陌生 之前在编译 C 脚本时遇到了一些问题 我遇到了以下问题 fatal error stdio h No such file or directory include
  • Angular 4 动画不适用于 Safari iOS 9.3

    我目前正在所有可能的浏览器中测试我的应用程序 我发现角度动画在 Safari iOS 9 3 中的行为与预期不符 下班后 花了几个小时试图解决这个问题 我来寻求帮助 提前致谢 我的代码如下 包 json dependencies angul
  • Spring 3.1 自动装配在自定义约束验证器中不起作用

    我在自定义约束验证器内自动装配 bean 时遇到问题 约束验证器实例不是使用 Spring 的 LocalValidatorFactoryBean 给出的 JSR 303 提供程序是 hibernate validator 4 2 0 Fi
  • 为什么是“using namespace std;”被认为是不好的做法?

    我听说using namespace std 是不好的做法 我应该使用std cout and std cin直接代替 为什么是这样 声明与中的某些内容同名的变量是否存在风险 std命名空间 考虑两个名为 Foo 和 Bar 的库 usin
  • Windows Azure 上的 AspPDF 和 AspJPEG

    我最近开始将 NET 应用程序迁移到 Windows Azure 云服务 我们的应用程序严重依赖于许多 COM 类组件 其中包括 AspPDF 用于 PDF 生成和操作 和 AspJPEG 用于调整图像大小 在典型的非云 IIS 设置中 我
  • 如何将 Rowversion 或 Timestamp SQL Server 数据类型从 SQLDataReader 读取到 C# 变量

    我有一个 SQL Server 2012 数据库 每个表都有一组审计字段 其中一个是名为 RowVer 的列 其数据类型为timestamp 与 一样rowversion 我很难读取 a 的值SqlDataReader到一个 C 对象 其属
  • 在 Docker 容器内运行 Docker:无法连接到 Docker 守护进程

    我创建了一个 Dockerfile 来在 Docker 中运行 Docker FROM ubuntu 16 04 RUN apt get update apt get install y apt transport https ca cer
  • 两个四元数之间的“距离”(或角度大小)?

    我想找到两个四元数之间的 距离 我所说的 距离 是指单个浮点数或整数 而不是另一个四元数 这就是区别 即inverse q1 q2 我想你可以称我想要的为 角幅度 物理对象从原始角度旋转得越远 我就需要对其施加越大的扭矩 我不明白四元数涉及
  • 如何将 ComboBox 的 SelectedItem 绑定到作为 ItemsSource 中项目的副本的对象?

    我正在将 MVVM 模式与 WPF 一起使用 并遇到了问题 我可以将其简化为以下内容 我有一个 CardType 模型 public class CardType public int Id get set public string Na
  • 重写 std:exception 的析构函数

    如果以下情况 则以下程序无法在 g 4 4 中编译 line 8被评论 为什么 看来当我重写时std exception构造函数 我也必须重写它的析构函数 这是什么原因呢 include
  • Scala 中的反函数

    Scala 有没有办法表达任何函数的反函数 例如 如果我有一个函数f像这样 x Int gt x 1 我希望能够编写一个反函数g like f x Int gt x not a valid scala syntax or x Int gt
  • 字符串连接在 SQLite 中不起作用

    我正在尝试执行 SQlite 替换函数 但在函数中使用另一个字段 select locationname p from location 在此片段中 结果是 0 的列表 我本来期望一个字符串 其中包含来自 locationname 的文本和
  • 为什么使用整数而不是长整型?

    我经常看到有关的问题Overflow错误与vba 我的问题是为什么使用integer变量声明而不是仅仅定义所有数值变量 不包括double等 作为long 除非您正在执行类似 for 循环的操作 您可以保证该值不会超过 32 767 限制
  • Windows 上的 Java:如何将文件删除到垃圾箱(使用 JNA)

    我根本没有 Windows API 的经验 所以请原谅我的无知 我想将文件删除到垃圾箱 如何使用JNA以及如何检测这是否不可能 例如 因为文件位于网络共享上 Use com sun jna platform FileUtils代替com s
  • 使用支持 WebGL 的浏览器查看 VRML 文件 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我有一个生成 VRML 1 0 文件的旧应用程序 我想构建一个基于 WebGL 的 Web 界面来显示这些 VRML 文件 有没有简单的方法可以做到
  • 具有 ngFor 元素的 ngModel 的动态 angular2 形式

    我正在尝试创建一个连接到 ngModel 的动态表单 它允许用户根据需要添加更多控件 如下图所示 表单的行为符合预期 但添加一组新控件时除外 因为它会删除先前输入的内容 尽管模型没有改变 我创建了这个plunkr为了展示我正在谈论的行为 这
  • Kerberos、委派以及如何正确执行此操作?

    我有两个独立的自制应用程序 需要在它们之间进行通信 一个是前端应用程序 实际上是 asp net 另一个是会计应用程序的后端接口 后端接口不是专门为此前端创建的 它是许多其他应用程序用来与我们的产品集成的通用接口 为了方便用户 我们希望在前
  • 离散余弦变换DCT实现C

    我试图在 C 中实现正向和反向离散余弦变换 DCT 代码是通过 dct 函数将单个输入像素块变换为变换矩阵 然后通过 idct 功能 请参阅随附的代码 我的 idct 输出是 244 116 244 116 等连续值 从 idct 值的外观