2013-05-02 5 views
-2

Я пытаюсь реализовать версию 1D DCT от Loeffler, но без каких-либо результатов ... Я следил за цепочкой операций, показанной на блок-схеме, но изображение становится белым :(Что я делаю неправильно?Почему эта реализация Foward DCT версии Loffler не работает?

Диаграмма:

1D DCT 8 BY LOEFFLER

код:

включают
#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 пикселей:

+1

Похоже, что он зажимается, что означает, что большинство значений переполнено. Попробуйте на меньшем изображении, возможно, 4x4, которое вы также можете вычислить вручную, чтобы вы могли проверить свою работу. Используйте свой отладчик или задайте более конкретный вопрос. Мы не работаем над вами. – metal

ответ

0

я получил! Мне никто не помогает. Просто идиот, который называет меня ленивым. Но не я! Вот код. Может помочь кому-то ...

#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 */ 
    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); 

     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 */ 
    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]; 

     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 */ 
    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 < in.cols/8; ++x) { 
     for (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; 
} 
+2

Видите, немного смажьте локоть, и у вас это получилось. так в чем была проблема? – metal

+1

Проблема заключалась в том, что мне нужно сдвинуть вправо конечный результат на 3 (/ 8) :) –