【问题标题】:Issue related to implementing Inverse DCT on Images与在图像上实施逆 DCT 相关的问题
【发布时间】:2014-03-15 10:34:20
【问题描述】:

我正在尝试在图像上实现 DCT,以作为理解整个 JPEG 压缩管道(Java 中)的一部分。我可以成功实现正向 DCT。但是,我在逆 DCT 中遇到问题。任何帮助将不胜感激。

public BufferedImage Inverse_DCT (BufferedImage img)
{
    int width = img.getWidth();
    int height = img.getHeight();
    BufferedImage OutputImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);

    // ------------------- IDCT Implementation ------------------------------
    double [][]Cos_Basis = new double [8][8]; // 8X8 Cosine Basis Implementation
    double [] CoEff = new double [8];
    // ------------------ Pre Compute The Kernel ---------------------------
    for (int i=0;i<8;i++)
    {   
        for (int j=0;j<8;j++)
        {
            Cos_Basis[i][j] =  Math.cos((2*i+1)*j*3.14159f/16.0f); // COSINE KERNEL
        }
        if (i==0)
            CoEff[i]=1/(Math.sqrt(2));
        else
            CoEff[i]=1;             
    }
    // -------------------- IDCT Code --------------------------------------
    for (int row=0;row<(height/8);row++)
    {
        for (int col=0;col<(width/8);col++)
        {
            for (int i=0;i<8;i++) // Block Row
            {
                for (int j=0;j<8;j++) // Block Col
                {
                   double sumR = 0;double sumG = 0;double sumB = 0;
                   for (int x=0;x<8;x++)
                   {
                       for (int y=0;y<8;y++)
                       {
                           sumR += (CoEff[x])*(CoEff[y])*((((img.getRGB((col*8+y),(row*8+x))>>16) & 0xFF))*(Cos_Basis[i][x])*(Cos_Basis[j][y]));
                           sumG += (CoEff[x])*(CoEff[y])*((((img.getRGB((col*8+y),(row*8+x))>>8) & 0xFF))*(Cos_Basis[i][x])*(Cos_Basis[j][y]));
                           sumB += (CoEff[x])*(CoEff[y])*((((img.getRGB((col*8+y),(row*8+x))>>0) & 0xFF))*(Cos_Basis[i][x])*(Cos_Basis[j][y]));
                       }
                   }

                   sumR *= 0.25f; sumR += 128;
                   sumG *= 0.25f; sumG += 128;
                   sumB *= 0.25f; sumB += 128;
                   if (sumR<0) sumR=0; if (sumG<0) sumG=0;if (sumB<0) sumB=0;
                   if (sumR>255) sumR=255; if (sumG>255) sumG=255;if (sumB>255) sumB=255;
                   //System.out.println("SumR : "+sumR+"  SumG:"+sumG+" SumB:"+sumB);
                   // Assign Output Image
                   int pix = 0x00000000 | (((int)(sumR) & 0xff) << 16) | (((int)(sumG) & 0xff) << 8) | ((int)(sumB) & 0xff);
                   //System.out.println("PIXEL : "+pix);
                   OutputImage.setRGB((col*8+j),(row*8+i),pix);
                }
            }
        }
    }
    return OutputImage;

}

我可以确认我的正向 DCT 是正确的(使用论文中的 8x8 示例并获得匹配值)。但是,IDCT 给我带来了问题。我认为我已经正确地实现了公式,但似乎无法指出我出错的地方。你能帮忙吗?

【问题讨论】:

    标签: java image-processing dct


    【解决方案1】:

    问题在我发布数小时后由我解决,我通过以下方式解决了这个问题;现在可以正常使用了。

    public BufferedImage Inverse_DCT (BufferedImage img){
    int width = img.getWidth();
    int height = img.getHeight();
    BufferedImage OutputImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
    
    // ------------------- IDCT Implementation ------------------------------
    double [][]Cos_Basis = new double [8][8]; // 8X8 Cosine Basis Implementation
    //double [] CoEff = new double [8];
    double Cu,Cv;
    // ------------------ Pre Compute The Kernel ---------------------------
    for (int i=0;i<8;i++)
    {   
        for (int j=0;j<8;j++)
        {
            Cos_Basis[i][j] =  Math.cos((2*i+1)*j*3.14159f/16.0f); // COSINE KERNEL
        }
        //if (i==0)
        //    CoEff[i]=1/(Math.sqrt(2));
        //else
        //    CoEff[i]=1;             
    }
    // -------------------- IDCT Code --------------------------------------
    for (int row=0;row<(height);row+=8)
    {
        for (int col=0;col<(width);col+=8)
        {
            for (int i=0;i<8;i++) // Block Row
            {
                for (int j=0;j<8;j++) // Block Col
                {
                   double sumR = 0;double sumG = 0;double sumB = 0;
                   for (int x=0;x<8;x++)
                   {
                       for (int y=0;y<8;y++)
                       {  
                           if (x==0) {Cu = (1/(Math.sqrt(2)));}
                           else { Cu = 1;}
    
                           if (y==0) {Cv = (1/(Math.sqrt(2)));}
                           else { Cv = 1;} 
    
                           sumR += (Cu)*(Cv)*((((img.getRGB((col+y),(row+x))>>16) & 0xFF))*(Cos_Basis[i][x])*(Cos_Basis[j][y]));
                           sumG += (Cu)*(Cv)*((((img.getRGB((col+y),(row+x))>>8) & 0xFF))*(Cos_Basis[i][x])*(Cos_Basis[j][y]));
                           sumB += (Cu)*(Cv)*((((img.getRGB((col+y),(row+x))>>0) & 0xFF))*(Cos_Basis[i][x])*(Cos_Basis[j][y]));
                       }
                   }
    
                   sumR *= 0.25f; 
                   sumG *= 0.25f; 
                   sumB *= 0.25f; 
                   if (sumR<0) sumR=0; if (sumG<0) sumG=0;if (sumB<0) sumB=0;
                   if (sumR>255) sumR=255; if (sumG>255) sumG=255;if (sumB>255) sumB=255;
                   //System.out.println("SumR : "+sumR+"  SumG:"+sumG+" SumB:"+sumB);
                   // Assign Output Image
                   int pix = 0xff000000 | (((int)(sumR) & 0xff) << 16) | (((int)(sumG) & 0xff) << 8) | ((int)(sumB) & 0xff);
                   //System.out.println("PIXEL : "+pix);
                   OutputImage.setRGB((col+j),(row+i),pix);
                }
            }
        }
    }
    return OutputImage;
    }
    

    【讨论】:

      猜你喜欢
      • 2021-05-29
      • 2014-06-05
      • 2021-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多