版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/feimengjuan/article/details/50949152
这几天一直在看MPEG编解码的原理,由于利用ffmpeg实在提不出DCT系数,就根据MPEG的编码原理来看看这个DCT系数到底什么样,于是在OpenCV中实现了一下图像压缩这一块,基于8*8块DCT变换,同时也再进行了一下反变换,最后得到了原图。
代码如下:
#include "highgui.h"
#include <cv.h>
#include<iostream>
using namespace std;
using namespace cv;
int main()
{
Mat img = imread("1.jpg");
//分解为YUV颜色空间
Mat YUVImage;
cvtColor(img,YUVImage,CV_BGR2YUV);
//分解为三个通道
vector<Mat> YUV;
split(YUVImage,YUV);
//先转换下格式
Mat float_Y,float_U,float_V;
YUV[0].convertTo(float_Y,CV_64FC1);
YUV[1].convertTo(float_U,CV_64FC1);
YUV[2].convertTo(float_V,CV_64FC1);
//基于8*8块的DCT变换及其反变换
Rect windows; //利用这个8*8的矩形来进行8*8块的DCT变换
//DCT变换
Mat DCTU,DCTV,DCTY;
float_Y.copyTo(DCTY);
float_U.copyTo(DCTU);
float_V.copyTo(DCTV);
for (int i = 0;i<img.cols/8;i++)
{
for (int j = 0;j<img.rows/8;j++)
{
windows.x = 8 * i;
windows.y = 8 * j;
windows.height = 8;
windows.width = 8;
dct(float_Y(windows),DCTY(windows));
dct(float_U(windows),DCTU(windows));
dct(float_V(windows),DCTV(windows));
}
}
////反DCT变换
for (int i = 0;i<img.cols/8;i++)
{
for (int j = 0;j<img.rows/8;j++)
{
windows.x = 8 * i;
windows.y = 8 * j;
windows.height = 8;
windows.width = 8;
dct(DCTY(windows),float_Y(windows),DCT_INVERSE);
dct(DCTU(windows),float_U(windows),DCT_INVERSE);
dct(DCTV(windows),float_V(windows),DCT_INVERSE);
}
}
vector<Mat> YUV_dst(3);
//格式转换
float_Y.convertTo(YUV_dst[0],CV_8UC1);
float_U.convertTo(YUV_dst[1],CV_8UC1);
float_V.convertTo(YUV_dst[2],CV_8UC1);
//将三个通道进行合并
Mat yuv,dst_RGB;
merge(YUV_dst,yuv);
//转为RGB图像
cvtColor(yuv,dst_RGB,CV_YUV2BGR);
imshow("Y",DCTY);
imshow("U",DCTU);
imshow("V",DCTV);
imshow("dst",dst_RGB);
waitKey(0);
system("pause");
}