C++实现离散余弦变换(参数为Eigen矩阵)
C++实现离散余弦变换(参数为Eigen矩阵)
问题描述
昨天写了一个参数为二维指针为参数的离散余弦变换,虽然改进了参数为二维数组时,当数组大小不确定时声明函数时带来的困难,但使用指针作为参数也存在一些不足之处,比如需要手动寻址、容易出现指针越界等。因此这篇文章中的代码对昨天的代码做了进一步的改进,将函数的参数设置为Eigen矩阵,很好的避免了上述问题。
DCT
代码的主体跟之前的代码没啥差别,主要就是改变了函数的参数类型
// DCT - Discrete Cosine Transform
void DCT( MatrixXd &input, MatrixXd &output )
{
    cout<<"Test in DCT"<<endl;
    double ALPHA, BETA;
    int u = 0;
    int v = 0;
    int i = 0;
    int j = 0;
    int row = input.rows();
    int col = input.cols();
    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 += input(i,j) * cos((2*i+1)*u*PI/(2.0 * row)) * cos((2*j+1)*v*PI/(2.0 * col));
                }
            }
            output(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)<< output(m,n) <<" \t";
        }
        cout << endl;
    }
}
注意比较上述Eigen数组的访问方法。访问Eigen矩阵的i行j列元素是,使用的是(i,j)
IDCT代码
// Inverse DCT
void IDCT( MatrixXd &input, MatrixXd &output )
{
    cout<<"Test in IDCT"<<endl;
    double ALPHA, BETA;
    int u = 0;
    int v = 0;
    int i = 0;
    int j = 0;
    int row = input.rows();
    int col = input.cols();
    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 * input(u,v)* cos((2*i+1)*u*PI/(2.0 * row)) * cos((2*j+1)*v*PI/(2.0 * col));
                }
            }
            output(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)<< output(m,n)<<"\t";
        }
        cout << endl;
    }
}
测试代码
#include <iostream>
#include <math.h>
#include<cstdio>
#include <iomanip>
#include<algorithm>
#include<fstream>
#include<math.h>
#include<string>
#include <Eigen/Dense> 
using namespace std;
using namespace Eigen;
#define PI 3.1415926
int main()
{
    int i = 0;
    int j = 0;
    int u = 0;
    int v = 0;
    const int rows = 4;
    const int cols = 2 ;
    double inputdata[rows][cols] = {
        {89,23},
        {73,48},
        {45,67},
        {56, 102},
    };
    double outputdata[rows][cols];
    MatrixXd minput;
    MatrixXd moutput;
    minput.setZero(4,2);
    moutput.setZero(4,2);
    for (int i = 0; i < minput.rows(); i++)
    {
        for (int j = 0; j < minput.cols(); j++)
        {
            minput(i,j) = inputdata[i][j];
        }
    }
    DCT( minput, moutput );
    IDCT(moutput, minput);
    system("pause");
    return 0;
}
运行结果

转载请注明出处:http://www.cnblogs.com/scut-linmaojiang/p/5016811.html
C++实现离散余弦变换(参数为Eigen矩阵)的更多相关文章
- C++实现离散余弦变换(参数为二维指针)
		
C++实现离散余弦变换(参数为二维指针) 写在前面 到目前为止已经阅读了相当一部分的网格水印等方面的论文了,但是论文的实现进度还没有更上,这个月准备挑选一些较为经典的论文,将其中的算法实现.在实现论文 ...
 - 二维离散余弦变换(2D-DCT)
		
图像处理中常用的正交变换除了傅里叶变换以外,还有一些其它常用的正交变换,其中离散余弦变换DCT就是一种,这是JPEG图像压缩算法里的核心算法,这里我们也主要讲解JPEG压缩算法里所使用8*8矩阵的二维 ...
 - DCT(离散余弦变换)算法原理和源码(python)
		
