DCT变换及量化的c++实现(基于opencv矩阵运算)
2017-05-27 23:17
701 查看
由于DCT的数学原理不好描述,直接放代码了:
#include<iostream> #include<fstream> #include<opencv2/core/core.hpp> #include<opencv2/highgui/highgui.hpp> using namespace std; using namespace cv; const double pi = 3.141592; void initDctMat(Mat &A) //计算8x8块的离散余弦变换系数 { for (int i = 0; i < 8; ++i) for (int j = 0; j < 8; ++j) { float a; if (i == 0) a = sqrt(1.0 / 8.0); else a = sqrt(2.0 / 8.0); A.ptr<float>(i)[j] = a*cos((j + 0.5)*pi*i / 8); } } //dct变换 void myDct(Mat &image, const Mat &A, const Mat &mask) { //分块 8x8 for(int i = 0; i < 256; i+=8) for (int j = 0; j < 256; j += 8) { //X = AXAT image(Range(i, i + 8), Range(j, j + 8)) = A * image(Range(i, i + 8), Range(j, j + 8)) *A.t(); //用mask量化 image(Range(i, i + 8), Range(j, j + 8)) /= mask; } } //dct反变换 void myiDct(Mat &image, const Mat &A, const Mat &mask) { //分块8x8 for (int i = 0; i < 256; i += 8) for (int j = 0; j < 256; j += 8) { //还原量化 image(Range(i, i + 8), Range(j, j + 8)) = image(Range(i, i + 8), Range(j, j + 8)).mul(mask); //X = ATXA image(Range(i, i + 8), Range(j, j + 8)) = A.t() * image(Range(i, i + 8), Range(j, j + 8)) * A; } } int main() { //读取图像,图像为灰度图,单通道 Mat image = imread("lena.bmp",CV_LOAD_IMAGE_GRAYSCALE); Mat fimage; Mat A(Size(8, 8), CV_32FC1);// 离散余弦系数矩阵 //初始化mask量化矩阵 float msk[8][8] = { {16,11,10,16,24,40,51,61},{12,12,14,19,26,58,60,55},{14,13,16,24,40,57,69,56},{14,17,22,29,51,87,80,62},{18,22,37,56,68,109,103,77},{24,35,55,64,81,104,113,92},{49,64,78,87,103,121,120,101},{72,92,95,98,112,100,103,99}}; Mat mask(8, 8, CV_32FC1, msk); //显示原图 if (!image.empty()) imshow("image", image); //计算A系数 initDctMat(A); //转换成浮点数矩阵,进行dct变换 image.convertTo(fimage, CV_32FC1); myDct(fimage, A, mask); //计算压缩率, 用非零矩阵点数量比总数量、 fimage.convertTo(image, CV_8UC1); double dctRate = countNonZero(image) / (256.0 * 256.0); cout << "the size becomes " << dctRate * 100 << "% of the original." << endl; imshow("压缩图", fimage); //dct反变换 myiDct(fimage, A, mask); //显示还原的图像 fimage.convertTo(image, CV_8UC1); imshow("还原图", image); waitKey(0); return 0; }运行结果:
相关文章推荐
- OpenCV实现基于8*8块DCT变换的图像压缩
- 在C++中实现矩阵运算
- C/C++语言实现矩阵求逆运算—高斯约化/消元法
- C++矩阵运算实现
- H.264中整数DCT变换,量化,反量化,反DCT究竟是如何实现的?(无代码,无真相)
- OpenCV Mat 四则运算符实现矩阵运算
- H.264中整数DCT变换,量化,反量化,反DCT究竟是如何实现的?
- VS2010实现opencv基于DCT的图像压缩
- 利用SIFT和RANSAC算法(openCV框架)实现物体的检测与定位,并求出变换矩阵(findFundamentalMat和findHomography的比较)
- C++实现矩阵运算
- opencv2.0以后新增C++接口的 Mat矩阵 单行赋值及矩阵合并的问题与实现(苦心研究多天才解决!)
- OpenCV C++ API 矩阵常用运算
- C++实现矩阵类,实现了大部分矩阵运算功能,大家可以类比matlab
- OpenCV 区域编码和阈值编码实现图像压缩(8*8DCT变换,保留50%的系数)
- zz:基于 OpenCV 的矩阵运算 (CvMat)
- VS2010实现opencv基于DCT的图像压缩
- 直方图均衡化的 C++ 实现(基于 openCV)
- 匈牙利算法的C++实现(基于OpenCV)
- H.264中整数DCT变换,量化,反量化,反DCT究竟是如何实现的?
- C++实现R语言向量化运算(向量类:c 矩阵类:matrix)2015.9.11