#include<bits/stdc++.h>
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;
const double pi = 3.1415926;
int width, height, channels;
double dct1[80][80][10][10];
double result[80][80][10][10];
double result2[80][80][10][10];
double tmp[10][10];
double to[10][10];
double alpha(int x)
{
if (x == 0)
return sqrt(1.0 / 8.0);
return sqrt(2.0 / 8.0);
}
int H, W;
int main()
{
// 【1】读入一张图片,载入图像
Mat srcImage = imread("D:\\OneDrive\\桌面\\下载.jfif", 0);
Mat image = srcImage.clone();
height = srcImage.rows;
width = srcImage.cols;
channels = srcImage.channels();
H = height / 8;
W = width / 8;
//初始化
for (int i = 0; i < height; i++)
{
uchar* data = srcImage.ptr<uchar>(i);
uchar* data2 = image.ptr<uchar>(i);
for (int j = 0; j < width; j++)
{
dct1[i / 8][j / 8][i % 8][j % 8] = double(data[j]);
data2[j] = data[j];//初始化边角
}
}
//对每个8*8矩阵计算dct和逆dct
for (int h = 0; h < H; h++)
for (int w = 0; w < W; w++)
{
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
{
result[h][w][i][j] = 0.0;
for (int i2 = 0; i2 < 8; i2++)
for (int j2 = 0; j2 < 8; j2++)
{
result[h][w][i][j] = 1.0 * result[h][w][i][j] + 1.0 * dct1[h][w][i2][j2] * alpha(i) * alpha(j) * cos(pi / 16.0 * i * (2.0 * i2 + 1.0)) * cos(pi / 16.0 * j * (2.0 * j2 + 1.0));
}
}
for (int i2 = 0; i2 < 8; i2++)
for (int j2 = 0; j2 < 8; j2++)
{
result2[h][w][i2][j2] = 0.0;
for (int i = 0; i < 4; i++)//从这里控制压缩率
for (int j = 0; j < 4; j++)
{
result2[h][w][i2][j2]=1.0* result2[h][w][i2][j2]+1.0* result[h][w][i][j] * alpha(i) * alpha(j) * cos(pi / 16.0 * i * (2.0 * i2 + 1.0)) * cos(pi / 16.0 * j * (2.0 * j2 + 1.0));
}
}
}
for (int h = 0; h < H; h++)
for (int w = 0; w < W; w++)
{
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
{
uchar* data = image.ptr<uchar>(h*8+i);
data[w * 8 + j] = result2[h][w][i][j];
}
}
imshow("【原始图】", srcImage);
imshow("【复制图】", image);
waitKey(0);
return 0;
}
原图:
1/4压缩率结果:
1/64压缩率: