8*8DCT、量化、zigzag扫描
来源:互联网 发布:数据库分库分表策略 编辑:程序博客网 时间:2024/06/01 10:40
距上次说的DCT处理有段时间了。8*8DCT就是对图片进行划分为多个8*8块的方正进行DCT处理,然后对处理后的矩阵进行量化(这个处理对原图是有损的),由DCT处理的特征,我们对处理后的矩阵进行zigzag scan。具体原理请见:jpeg压缩原理(大牛的)
代码附上:
// myDCT.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include "cv.h"#include "highgui.h"#include "winsock.h"#include <iostream>#include <iomanip>#include <vector>#include <string>using namespace std;void dct(IplImage* img);void zigzag(CvMat* m,int n,vector<double> &v);vector<double> v;int _tmain(int argc, _TCHAR* argv[]){const char* img_name="image_0002.jpg";IplImage* img=cvLoadImage(img_name,1);if(!img)//载入失败{cout<<"load image fail!"<<endl;system("pause");return -1;}if(!img->imageData)//载入的图像数据是否正确{system("pause");return -1;}dct(img);cvReleaseImage(&img);system("pause");return 0;}/*对图像进行DCT处理*/void dct(IplImage* img){IplImage* imggray=cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1);cvCvtColor(img,imggray,CV_RGB2GRAY);//获取图像信息int height,width,step,channels;uchar *data;height=imggray->height;width=imggray->width;step=imggray->widthStep;channels=imggray->nChannels;data=(uchar *)imggray->imageData;//定义一个图像矩阵CvMat *img_mat= cvCreateMat(width,height, CV_64FC1);IplImage* dst=cvCreateImage(cvSize(width,height),IPL_DEPTH_64F,1);//把图像转化为矩阵cvConvert(imggray,img_mat);//矩阵分块 设置了一个8*8子矩阵遍历提取原矩阵数据,进行DCT变换,赋值给另一矩阵CvMat *imgmatfenkuai=cvCreateMat(width, height, CV_64FC1);cvSetIdentity(imgmatfenkuai);CvMat *imgmatquantize8;//量化系数int QS[8][8] ={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};/*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 s=0;s<width/8;s++){for(int k=0;k<height/8;k++){//从img_mat中取出8*8子块CvMat *imgmatsub=cvCreateMat(8,8,CV_64FC1);CvRect imgmatsubrect=cvRect(8*s,8*k,8,8);cvGetSubArr(img_mat,imgmatsub,imgmatsubrect);IplImage* imgdstsub=cvCreateImage(cvSize(8,8),IPL_DEPTH_64F,1);//对字块进行DCT处理cvDCT(imgmatsub,imgdstsub,CV_DXT_FORWARD);CvMat *imgmatdctsub=cvCreateMat(8,8,CV_64FC1);//把DCT图像转化成矩阵cvConvert(imgdstsub,imgmatdctsub);imgmatquantize8=cvCreateMat(8,8,CV_64FC1);for (int i=0;i<8;i++){for(int j=0;j<8;j++){//往分imgmatfenkuai矩阵中添加经过DCT处理后值cvmSet(imgmatfenkuai,8*s+i,8*k+j,cvmGet(imgmatdctsub,i,j));//对经过DCT后字块进行量化double lianghua=cvRound(cvmGet(imgmatdctsub,i,j)/QS[i][j]);//quantization *QS[i][j]//另将量化后值存在imgmatquantize8中,以便之后对之进行zigzag扫描cvmSet(imgmatquantize8,i,j,lianghua);}}//对量化后矩阵进行zigzag扫描zigzag(imgmatquantize8,8,v);cvReleaseMat(&imgmatsub);cvReleaseMat(&imgmatdctsub);cvReleaseImage(&imgdstsub);cvReleaseMat(&imgmatquantize8);}}//对每个8*8矩阵zigzag扫描后的向量进行遍历输出vector<double>::iterator it=v.begin();while(it!=v.end()){cout<<(*it)<<" ";it++;}v.clear();cvReleaseImage( &imggray );}/*对矩阵进行zigzag扫描,m表示扫描矩阵,n表示矩阵维度,v为扫描后得到的定长向量*/void zigzag(CvMat* m,int n,vector<double> &v){int i,j,s,dir,squa;i=j=0;dir=0;s=0;squa=n*n;//扫描while(s<squa){switch(dir){case 0:v.push_back(cvmGet(m,i,j));j++;if(0==i)dir=1;if(n-1==i)dir=3;break;case 1:v.push_back(cvmGet(m,i,j));i++;j--;if(n-1==i)//这里有if和else,注意这里的逻辑和上面两个if的逻辑有区别的dir=0;else if(0==j)dir=2;break;case 2:v.push_back(cvmGet(m,i,j));i++;if(0==j)dir=3;if(n-1==j)dir=1;break;case 3:v.push_back(cvmGet(m,i,j));i--;j++;if(n-1==j)dir=2;else if(0==i)dir=0;break;default:break;}s++;}}Reference:
8*8DCT
zigzag数组
0 0
- 8*8DCT、量化、zigzag扫描
- DCT变换和量化
- DCT变换和量化
- DCT 和量化
- Zigzag扫描
- JPEG编码中的DCT与量化
- 4*4整数快速变换(包括DCT变换量化以及反DCT变换反量化)
- H.264中整数DCT变换,量化,反量化,反DCT究竟是如何实现的?
- H.264中整数DCT变换,量化,反量化,反DCT究竟是如何实现的?
- DCT变换以及量化,反量化,逆DCT变换的实现。
- H.264中整数DCT变换,量化,反量化,反DCT究竟是如何实现的?
- H.264中整数DCT变换,量化,反量化,反DCT究竟是如何实现的?
- zigzag图像扫描
- zigzag扫描 简单介绍
- Zigzag逆扫描
- 8叉树量化
- H.264中整数DCT变换,量化,反量化,反DCT究竟是如何实现的?(无代码,无真相)
- H.264中整数DCT变换,量化,反量化,反DCT究竟是如何实现的?(无代码,无真相)
- struts2指定欢迎页面为action请求
- 学习Linux 《鸟哥的Linux私房菜 基础学习篇(第三版)》--第6章 Linux的档案权限与目录配置 笔记
- 关于sudo找不到命令
- 哈希 poj3349 Snowflake Snow Snowflakes
- OFBIZ分享:关于contronal.xml 文件中response的类型
- 8*8DCT、量化、zigzag扫描
- oracle表列约束
- MFC控件使用在项目上的总结
- [C++] 异常处理
- MYSQL多表查询
- android学习笔记---事件分发(下)
- Android中Service类onStartCommand
- 有关于数据库
- OFBIZ分享:base-permission该如何设置