2016-02-04 91 views
1

我要实现在C + + DCT算法,这是我本次代码:问题,以DCT实施

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

} 

我比较了CV DCT算法如下结果:

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; 
} 

DCT和cv DCT之间的结果非常不同,所以我认为我的DCT算法是错误的,但我搜索了几个小时,找不到我的错误,谁能告诉我我在哪里做错了什么?

+0

的OpenCV的DCT使用DFT计算,如下所述: HTTP: //www.ece.utexas.edu/~bevans/courses/ee381k/lectures/09_DCT – sturkmen

+1

其中** DCT **?其中有更多** DCT-I,II,III,IV **请确保你比较相同的东西。另请参阅[快速DCT](http://stackoverflow.com/a/22779268/2521214)。它也使用** FFT **,但您可以通过在行上使用** 1D DCT **来执行** 2D DCT **转置...执行列...转置...正常化。 1D DCT更容易这个过程也比直接2D计算更快,而且更容易调试。如果您需要** FFT **帮助,请参见[如何计算离散傅立叶变换?](http://stackoverflow.com/a/26355569/2521214)。 – Spektre

回答

0

您的指数计算错误。在indexNumber = x * oBlock.rows + y;,因为x计数行,它需要被列数乘以:

indexNumber = x * oBlock.cols + y; 

同为indexNumber = u * oBlock.rows + v;

indexNumber = u * oBlock.cols + v; 
+0

实际上,因为它们都等于8,所以不会影响结果 –