JPEG编码中的DCT与量化
来源:互联网 发布:linux下python mmap 编辑:程序博客网 时间:2024/06/08 19:00
研一上很快过去了,留下了若干课程资料的文件夹。最近整理一下这些资料,挑选一些有用的课程作业贴到博客里面来。
1. 简介
JPEG是最常用的有损图像压缩算法,而8×8的二维DCT(离散余弦变换)变换和量化又是该算法中的核心步骤。本文作业的例子,是针对一个8×8的数据块进行正反二维DCT变换、量化和反量化。
2. 作业题目
逐个读入8×8(十六进制文本串格式的)亮度数据块,依次进行二维DCT变换、量化(采用标准亮度量化表)、逆量化和逆二维DCT变换。输出原始数据、变换后的数据、量化表、量化后的数据、逆量化的数据和反变换的数据。
3. 过程
4. 源码
/* * main.cpp * * Created on: 2016.10.17 * Author: liboyang */#include <iostream>#include <stdlib.h>#include <math.h>#include <fstream>#include <string>#include <iomanip>#define MAXSIZE 64#define COL 8#define ROW 8#define PI 3.1415926using namespace std;int Char2Int(char c);void getIntInput(int index, int counterRow, string input);void DCT(int index);void IDCT(int index);void Quantisation(int index);void inverseQuantisation(int index);string inputString[4][ROW];int inputInt[4][ROW][COL];double outputDCT[4][ROW][COL];double outputIDCT[4][ROW][COL];double outputQuan[4][ROW][COL];double outputInverseQuan[4][ROW][COL];int quantisationChart[ROW][COL]= { {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}};int main() { string tempRead; ifstream inFile; /* Read from file */ inFile.open("./input.txt", ios::in); if (NULL == inFile) { cout << "文件打开失败!" << endl; return 1; } int counterInput = 0, indexInput = 0; while (getline(inFile, tempRead)) { inputString[indexInput][counterInput] = tempRead; counterInput++; if (counterInput == 7) { counterInput = 0; indexInput++; counterInput--; } } /*cout << "源图像样本16进制" << endl; for (int i = 0; i < 4; i++) { for (int j = 0; j < ROW; j++) { cout << setw(2) << inputString[i][j] << endl; } cout << endl; }*/ /* Change Hex to Dec */ for (int i = 0; i < 4; i++) { for (int j = 0; j < ROW; j++) { getIntInput(i, j, inputString[i][j]); } } cout << endl << "源图像样本10进制" << endl; for (int m = 0; m < 4; m++) { for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { cout << setw(2) << inputInt[m][i][j] << " \t"; } cout << endl; } cout << endl; } cout << endl << "DCT" << endl; /* DCT */ /* Each element minus 128 */ for (int m = 0; m < 4; m++) { for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { inputInt[m][i][j] -= 128; } } } for (int i = 0; i < 4; i++) { DCT(i); } for (int m = 0; m < 4; m++) { for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { cout << setw(2) << fixed << setprecision(1) << outputDCT[m][i][j] << " \t"; } cout << endl; } cout << endl; } cout << endl << "标准量化表" << endl; /* Quantisation */ for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { cout << setw(2) << quantisationChart[i][j] << " \t"; } cout << endl; } for (int i = 0; i < 4; i++) { Quantisation(i); } cout << endl << "量化系数" << endl; for (int m = 0; m < 4; m++) { for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { cout << setw(2) << fixed << setprecision(0) << outputQuan[m][i][j] << " \t"; } cout << endl; } cout << endl; } for (int i = 0; i < 4; i++) { inverseQuantisation(i); } cout << endl << "反量化系数" << endl; for (int m = 0; m < 4; m++) { for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { cout << setw(2) << fixed << setprecision(0) << outputInverseQuan[m][i][j] << " \t"; } cout << endl; } cout << endl; } cout << endl << "IDCT" << endl; for (int i = 0; i < 4; i++) { IDCT(i); } /* Each element add 128 */ for (int m = 0; m < 4; m++) { for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { outputIDCT[m][i][j] += 128; } } } for (int m = 0; m < 4; m++) { for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { cout << setw(2) << fixed << setprecision(0) << outputIDCT[m][i][j] << " \t"; } cout << endl; } cout << endl; } system("pause"); return 0;}int Char2Int(char c) { if (c >= '0'&& c <= '9') { return c - '0'; } else if (c >= 'A' && c <= 'F') { return c - 'A' + 10; } else if (c >= 'a' && c <= 'f') { return c - 'a' + 10; } return -1;}void getIntInput(int index, int counterRow, string input) { int first, second; int counter = 0; for (int i = 0; i < MAXSIZE; i+=3) { first = Char2Int(input[i]); second = Char2Int(input[i+1]); if (first != -1 && second != -1) { inputInt[index][counterRow][counter] = second + first * 16; counter++; } }}void DCT(int index) { double ALPHA, BETA; int u = 0; int v = 0; int i = 0; int j = 0; for (u = 0; u < ROW; u++) { for (v = 0; v < COL; v++) { if (u == 0) { ALPHA = 1.0 / sqrt(2); } else { ALPHA = 1.0; } if (v == 0) { BETA = 1.0 / sqrt(2); } else { BETA = 1.0; } double tmp = 0.0; for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) { tmp += inputInt[index][i][j] * cos((2*i+1)*u*PI/16) * cos((2*j+1)*v*PI/16); } } outputDCT[index][u][v] = ALPHA * BETA * tmp * 0.25; } }}void Quantisation(int index) { int u, v; for (u = 0; u < ROW; u++) { for (v = 0; v < COL; v++) { outputQuan[index][u][v] = round(outputDCT[index][u][v] / quantisationChart[u][v]); if (outputQuan[index][u][v] == -0) { outputQuan[index][u][v] = 0; } } }}void inverseQuantisation(int index) { int u, v; for (u = 0; u < ROW; u++) { for (v = 0; v < COL; v++) { outputInverseQuan[index][u][v] = outputQuan[index][u][v] * quantisationChart[u][v]; if (outputInverseQuan[index][u][v] == -0) { outputInverseQuan[index][u][v] = 0; } } }}void IDCT(int index) { double ALPHA, BETA; int u = 0; int v = 0; int i = 0; int j = 0; for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) { double tmp = 0.0; for (u = 0; u < ROW; u++) { for (v = 0; v < COL; v++) { if (u == 0) { ALPHA = 1.0 / sqrt(2); } else { ALPHA = 1.0; } if (v == 0) { BETA = 1.0 / sqrt(2); } else { BETA = 1.0; } tmp += ALPHA * BETA * cos((2*i+1)*u*PI/16) * cos((2*j+1)*v*PI/16) * outputInverseQuan[index][u][v]; } } outputIDCT[index][i][j] = 0.25 * tmp; } }}
0 0
- JPEG编码中的DCT与量化
- 关于JPEG库中的DCT变换到熵编码这一路
- 基于DCT的JPEG图像压缩编码过程及举例
- 实验三 基于DCT编码的JPEG压缩
- DCT变换和量化
- DCT变换和量化
- DCT 和量化
- JPEG压缩原理与DCT离散余弦变换
- JPEG压缩原理与DCT离散余弦变换
- JPEG标准DCT算法
- 量化与“Z”字编码
- JPEG压缩过程 DCT算法
- JPEG压缩原理(DCT)
- JPEG标准DCT优化实现
- DCT编码原理分析
- 8*8DCT、量化、zigzag扫描
- JPEG压缩编码方法与实现
- jpeg图像的压缩编码与解码
- 覆盖索引
- 51nod 1478 括号序列的最长合法子段(栈-括号匹配寻找最长合法子串长度及其个数)
- 转载:移动前端开发之viewport的深入理解
- 文章标题
- go提问模板
- JPEG编码中的DCT与量化
- iOS消息机制--动态方法解析、消息转发机制
- Codeforces Round #404 (Div. 2) D. Anton and School
- 【并发】volatile详解
- xampp mysql无法启动。
- Eclipse GitHub SSH2 key配置
- 使用IDEA创建一个Spring Boot项目
- Flask-heroku部署相关问题
- string类的用法