http://www.cnblogs.com/scut-linmaojiang/p/5013590.html

写在前面

到目前为止已经阅读了相当一部分的网格水印等方面的论文了,但是论文的实现进度还没有更上,这个月准备挑选一些较为经典的论文,将其中的算法实现。在实现论文的过程中,发现论文中有用到一些空域转频率域的算法。因此也就想到了实现一下离散余弦变换。虽然本文的代码和网上很多已有的代码很类似,思路都没有太多的差别,但是本文有一个比较重要的改进。具体的说,网上现有DCT算法输入的是一个固定的二维数组。当二维数组作为函数参数进行传递时,至少需要给出第二个维度的大小,否则编译器会报错。但是在图形图像处理中,当我们希望使用DCT变换把某个图形或者图像转换到频域时,可能我在调用DCT函数之前事先并不知道图形或者图像的规模,因此这种传参方式较大限制了代码的使用。本文的一个改进就是,DCT函数的参数不再是二维数组,而是传入一个二维指针,通过手动寻址来实现函数功能。

离散余弦变换理论基础

我想大家比较熟知的是傅立叶变换。其实离散余弦变换跟傅立叶变换差不多。二维离散余弦变换的定义由下式表示:

反变换表示如下:

代码实现

根据上面的公式,很容易就能写出代码

// DCT - Discrete Cosine Transform
void DCT( double ** input, double ** output, int row, int col ) { cout<<"Test in DCT"<<endl; double ALPHA, BETA; int u = 0; int v = 0; int i = 0; int j = 0; for(u = 0; u < row; u++) { for(v = 0; v < col; v++) { if(u == 0) { ALPHA = sqrt(1.0 / row); } else { ALPHA = sqrt(2.0 / row); } if(v == 0) { BETA = sqrt(1.0 / col); } else { BETA = sqrt(2.0 / col); } double tmp = 0.0; for(i = 0; i < row; i++) { for(j = 0; j < col; j++) { tmp += *((double*) input + col*i + j ) * cos((2*i+1)*u*PI/(2.0 * row)) * cos((2*j+1)*v*PI/(2.0 * col)); } } *((double*) output + col*u + v) = ALPHA * BETA * tmp; } } cout << "The result of DCT:" << endl; for(int m = 0; m < row; m++) { for(int n= 0; n < col; n++) { cout <<setw(8)<< *((double*) output + col*m + n)<<" \t"; } cout << endl; } } 

注意代码中的函数参数不是二维数组,而是一个指向二维数组的指针。相应的反变换的代码如下:

// Inverse DCT
void IDCT( double ** input, double ** output, int row, int col )
{cout<<"Test in IDCT"<<endl;double ALPHA, BETA;int u = 0; int v = 0; int i = 0; int j = 0; for(i = 0; i < row; i++) { for( j = 0; j < col; j++) { double tmp = 0.0; for(u = 0; u < row; u++) { for(v = 0; v < col; v++) { if(u == 0) { ALPHA = sqrt(1.0 / row); } else { ALPHA = sqrt(2.0 / row); } if(v == 0) { BETA = sqrt(1.0 / col); } else { BETA = sqrt(2.0 / col); } tmp += ALPHA * BETA * *((double*) input + col*u + v )* cos((2*i+1)*u*PI/(2.0 * row)) * cos((2*j+1)*v*PI/(2.0 * col)); } }  *((double*) output + col*i + j) = tmp; } } cout << "The result of IDCT:" << endl; for(int m = 0; m < row; m++) { for(int n= 0; n < col; n++) { cout <<setw(8)<< *((double*) output + col*m + n)<<"\t"; } cout << endl; } } 

测试代码

#include <iostream>
#include <math.h>
#include<cstdio> #include <iomanip> #include<algorithm> using namespace std; #define PI 3.1415926 int main() { int i = 0; int j = 0; int u = 0; int v = 0; const int rows = 3; const int cols = 3; double inputdata[rows][cols] = { {89,101,114}, {97,115,131}, {114,134,159}, }; double outputdata[rows][cols]; DCT( (double**)inputdata, (double**)outputdata,rows, cols ); IDCT( (double**)outputdata, (double**)inputdata,rows,cols ); system("pause"); return 0; } 

程序运行结果如下:

小结

之后可以对代码进行升级,不再使用二维数组作为参数传递,而是使用Eigen类型作为参数,这样代码更加清晰,并且内存管理等方面也更加方便。

转载请注明出处:http://www.cnblogs.com/scut-linmaojiang/p/5013590.html

