离散余弦函数(c++实现)
来源:互联网 发布:淘宝专业刷信誉网站 编辑:程序博客网 时间:2024/05/16 15:45
理论:
图像处理中常用的正交变换除了傅里叶变换外,还有其他一些有用的正交变换,其中离散余弦就是一种。离散余弦变换表示为DCT( Discrete Cosine Transformation),常用于图像处理和图像识别等。
一维离散余弦变换
正变换
(1)
(2)
式中F(u)是第u个余弦变换系数,u是广义频率变量,u=1,2,3……N-1; f(x)是时域N点序列, x=0,1,2……N-1
反变换
(3)
显然,式(1)式(2)和式(3)构成了一维离散余弦变换对。
二维离散余弦变换
正变换
(4)
式(4)是正变换公式。其中f(x,y)是空间域二维向量之元素, x,y=0,1,2,……N-1;F(u,v)是变换系数阵列之元素。式中表示的阵列为N×N
反变换
(5)
式中的符号意义同正变换式一样。式(4)和式(5)是离散余弦变换的解析式定义。
矩阵表示法
更为简洁的定义方法是采用矩阵式定义。根据以上公式定义可知,离散余弦变换的系数矩阵可以写成如下:
如果令N=4,那么由一维解析式定义可得如下展开式。
写成矩阵式
若定义F(u)为变换矩阵,A为变换系数矩阵,f(x)为时域数据矩阵,则一维离散余弦变换的矩阵定义式可写成如下形式
[F(u)]=[A][f(x)] (6)
同理,可得到反变换展开式
写成矩阵式即
[f(x)]=[A]T[F(u)] (7)
二维离散余弦变换也可以写成矩阵式:
[F(u,v)]=[A][f(x,y)][A]T (8)
[f(x,y)]=[A]T[F(u,v)][A]
式中[f(x,y)]是空间数据阵列,A是变换系数阵列,[F(u,v)]是变换矩阵,[A]T是[A]的转置。
对二维图像进行离散余弦变换
由以上对二维离散余弦变换的定义及公式(7)可知,求二维图像的离散余弦变换要进行以下步骤:
1.获得图像的二维数据矩阵f(x,y);
2.求离散余弦变换的系数矩阵[A];
3.求系数矩阵对应的转置矩阵[A]T;
4.根据公式(7)[F(u,v)]=[A][f(x,y)][A]T 计算离散余弦变换;
实现代码:
#include<opencv2/opencv.hpp>#include<bitset>using namespace std;using namespace cv;void coefficient(const int& n,double** p,double** q){ double t = 1.0 / sqrt(n+0.0); for (int i = 0; i < n;i++){ q[0][i] = t; p[i][0] = t; } for (int i = 1; i < n;i++){ for (int j = 1; j < n;j++){ q[i][j] = sqrt(2.0 / n)*cos(i*(j + 0.5)*CV_PI / n); p[j][i] = q[i][j]; } }}void matrix_computation(double** result,double** q,double** p, int &n){ double t = 0; for (int i = 0; i < n;i++){ for (int j = 0; j < n;j++){ t = 0; for (int k = 0; k < n;k++){ t += q[i][j] * p[j][i]; } result[i][j] = t; } }}void DCT(Mat_<uchar> img,double** iMatrix,int &n){ for (int i = 0; i < n;i++){ for (int j = 0; j < n; j++){ iMatrix[i][j] = img(i, j); } } double** coefficient1 = new double*[n]; double** coefficient2 = new double*[n]; double** tmp = new double*[n]; for (int i = 0; i < n; i++){ coefficient1[i] = new double[n]; coefficient2[i] = new double[n]; tmp[i] = new double[n]; } coefficient(n, coefficient1, coefficient2); matrix_computation(tmp,coefficient1,iMatrix,n); matrix_computation(iMatrix, coefficient2, tmp, n); for (int i = 0; i < n; i++){ delete[] coefficient1[i]; delete[] coefficient2[i]; delete[] tmp[i]; } delete[] coefficient1; delete[] coefficient2; delete[] tmp;}void calc(double** iMatrix,bitset<64> &it){ double sum=0; for (int i = 0; i < 8; i++){ for (int j = 0; j < 8; j++){ sum += iMatrix[i][j]; } } double average = sum / 64; for (int i = 0; i < 8; i++){ int pos = i * 8; for (int j = 0; j < 8; j++){ it.at(pos+j)=iMatrix[i][j] >= average ? 1 : 0; } }}int main(){ Mat img = imread("6.jpg"); bitset<64> bits; resize(img, img, Size(32, 32)); cvtColor(img, img, CV_BGR2GRAY); int n = img.rows; double** imatrix = new double*[n]; for (int i = 0; i < n;i++){ imatrix[i] = new double[n]; } DCT(img,imatrix,n); calc(imatrix, bits); for (int i = 0; i < 64; i++){ cout << bits.at(i); } cout << endl; Mat img1 = imread("1.jpg"); bitset<64> bits1; resize(img1, img1, Size(32, 32)); cvtColor(img1, img1, CV_BGR2GRAY); int n1 = img1.rows; double** imatrix1 = new double*[n1]; for (int i = 0; i < n1; i++){ imatrix1[i] = new double[n1]; } DCT(img1, imatrix1, n1); calc(imatrix1, bits1); for (int i = 0; i < 64; i++){ cout << bits1.at(i); } for (int i = 0; i < n1; i++){ delete[] imatrix1[i]; } for (int i = 0; i < n; i++){ delete[] imatrix[i]; } delete[] imatrix; cin.get(); delete[] imatrix1; return 0;}
- 离散余弦函数(c++实现)
- C实现 离散余弦转换DCT 源代码
- 离散余弦变换(C++实现)
- 傅里叶与离散余弦(计算机图像处理实现)研究
- 离散余弦变换(DCT)
- DCT离散余弦变换C版本
- DCT离散余弦变换C版本【转】
- 快速离散余弦变换代码实现(FDCT)
- 离散余弦变换的C++实现
- matlab实现离散余弦变换(DCT)
- 关于离散余弦变换(DCT)---转载
- 图像变换(离散余弦变换DCT)
- 离散余弦变换(Discrete Cosine Transform)
- 离散余弦变换(Discrete Cosine Transform)
- 离散余弦变换(DCT)的来龙去脉
- 快速逆离散余弦变换代码实现(FIDCT)
- DCT(discrete cosine transform)离散余弦变换及matlab实现
- 离散余弦变换 DCT
- Android中,判断是否联网,连接的是移动数据还是WiFi,移动数据是2g,3g,还是4g
- AndroidStudio 下SVN的使用
- Handler 源码解析
- python 集合类型总结表
- html5 中form表单post与get方法的区别
- 离散余弦函数(c++实现)
- ListView的简单实用及其优化
- 定时关机软件
- 简单的轮播图效果实现
- 报表开发之自定义函数
- HDU 5733 tetrahedron(计算几何)【多校联合】
- Android —— 枚举Enum
- Java 反射机制(1)
- Windows与USB的通信