我正在尝试实现 Loeffler 的 1D DCT 版本,但没有任何结果......我按照流程图中显示的操作链进行操作,但图像变为白色 :( 我做错了什么?
示意图:
编码:
包括
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <stdio.h>
#include <opencv/cv.hpp>
#include <pthread.h>
#include "highgui.h"
#include "cv.h"
using namespace std;
using namespace cv;
#define C3 851
#define S3 569
#define C1 1004
#define S1 200
#define C6 392
#define S6 946
#define R2 181
void dct2(Mat in, double dct[8][8], int xpos, int ypos) {
int i;
double rows[8][8];
int x0, x1, x2, x3, x4, x5, x6, x7, x8;
//cout << S3 << " " << S1 << " " << S6 << endl;
/* transform rows */
for (i = 0; i < 8; i++) {
x0 = in.at<uchar>(xpos + 0, ypos + i);
x1 = in.at<uchar>(xpos + 1, ypos + i);
x2 = in.at<uchar>(xpos + 2, ypos + i);
x3 = in.at<uchar>(xpos + 3, ypos + i);
x4 = in.at<uchar>(xpos + 4, ypos + i);
x5 = in.at<uchar>(xpos + 5, ypos + i);
x6 = in.at<uchar>(xpos + 6, ypos + i);
x7 = in.at<uchar>(xpos + 7, ypos + i);
//STAGE 1
int X0 = x0;
x0 += x7;
int X1 = x1;
x1 += x6;
int X2 = x2;
x2 += x5;
int X3 = x3;
x3 += x4;
x4 = X3 - x4;
x5 = X2 - x5;
x6 = X1 - x6;
x7 = X0 - x7;
//STAGE 2
X0 = x0;
X1 = x1;
x0 += x3;
x1 += x2;
x2 = X1 - x2;
x3 = X0 - x3;
int X4 = x4;
x4 = x4 * C3 + x7 * S3;
x7 = x7 * C3 - X4 * S3;
int X5 = x5;
x5 = x5 * C1 + x6 * S1;
x6 = x6 * C1 - X5 * S1;
//STAGE 3
X0 = x0;
x0 += x1;
x1 = X0 - x1;
X2 = x2;
x2 = R2 * (x2 * C6 + x3 * S6);
x3 = R2 * (x3 * C6 - X2 * S6);
X4 = x4;
X5 = x5;
x4 += x6;
x5 = x7 - x5;
x6 = X4 - x6;
x7 += X5;
//STAGE 4
X4 = x4;
rows[i][0] = x0;
rows[i][4] = x1;
rows[i][2] = x2 >> 17;
rows[i][6] = x3 >> 17;
rows[i][7] = (x4 + x7) >> 10;
rows[i][3] = (x5 * R2) >> 17;
rows[i][5] = (x6 * R2) >> 17;
rows[i][2] = (x4 - x7) >> 10;
}
/* transform columns */
for (i = 0; i < 8; i++) {
x0 = rows[0][i];
x1 = rows[1][i];
x2 = rows[2][i];
x3 = rows[3][i];
x4 = rows[4][i];
x5 = rows[5][i];
x6 = rows[6][i];
x7 = rows[7][i];
//STAGE 1
int X0 = x0;
x0 += x7;
int X1 = x1;
x1 += x6;
int X2 = x2;
x2 += x5;
int X3 = x3;
x3 += x4;
x4 = X3 - x4;
x5 = X2 - x5;
x6 = X1 - x6;
x7 = X0 - x7;
//STAGE 2
X0 = x0;
X1 = x1;
x0 += x3;
x1 += x2;
x2 = X1 - x2;
x3 = X0 - x3;
int X4 = x4;
x4 = x4 * C3 + x7 * S3;
x7 = x7 * C3 - X4 * S3;
int X5 = x5;
x5 = x5 * C1 + x6 * S1;
x6 = x6 * C1 - X5 * S1;
//STAGE 3
X0 = x0;
x0 += x1;
x1 = X0 - x1;
X2 = x2;
x2 = R2 * (x2 * C6 + x3 * S6);
x3 = R2 * (x3 * C6 - X2 * S6);
X4 = x4;
X5 = x5;
x4 += x6;
x5 = x7 - x5;
x6 = X4 - x6;
x7 += X5;
//STAGE 4
X4 = x4;
dct[0][i] = x0;
dct[4][i] = x1;
dct[2][i] = x2 >> 17;
dct[6][i] = x3 >> 17;
dct[7][i] = (x4 + x7) >> 10;
dct[3][i] = (x5 * R2) >> 17;
dct[5][i] = (x6 * R2) >> 17;
dct[1][i] = (x4 - x7) >> 10;
}
}
#define COEFFS(Cu,Cv,u,v) { \
if (u == 0) Cu = 1.0 / sqrt(2.0); else Cu = 1.0; \
if (v == 0) Cv = 1.0 / sqrt(2.0); else Cv = 1.0; \
}
void idct2(Mat in, double data[8][8], const int xpos, const int ypos) {
int u, v, x, y;
/* iDCT */
for (y = 0; y < 8; y++)
for (x = 0; x < 8; x++) {
double z = 0.0;
for (v = 0; v < 8; v++)
for (u = 0; u < 8; u++) {
double S, q;
double Cu, Cv;
COEFFS(Cu, Cv, u, v);
S = data[v][u];
q = Cu * Cv * S
* cos(
(double) (2 * x + 1) * (double) u * M_PI
/ 16.0)
* cos(
(double) (2 * y + 1) * (double) v * M_PI
/ 16.0);
z += q;
}
z /= 4.0;
if (z > 255.0)
z = 255.0;
if (z < 0)
z = 0.0;
in.at<uchar>(x + xpos, y + ypos) = (uchar) z;
}
}
int main() {
Mat in = imread("lena.bmp", CV_LOAD_IMAGE_GRAYSCALE);
double DCT[8][8];
for (int x = 0; x < 8; ++x) {
for (int y = 0; y < 8; ++y) {
dct2(in, DCT, x * 8, y * 8);
idct2(in, DCT, x * 8, y * 8);
}
}
imshow("original", in);
waitKey(0);
return 0;
}
Lena 的 pic 64 x 64 像素的结果: