1

I have to implement a DCT algorithm in C++, here is my present code :

// dct: computes the discrete cosinus tranform of a 8x8 block
template<typename Tin=uchar,typename Tout=float>
inline cv::Mat_<Tout> dct(const cv::Mat_<Tin>& oBlock) {

int indexNumber;
float pi = 3.14159265359;
float fcoscos, fxy, cos1, cos2, forCos1, forCos2;

cv::Mat_<Tout> resultBloc(8, 8);

for (int u = 0; u < oBlock.rows; u++){
    for (int v = 0; v < oBlock.cols; v++){

        float cu=0, cv=0, Result=0;

        // calcul c(u)
        if (u == 0){
            cu = (float)sqrt((float)1 / (float)oBlock.rows);
        }
        else {
            cu = (float)sqrt((float)2 / (float)oBlock.rows);
        }

        // calcul c(v)
        if (v == 0){
            cv = (float)sqrt((float)1 / (float)oBlock.cols);
        }
        else {
            cv = (float)sqrt((float)2 / (float)oBlock.cols);
        }

        float sums = 0;

        for (int x = 0; x < oBlock.rows; x++){
            for (int y = 0; y < oBlock.cols; y++){

                indexNumber = x * oBlock.rows + y;
                fxy = (int)oBlock.data[indexNumber];

                forCos1 = (pi*((2 * x) + 1)*u) / (2 * oBlock.rows);
                forCos2 = (pi*((2 * y) + 1)*v) / (2 * oBlock.cols);

                cos1 = cos(forCos1);
                cos2 = cos(forCos2);

                fcoscos = fxy * cos1 * cos2; 

                sums += fcoscos;

            }
        }

        // calcul total
        Result = sums*cu*cv;

        indexNumber = u * oBlock.rows + v;
        resultBloc.data[indexNumber] = Result;

    }
}

return resultBloc;

}

I compared the result with the cv DCT algorithm as follow :

cv::Mat_<float> tempImage(8,8);

for (int i = 0; i < vecImageCut[0].cols*vecImageCut[0].rows; i++){
    tempImage.data[i] = (int)vecImageCut[0].data[i];
}
cv::Mat_<float> dctCV;
cv::dct(tempImage, dctCV);
for (int i = 0; i < blocksAfterDCT[0].cols*blocksAfterDCT[0].rows; i++){
    std::cerr << "Difference DCT for pixel " << i << " : " << dctCV.data[i] - blocksAfterDCT[0].data[i] << std::endl;
}

The results between my DCT and the cv DCT are very different so i assume my DCT algorithm is wrong but i searched for hours and i can't find my mistake, can anyone tell me where i did something wrong ?

  • OpenCV's DCT is calculated using DFT, as described here: http://www.ece.utexas.edu/~bevans/courses/ee381k/lectures/09_DCT – sturkmen Feb 05 '16 at 02:41
  • 1
    which **DCT**? There are more of them **DCT-I,II,III,IV** be sure you are comparing the same stuff. also see [fast DCT](http://stackoverflow.com/a/22779268/2521214). it also uses **FFT** but you can do **2D DCT** by using **1D DCT** on rows ... transpose ... do columns ... transpose ... normalize. 1D DCT is more easily This process is also faster then direct 2D computation and also much more easy to debug. If you need help with **FFT** see [How to compute Discrete Fourier Transform?](http://stackoverflow.com/a/26355569/2521214). – Spektre Feb 05 '16 at 07:47

1 Answers1

0

Your index calculations are wrong. In indexNumber = x * oBlock.rows + y;, since x is counting rows it needs to be multiplied by the number of columns:

indexNumber = x * oBlock.cols + y;

The same for indexNumber = u * oBlock.rows + v;

indexNumber = u * oBlock.cols + v;
1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56