原理: 离散余弦变换(DCT for Discrete Cosine Transform)是与傅里叶变换相关的一种变换,它类似于离散傅里叶变换(DFT for Discrete Fourier Tra ...
 - Matlab/Eigen矩阵填充问题
		
Matlab进行矩阵填充时可以填充空矩阵,相当于空矩阵不存在,例如一下代码: P_RES = [ P_xv P_xvy P_xv*dy_dxv'; P_yxv P_y P_yxv*dy_dxv'; d ...
 - Eigen 矩阵库学习笔记
		
最近为了在C++中使用矩阵运算,简单学习了一下Eigen矩阵库.Eigen比Armadillo相对底层一点,但是只需要添加头文库即可使用,不使用额外的编译和安装过程. 基本定义 Matrix3f是3* ...
 - eigen矩阵操作练习
		
// // Created by qian on 19-7-16. // /* 相机位姿用四元数表示 q = [0.35, 0.2, 0.3, 0.1] x,y,z,w * 注意:输入时Quatern ...
 - Eigen矩阵基本运算
		
1 矩阵基本运算简介 Eigen重载了+,-,*运算符.同时提供了一些方法如dot(),cross()等.对于矩阵类的运算符重载只支持线性运算,比如matrix1*matrix2是矩阵相乘,当然必须要 ...
 - 优化IPOL网站中基于DCT(离散余弦变换)的图像去噪算法(附源代码)。
		
在您阅读本文前,先需要告诉你的是:即使是本文优化过的算法,DCT去噪的计算量依旧很大,请不要向这个算法提出实时运行的苛刻要求. 言归正传,在IPOL网站中有一篇基于DCT的图像去噪文章,具体的链接地址 ...
 - C++矩阵库 Eigen 快速入门
		
最近需要用 C++ 做一些数值计算,之前一直采用Matlab 混合编程的方式处理矩阵运算,非常麻烦,直到发现了 Eigen 库,简直相见恨晚,好用哭了. Eigen 是一个基于C++模板的线性代数库, ...
 
随机推荐
- 李洪强漫谈iOS开发[C语言-010] - C语言简要复习
			
// // main.m // 05 - 简要复习 // // Created by vic fan on 16/7/13. // Copyright © 2016年 李洪强. All rig ...
 - JAVA:23种设计模式详解(转)2
			
我们接着讨论设计模式,上篇文章我讲完了5种创建型模式,这章开始,我将讲下7种结构型模式:适配器模式.装饰模式.代理模式.外观模式.桥接模式.组合模式.享元模式.其中对象的适配器模式是各种模式的起源,我 ...
 - Photoshop:建议设置
			
一.新建文档设置: 二.对齐设置 菜单->视图->对齐->全部 使用图层.形状等操作时自动对齐网格,画矢量图不怕模糊边缘,确保每个像素保持清晰. 三.首选项设置 关掉"启用 ...
 - NPOI操作EXCEL----------NPOI基础01
			
来源地址:http://www.cnblogs.com/csqb-511612371/p/4878059.html 先来介绍一下NPOI基本的东西: 1.下载地址:http://npoi.codepl ...
 - [Mongo] error inserting documents: BSONObj size is invalid (mongoimport mongorestore 数据备份恢复)
			
解决办法如下, ./mongoimport -port 6066 -d xxx -c xxx --batchSize=10 /root/mong_data/test/xxx 原因转自 http://b ...
 - i386 和amd64 的意思
			
首先可以简化一个概念,i386=Intel 80386.其实i386通常被用来作为对Intel(英特尔)32位微处理器的统称. Windows NT类系统的安装盘上,通常i386是其根上的一个文件夹, ...
 - HDFS小文件处理——Mapper处理
			
处理小文件的时候,可以通过org.apache.hadoop.io.SequenceFile.Writer类将所有文件写出到一个seq文件中. 大致流程如下: 实现代码: package study. ...
 - Ubuntu安装Apache
			
在虚拟机上安装了Ubuntu13.10 ,然后使用命令 sudo apt-get install apache2 安装apache总提示“E: 未找到软件包...”,不知所踪,这可能是新手容易的犯 的 ...
 - useradd和adduser的区别
			
1. 在root权限下,useradd只是创建了一个用户名,如 (useradd +用户名 ),它并没有在/home目录下创建同名文件夹,也没有创建密码,因此利用这个用户登录系统,是登录不了的,为了 ...
 - 打开一个已经写好的Android studio工程的方法