Java Jpeg DCT和IDCT计算不正确

Java Jpeg DCT和IDCT计算不正确,java,image-processing,jpeg,multimedia,dct,Java,Image Processing,Jpeg,Multimedia,Dct,我试图计算输入图像的DCT和IDCT,并将IDCT输出显示为结果图像。但是我的IDCT值超过了300。我的输入图像是“.rgb”图像。 我还将输入图像的高度和宽度视为常数,即352*288 我将每个像素的输入红色、绿色和蓝色整数表示为rgb[3][64][1583],其中[3]->红色/绿色/蓝色索引和[64]->每个块中的像素索引和[1583]-> 8*8块的索引,即1583块中的一个块 最后,我保留了我的量化表,它有统一的值->2^N,其中N作为参数传递。在这段代码中,quantLevel是

我试图计算输入图像的DCT和IDCT,并将IDCT输出显示为结果图像。但是我的IDCT值超过了300。我的输入图像是“.rgb”图像。 我还将输入图像的高度和宽度视为常数,即352*288

我将每个像素的输入红色、绿色和蓝色整数表示为rgb[3][64][1583],其中[3]->红色/绿色/蓝色索引和[64]->每个块中的像素索引和[1583]-> 8*8块的索引,即1583块中的一个块

最后,我保留了我的量化表,它有统一的值->2^N,其中N作为参数传递。在这段代码中,quantLevel是上面的N

以下是我的代码:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Jpeg {    
   double rgb[][][]=new double[3][64][1584];
   double rgbfinal[][][]=new double[3][64][1584];
   double R[][]=new double[64][1584];
   double G[][]=new double[64][1584];
   double B[][]=new double[64][1584];

   public void go(String fname, int quantLevel){       
     int numBlocks=(352*288)/64;           

    String fileName = fname;
    int width=352,height=288;   
    BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

    try {
            File file = new File(fname);
        InputStream is = new FileInputStream(file);

        long len = file.length();
        byte[] bytes = new byte[(int)len];

        int offset = 0;
            int numRead = 0;
            while (offset < bytes.length && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
                offset += numRead;
        }               
        int ind = 0;
        for(int y = 0; y < height; y++){    
            for(int x = 0; x < width; x++){                     
                byte r = bytes[ind];
                byte g = bytes[ind+height*width];
                byte b = bytes[ind+height*width*2];                 
                int pix = 0xff000000 | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff);             
                img.setRGB(x,y,pix);
                ind++;
            }
        }           
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }

   int indexRow=0,indexCol=0,indexBlock=0,indexBits=0,indexPixelBlock=0,indexPixel=0;
   long  count=0L;
   String binary="";

       indexPixel=0;
       indexBlock=0;   
       int i=0;
           while(count!=(long)(numBlocks*64)){                                                                                                         
               int pix = img.getRGB(indexCol, indexRow);
               int red = (pix >> 16) & 0x000000FF;
               int green = (pix >>8 ) & 0x000000FF;
               int blue = (pix) & 0x000000FF;

               rgb[0][indexPixel][indexBlock]=red;               
               rgb[1][indexPixel][indexBlock]=green;               
               rgb[2][indexPixel][indexBlock]=blue;

              count++;         
              indexPixel++;

              if(indexCol==width-1 && indexRow==height-1)               
                  break;                

              if(indexCol%7==0 && indexCol!=0 && indexPixel%8==0)
                  {                                                 
                      indexPixel=indexPixelBlock;
                      indexBlock++;                                                                                                   
                  }

              if(indexPixel%8==0 && indexCol%7!=0 && indexBlock!=1583)
                  {
                     indexPixel=indexPixelBlock;
                     indexBlock++;
                  }

              if(indexCol==width-1)
                  {                       
                      indexCol=0;                   
                      indexRow++;
                  } 
              else
                  indexCol++;                                                                                                                  

              if((indexPixel)%8==0 && indexBlock==numBlocks-1 && indexCol%7==0)            
                 {                        
                      indexBlock=0;
                      indexPixelBlock=indexPixel;                                              
                 }                                                 
           }
    calcQuantizedDCT(quantLevel);                    
    calcInverseDCT(quantLevel);

    JFrame frame = new JFrame();
    frame.setLocation(0,0);
    frame.setSize(1024, 720);                
    frame.getContentPane().setBackground(Color.WHITE);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);       

    JPanel p=new JPanel();   
    p.setLayout(new FlowLayout(FlowLayout.LEFT));
    p.setLocation(100,100);    

    JLabel label = new JLabel(new ImageIcon(img));    
    label.setLocation(0,0);
    label.setSize(352,288);

    p.add(label);
    frame.add(p);        
    frame.setVisible(true);

    return;
   }

   void calcQuantizedDCT(int quantLevel)
   {      
       String binary="";
       int indexBlock=0,indexPixel=0,indexBits=0,red=0,green=0,blue=0,x=0,y=0,indexPixelTemp=0,u=0,v=0;

       double sumRed=0,sumGreen=0,sumBlue=0;
       String substr="";
        int i=0;
       for(indexBlock=0;indexBlock<1584;indexBlock++)       
       {                               
           indexPixel=0;           
           //
           while(indexPixel!=64 && u<8)
           {                              
               while(indexPixelTemp<64 && x<8)
               {                                                                                               
                   red=(int)rgb[0][indexPixelTemp][indexBlock];
                   green=(int)rgb[1][indexPixelTemp][indexBlock];
                   blue=(int)rgb[2][indexPixelTemp][indexBlock];
                  // System.out.println(red);                           
                   sumRed+=red*Math.cos((Math.PI*(2*y+1)*u)/(2*8))*Math.cos((Math.PI*(2*x+1)*v)/(2*8));                                          
                   sumGreen+=green*Math.cos((Math.PI*(2*x+1)*u)/(2*8))*Math.cos((Math.PI*(2*y+1)*v)/(2*8));                                                                
                   sumBlue+=blue*Math.cos((Math.PI*(2*x+1)*u)/(16))*Math.cos((Math.PI*(2*y+1)*v)/(16));

                   indexPixelTemp++;
                   y++;
                   if(y==8)
                   {
                       x++;
                       y=0;                       
                   }       

               }              
               //System.out.println("SumRed :"+sumRed);

               if(u==0 && v==0)                   
               {                                      
                   //System.out.println("U & V & Pixel & Block "+u+" "+v+" "+indexPixel+" "+indexBlock);
                   R[indexPixel][indexBlock]=(Math.sqrt(1.0/64.0)*sumRed)/Math.pow(2,quantLevel);
                   G[indexPixel][indexBlock]=(Math.sqrt(1.0/64.0)*sumGreen)/Math.pow(2,quantLevel);
                   B[indexPixel][indexBlock]=(Math.sqrt(1.0/64.0)*sumBlue)/Math.pow(2,quantLevel);                   
               }
               else
               {
                   //System.out.println("U & V & Pixel & Block "+u+" "+v+" "+indexPixel+" "+indexBlock);                   
                   R[indexPixel][indexBlock]=(Math.sqrt(2.0/32.0)*sumRed)/Math.pow(2,quantLevel);  
                   G[indexPixel][indexBlock]=(Math.sqrt(2.0/32.0)*sumGreen)/Math.pow(2,quantLevel);  
                   B[indexPixel][indexBlock]=(Math.sqrt(2.0/32.0)*sumBlue)/Math.pow(2,quantLevel);                    
               }                   

               indexPixel++;     

               if(indexPixel==64)
                   break;
               indexPixelTemp=0;
               v++;

               if(v==8)
               {
                   v=0;
                   u++;
               }
               x=0;y=0;sumGreen=0;sumRed=0;sumBlue=0;               
           }                      

           u=0;v=0;                   
       }       

         /*  for(int j=0;j<64;j++)       
           {
               System.out.print(R[j][0]+" ");
               if(j%7==0 && j!=0)
                   System.out.println();
           }   
           */   
   }   

   void calcInverseDCT(int quantLevel)
   {       
       String binary="";
       int indexBlock=0,indexPixel=0,indexBits=0,u=0,v=0,x=0,y=0,indexPixelTemp=0,sumRed=0,sumGreen=0,sumBlue=0,red=0,green=0,blue=0;

       for(indexBlock=0;indexBlock<1584;indexBlock++)
       {            
           for(indexPixel=0;indexPixel<64;indexPixel++)
           {           
               R[indexPixel][indexBlock]=R[indexPixel][indexBlock]*Math.pow(2,quantLevel);
               G[indexPixel][indexBlock]=G[indexPixel][indexBlock]*Math.pow(2,quantLevel);
               B[indexPixel][indexBlock]=B[indexPixel][indexBlock]*Math.pow(2,quantLevel);

           } 
       }
       int i=0;
       indexPixelTemp=0;
       indexPixel=0;
       for(indexBlock=0;indexBlock<1584;indexBlock++)
       {                      
           indexPixel=0;            
           while(indexPixel<64 && x<8)
           {
               indexPixelTemp=0;
               while(indexPixelTemp<64 && u<8)
               { 
                   red=(int)R[indexPixelTemp][indexBlock];                 
                   if(u==0 && v==0)                   
                       sumRed+=Math.sqrt(1.0/2.0)*red*Math.cos((Math.PI*(2*x+1)*u)/(2*8))*Math.cos((Math.PI*(2*y+1)*v)/(2*8));                   
                   else
                       sumRed+=red*Math.cos((Math.PI*(2*x+1)*u)/(2*8))*Math.cos((Math.PI*(2*y+1)*v)/(2*8));                                                              

                   green=(int)G[indexPixelTemp][indexBlock];
                   if(u==0 && v==0)                   
                       sumGreen+=Math.sqrt(1.0/2.0)*green*Math.cos((Math.PI*(2*x+1)*u)/(2*8))*Math.cos((Math.PI*(2*y+1)*v)/(2*8));
                   else
                       sumGreen+=green*Math.cos((Math.PI*(2*x+1)*u)/(2*8))*Math.cos((Math.PI*(2*y+1)*v)/(2*8));

                   blue=(int)B[indexPixelTemp][indexBlock];
                   if(u==0 && v==0)                   
                       sumBlue+=Math.sqrt(1.0/2.0)*blue*Math.cos((Math.PI*(2*x+1)*u)/(2*8))*Math.cos((Math.PI*(2*y+1)*v)/(2*8));
                   else
                       sumBlue+=blue*Math.cos((Math.PI*(2*x+1)*u)/(2*8))*Math.cos((Math.PI*(2*y+1)*v)/(2*8)); 

                   indexPixelTemp++;
                   v++;
                   if(v==8)
                   {
                       u++;
                       v=0;
                   }                                  
               }

               rgbfinal[0][indexPixel][indexBlock]=sumRed;
               rgbfinal[1][indexPixel][indexBlock]=sumGreen;
               rgbfinal[2][indexPixel][indexBlock]=sumBlue;                  

               indexPixel++;                                   
               indexPixelTemp=0;
               y++;

               if(y==8)
               {
                   y=0;
                   x++;
               }               
               u=0;v=0;sumGreen=0;sumRed=0;sumBlue=0;               
           }             
           if(i==3)
               break;
           x=0;y=0;                   
       }

       System.out.println();       
       /*for(i=0;i<64;i++)
       {
           System.out.print(rgbfinal[0][i][0]+" ");
           if(i%7==0 && i!=0)
               System.out.println();
       }*/
   }

   public static void main(String args[]){
        Jpeg a = new Jpeg();
        a.go("src/image2.rgb",0);         
    }    
}
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.FlowLayout;
导入java.awt.image.buffereImage;
导入java.io.File;
导入java.io.FileInputStream;
导入java.io.FileNotFoundException;
导入java.io.IOException;
导入java.io.InputStream;
导入java.util.array;
导入javax.swing.ImageIcon;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JPanel;
公共类Jpeg{
双rgb[][]=新双[3][64][1584];
双精度RGB最终[][]]=新双精度[3][64][1584];
双R[][]=新双[64][1584];
双G[][]=新双[64][1584];
双B[][]=新双[64][1584];
公共void go(字符串fname,int-quantLevel){
int numBlocks=(352*288)/64;
字符串文件名=fname;
内部宽度=352,高度=288;
BuffereImage img=新的BuffereImage(宽度、高度、BuffereImage.TYPE_INT_RGB);
试一试{
文件文件=新文件(fname);
InputStream is=新文件InputStream(文件);
long len=file.length();
字节[]字节=新字节[(int)len];
整数偏移=0;
int numRead=0;
而(偏移量=0){
偏移量+=numRead;
}               
int ind=0;
对于(int y=0;y>8)&0x000000FF;
蓝色整数=(像素点)和0x000000FF;
rgb[0][indexPixel][indexBlock]=红色;
rgb[1][indexPixel][indexBlock]=绿色;
rgb[2][indexPixel][indexBlock]=蓝色;
计数++;
indexPixel++;
if(indexCol==width-1&&indexRow==height-1)
打破
if(indexCol%7==0&&indexCol!=0&&indexPixel%8==0)
{                                                 
indexPixel=indexPixelBlock;
indexBlock++;
}
if(indexPixel%8==0&&indexCol%7!=0&&indexBlock!=1583)
{
indexPixel=indexPixelBlock;
indexBlock++;
}
if(indexCol==宽度-1)
{                       
indexCol=0;
indexRow++;
} 
其他的
indexCol++;
如果((indexPixel)%8==0&&indexBlock==numBlocks-1&&indexCol%7==0)
{                        
indexBlock=0;
indexPixelBlock=indexPixel;
}                                                 
}
calcQuantizedDCT(量子级);
煅烧过的CT(quantLevel);
JFrame=新JFrame();
帧设置位置(0,0);
帧设置大小(1024720);
frame.getContentPane().setBackground(颜色:白色);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel p=新的JPanel();
p、 setLayout(新的FlowLayout(FlowLayout.LEFT));
p、 设定位置(100100);
JLabel标签=新JLabel(新图像图标(img));
标签设置位置(0,0);
标签。设置尺寸(352288);
p、 添加(标签);
框架。添加(p);
frame.setVisible(true);
返回;
}
无效calcQuantizedDCT(整数级)
{      
字符串binary=“”;
int indexBlock=0,indexPixel=0,indexBits=0,红色=0,绿色=0,蓝色=0,x=0,y=0,indexPixelTemp=0,u=0,v=0;
双sumRed=0,sumGreen=0,sumBlue=0;
字符串substr=“”;
int i=0;

对于(indexBlock=0;indexBlock首先,你是希望创建一个与JPEG兼容的编解码器?还是你只是在玩弄多媒体编码概念?如果是后者,那么你的能力会更强。如果是前者,你还有很多工作要做

直接回答您的问题:使用2D正向DCT变换8x8块并获得255以上的数字是正常的。正向DCT的低级实现通常将8x8无符号8位样本向量作为输入,并输出8x8有符号16位样本向量


如果您确实希望创建一个与JPEG兼容的编解码器,那么您仍然需要学习一些主题。对于初学者来说,JPEG不压缩RGB。RGB数据被转换为YUV,这些块被转换(然后量化、锯齿形和熵编码).

我肯定在学习。我完全同意你上面所说的,我也知道我们也需要进行熵编码。但现在我正在拍摄一张.rgb图像,以消除α分量和α分量