OpenCV实现基于8*8块DCT变换的图像压缩

版权声明:本文为博主原创文章,未经博主允许不得转载。 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");
}


猜你喜欢

转载自blog.csdn.net/feimengjuan/article/details/50949152