C++实现离散余弦变换(参数为二维指针)相关推荐

  1. C语言基础知识之define宏定义表达式,undef,内存对齐,a和a的区别,数组知识点,int (*)[10] p,二维数组参数与二维指针参数,函数指针数组,常见的内存错误及对策

    一.用define宏定义表达式 1.定义一年有多少秒: #define SEC_A_YEAR 60*60*24*365 //上述描述不可靠,没有考虑到在16位系统下把这样一个数赋给整型变量的时候可能会 ...

  2. 二维离散变换由c语言编写,C++实现离散余弦变换(参数为二维指针)(示例代码)...

    http://www.cnblogs.com/scut-linmaojiang/p/5013590.html 写在前面 到目前为止已经阅读了相当一部分的网格水印等方面的论文了,但是论文的实现进度还没有 ...

  3. 【Android FFMPEG 开发】FFMPEG 方法中指针类型参数说明 ( 一维指针类型参数 | 二维指针类型参数 )

    文章目录 I . 一维指针类型参数 II . 二维指针类型参数 I . 一维指针类型参数 1 . 音视频流数据包获取 : //读取数据包AVPacket *avPacket = av_packet_a ...

  4. vue js前端根据所需参数生成二维码并下载

    需要一个插件 qrcodejs2, 使用 npm install qrcodejs2 --save 下载该依赖包. 在vue中引入(我这边是vue2).import QRCode from 'qrco ...

  5. 微信生成带参数的二维码,合成海报,扫码后推送小程序?

    微信服务号渠道二维码功能,支持生成带参数二维码,合成海报二维码,微信扫码后推送内容:结合微号帮平台48小时信息推送,推送微信小程序. 带参二维码 海报二维码 微信扫码后回复 48小时信息推送 在微号帮 ...

  6. python制作微信个人二维码_Python实现 | 微信带参数的二维码

    微信运营越来越多了,这种带参数二维码的使用场景还挺多的,但是网上的实现大都是PHP啥的,还不想写PHP的我只好用Python实现一下了. 关于带参二维码的介绍,记得先看官网:生成带参数的二维码. 先大 ...

  7. 微信公众号之生成带参数的二维码

    生成带参数的二维码 为了满足用户渠道推广分析和用户帐号绑定等场景的需要,公众平台提供了生成带参数二维码的接口.使用该接口可以获得多个带不同场景值的二维码,用户扫描后,公众号可以接收到事件推送.目前有2 ...

  8. uniapp之小程序端生成分享海报(带自定义参数的二维码)

    内容需求: 小程序端生成一个海报,海报内容包括当前授权账号的头像,当前授权账号的邀请码,一张特定图片,分享页面的带对应参数的小程序二维码:生成的海报需要保存到本地 功能方法: 1.前端用canvas绘 ...

  9. 微信小程序生成带参数的二维码

    微信小程序生成带参数的二维码 //写一个图片来写路径,好让二维码显示出来 <image style="width:500rpx;height:500rpx;" src=&qu ...

最新文章

  1. ros 配置udev
  2. 对象存储使用案例_连云数据都有“对象存储”了,你还是单身?
  3. 形象的表述sigmoid的神经网络万能近似定理
  4. nginx和apache的伪静态区别
  5. ABP框架 v2.7.0已经发布!
  6. 怎样用bootsrapcol-md来实现四分屏_用会议平板提升会议效率,做好这两点
  7. 企业资源计划软件 业务知识点汇编整理
  8. C++基础教程之数据结构
  9. UVA 10803 - Thunder Mountain
  10. 太火了,这些牛逼的Java代码技巧,肯定能让你目瞪口呆!
  11. 微信公众号中视频下载的2种方法
  12. 历史上各大帝国面积排行榜
  13. 12岁的B站,放慢脚步做社区
  14. minigui学习笔记四
  15. Web 中的“选区”和“光标”需求实现
  16. Google Pay支付遇到的问题,妈妈再也不用担心我的面试
  17. Spring父子容器详解!!!!
  18. dota 英雄使用 曙光酒馆《2》
  19. 欢迎使用CSDN-markdown编辑器噶梦想偶尔
  20. [Linux转载]Linux 操作常用命令

热门文章

  1. 利用ClustrMaps | GoStats | 51la | Google Analytics统计和分析访问量
  2. 移动互联网新协议 GTP 中被曝多个高危漏洞,影响4G和5G 用户
  3. spring-boot-maven-plugin多模块install问题解决办法
  4. 抛出与抽象相对应的异常(61)
  5. BZOJ 3261: 最大异或和 [可持久化Trie]
  6. file does not exist 阿里云OSS图片上传遇到的问题
  7. openssl evp 对称加密(AES_ecb,ccb)
  8. 【资料整理】Eclipse快捷键
  9. DEDECMS使用SQL语句批量删除文章
  10. 【图文详解】,配置NLB群集