Я пытаюсь реализовать версию 1D DCT от Loeffler, но без каких-либо результатов ... Я следил за цепочкой операций, показанной на блок-схеме, но изображение становится белым :(Что я делаю неправильно?Почему эта реализация Foward DCT версии Loffler не работает?
Диаграмма:
код:
включают#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;
}
Результат Лены Pic 64 х 64 пикселей:
Похоже, что он зажимается, что означает, что большинство значений переполнено. Попробуйте на меньшем изображении, возможно, 4x4, которое вы также можете вычислить вручную, чтобы вы могли проверить свою работу. Используйте свой отладчик или задайте более конкретный вопрос. Мы не работаем над вами. – metal