c++ - Why this implementation of Foward DCT of Loffler's version doesn't work? -
i'm trying implement loeffler's version of 1d dct without results... followed chain of operations shown in flow diagram, image becomes white :( i'm doing wrong?
the diagram:
the code:
include
#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 */ (i = 0; < 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 */ (i = 0; < 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 */ (y = 0; y < 8; y++) (x = 0; x < 8; x++) { double z = 0.0; (v = 0; v < 8; v++) (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]; (int x = 0; x < 8; ++x) { (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; }
the result of lena's pic 64 x 64 pixels:
i got! no 1 helps me. idiot call me lazy. i'm not! here code. can someone...
#include <iostream> #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 c1 cos(m_pi/16) #define c3 cos(3*m_pi/16) #define c5 cos(5*m_pi/16) #define c6 cos(6*m_pi/16) #define s6 sin(6*m_pi/16) #define c7 cos(7*m_pi/16) #define r2 sqrt(2.0) */ #define c1 1004 #define c3 851 #define c5 569 #define c6 392 #define s6 946 #define c7 200 #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; int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; int tmp10, tmp11, tmp12, tmp13; int z1, z2, z3, z4, z5; /* transform rows */ (i = 0; < 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); tmp0 = x0 + x7; tmp7 = x0 - x7; tmp1 = x1 + x6; tmp6 = x1 - x6; tmp2 = x2 + x5; tmp5 = x2 - x5; tmp3 = x3 + x4; tmp4 = x3 - x4; tmp10 = tmp0 + tmp3; tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; rows[i][0] = tmp10 + tmp11; rows[i][4] = tmp10 - tmp11; rows[i][2] = (r2 * (tmp12 * c6 + tmp13 * s6)) >> 17; rows[i][6] = (r2 * (tmp13 * c6 - tmp12 * s6)) >> 17; //odd part z1 = tmp4 + tmp7; z2 = tmp5 + tmp6; z3 = tmp4 + tmp6; z4 = tmp5 + tmp7; z5 = (z3 + z4) * r2 * c3; tmp4 = tmp4 * r2 * (-c1 + c3 + c5 - c7); tmp5 = tmp5 * r2 * (c1 + c3 - c5 + c7); tmp6 = tmp6 * r2 * (c1 + c3 + c5 - c7); tmp7 = tmp7 * r2 * (c1 + c3 - c5 - c7); z1 = z1 * r2 * (c7 - c3); z2 = z2 * r2 * (-c1 - c3); z3 = z3 * r2 * (-c3 - c5); z4 = z4 * r2 * (c5 - c3); z3 += z5; z4 += z5; rows[i][7] = (tmp4 + z1 + z3) >> 17; rows[i][5] = (tmp5 + z2 + z4) >> 17; rows[i][3] = (tmp6 + z2 + z3) >> 17; rows[i][1] = (tmp7 + z1 + z4) >> 17; //cout << trunc(rows[i][2]) << endl; } /* transform columns */ (i = 0; < 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]; tmp0 = x0 + x7; tmp7 = x0 - x7; tmp1 = x1 + x6; tmp6 = x1 - x6; tmp2 = x2 + x5; tmp5 = x2 - x5; tmp3 = x3 + x4; tmp4 = x3 - x4; tmp10 = tmp0 + tmp3; tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; dct[0][i] = (tmp10 + tmp11) >> 3; dct[4][i] = (tmp10 - tmp11) >> 3; dct[2][i] = (r2 * (tmp12 * c6 + tmp13 * s6)) >> 20; dct[6][i] = (r2 * (tmp13 * c6 - tmp12 * s6)) >> 20; //cout << dct[0][i] << endl; //odd part z1 = tmp4 + tmp7; z2 = tmp5 + tmp6; z3 = tmp4 + tmp6; z4 = tmp5 + tmp7; z5 = (z3 + z4) * r2 * c3; tmp4 = tmp4 * r2 * (-c1 + c3 + c5 - c7); tmp5 = tmp5 * r2 * (c1 + c3 - c5 + c7); tmp6 = tmp6 * r2 * (c1 + c3 + c5 - c7); tmp7 = tmp7 * r2 * (c1 + c3 - c5 - c7); z1 = z1 * r2 * (c7 - c3); z2 = z2 * r2 * (-c1 - c3); z3 = z3 * r2 * (-c3 - c5); z4 = z4 * r2 * (c5 - c3); z3 += z5; z4 += z5; dct[7][i] = (tmp4 + z1 + z3) >> 20; dct[5][i] = (tmp5 + z2 + z4) >> 20; dct[3][i] = (tmp6 + z2 + z3) >> 20; dct[1][i] = (tmp7 + z1 + z4) >> 20; //cout << dct[0][i] << endl; } } #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 */ (y = 0; y < 8; y++) (x = 0; x < 8; x++) { double z = 0.0; (v = 0; v < 8; v++) (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]; (int x = 0; x < in.cols/8; ++x) { (int y = 0; y < in.rows/8; ++y) { dct2(in, dct, x * 8, y * 8); idct2(in, dct, x * 8, y * 8); } } imshow("original", in); waitkey(0); return 0; }
Comments
Post a Comment