当前位置:文档之家› 基于DCT变换的图像编解码matlab代码

基于DCT变换的图像编解码matlab代码

///////////////////////////////////////////////////////////// /////////////////////////////////////////// 基于块的变换编码//读入灰度图像数据,完成8*8像素块余弦变换并进行DCT系数矩阵量化,把得到的量化矩阵游程编码///////////////////////////////////////////////////////////// /////////////////////////////////////////#include<stdio.h>#include<iostream>#include<iomanip>#include<stdlib.h>#include<fstream>#include<math.h>#define PI 3.1415926#define WIDTH 256#define HEIGHT 256using namespace std;double arr[WIDTH][HEIGHT]={0}; //自定义数组保存文件二进制数据double dct2[8][8]={100}; //自定义数组保存待变换8*8像素块二进制数据int x(14),y(22); //任意设定开始选定数据坐标void DCT(int,int,double dct2[8][8]); //余弦变换算法函实现数double CuCv(int); //中间函数C(u),C(v) void Quant(double dct2[8][8]); //均匀量化函数void Run_level(double dct2[8][8]); //游程编码函数//*********************************************************** ********************************************void main(){char ch;int data[8][8]={0};FILE *fp = NULL; //创建文件指针并初始化//----------------------------------------------------------以二进制只读形式打开待处理IMG文件fp = fopen("LENA256.IMG","rb");if(fp == NULL)//如果失败了{printf("Buffer error! Program terminated!!\n\n");}ofstream outfile("源文件二进制数据.txt"); //建立文件char buf[24];int count = 0;//----------------------------------------------------------将读入文件的数据保存在自定义数组中for(int i (0);i<WIDTH;i++){for(int j(0);j<HEIGHT;j++){int c=fgetc(fp);arr[i][j] = c;}}fclose(fp); //关闭文件cout<<"256*256选定8*8像素块开始坐标:"<<endl<<x<<endl <<y<<endl;//----------------------------------------------------------选定8*8像素块,并保存数据到文本文件中for(int i(x);i<x+8;i++){for(int j(y);j<y+8;j++){outfile <<setw(3)<< arr[i][j] <<" ";}outfile<<endl;}outfile.close();DCT(x,y,dct2); //余弦变换Quant(dct2); //均匀量化for(int i = 0;i < 8 ;i++) //变换结果输出到文本文件中{for(int j = 0;j < 8;j++){cout<< dct2[i][j] <<" ";}}cout<<endl<<endl;Run_level(dct2);//zig-zag游程编码system("pause");}//*********************************************************** ********************************************void DCT(int m,int n,double dct2[8][8]) //余弦变换算法实现函数{for(int u(0);u<8;u++){for(int v(0);v<8;v++){double sum=0;for(int i(0);i<8;i++){for(int j(0);j<8;j++){sum=sum+(arr[m+i][n+j]*cos((2*i+1)*u*PI/16)*cos((2*j+1)*v* PI/16));}}double temp=CuCv(u)*CuCv(v);dct2[u][v]=int(temp*sum/4+0.5); //余弦变换后的值,四舍五入取整}}ofstream outfile2("余弦变换取整后数据.txt");for(int i = 0;i < 8 ;i++) //变换结果输出到文本文件中{for(int j = 0;j < 8;j++){outfile2 <<setw(3)<< dct2[i][j] <<" ";}outfile2<<endl; //得到DCT系数矩阵}outfile2.close();}//*********************************************************** ********************************************double CuCv(int a) //中间函数C(u),C(v){if(a==0){return 1/pow(2,0.5);}else{return 1;}}//*********************************************************** ********************************************void Quant(double dct2[8][8]) //均匀量化函数{int QS[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};for(int i(0);i<8;i++){for(int j(0);j<8;j++){dct2[i][j]=int(double(dct2[i][j])/QS[i][j]+0.5);}}ofstream outfile3("均匀量化后数据.txt");for(int i = 0;i < 8 ;i++) //变换结果输出到文本文件中{for(int j = 0;j < 8;j++){outfile3 <<setw(3)<< dct2[i][j] <<" ";}outfile3<<endl; //得到DCT系数矩阵}outfile3.close();}//*********************************************************** ********************************************void Run_level(double dct2[8][8]) //游程编码函数{int k(0),a[8][8]={0};int i(0),j(0),s(0); //i=行----j=列----s=总行/列数int dir(0); //扫描方向,0:右方,1:左下,2:下方,3:右上ofstream outfile4("游程符号.txt");while(s<8*8){a[i][j]=dct2[i][j]; //初始化zig-zag扫描位置int temp0=i,temp1=j;switch(dir) //下一个扫描位置{case 0:j++; //行进方向if(i==0)dir=1;if(i==7)dir=3;break;case 1:i++;j--;if(i==7)dir=0;else if(j==0)dir=2;break;case 2:i++;if(j==0) dir=3; if(j==7) dir=1; break;case 3:i--;j++;if(j==7)dir=2;else if(i==0)dir=0;break;default:break;}if(a[temp0][temp1]!=dct2[i][j]){ //输出游程符号到文件if(a[temp0][temp1]!=0){if(k!=0) k++;outfile4<<"("<<k<<","<<a[temp0][temp1]<<") ";k=0;}}else k++;s++;}outfile4.close();}。

相关主题