2013-03-05 2 views
2

입력 이미지의 DCT 및 IDCT를 계산하고 결과 이미지로 IDCT 출력을 표시하려고합니다. 그러나 IDCT 값은 300 이상입니다. 입력 이미지는 '.rgb'이미지입니다. 또한 입력 이미지의 높이와 너비를 상수로 생각하고 있습니다. 즉, 352 * 288Jpeg DCT 및 IDCT가 올바르게 계산되지 않았습니다.

저는 각 픽셀의 입력 빨강, 녹색 및 파랑 정수를 rgb [3] [64] [1583]로 나타냅니다. [3] -> 각 블록의 픽셀의 적색/녹색/청색 및 인덱스, 8 * 8 블록의 인덱스, 즉 1583 블록의 블록 중 하나.

그리고 마지막으로 내 양자화 테이블을 균일 한 값 -> 2^N이있는 곳으로 유지합니다. 여기서 N은 매개 변수로 전달됩니다.이 코드에서 quantLevel은 N 이상입니다. 내가 확인 레드에 대한 IDCT의 OUPUT로 출력 이미지를 표시하려고하고 있지 않다

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

가는 255

위 도와주세요 : 다음

내 코드입니다.

답변

1

먼저 JPEG 호환 코덱을 만들고 싶습니까? 아니면 멀티미디어 코딩 개념을 가지고 놀고 있습니까? 후자의 경우, 당신에게 더 많은 권력. 전자의 경우 앞으로 많은 일을해야합니다.

질문에 직접 대답하십시오 : 2D 순방향 DCT를 사용하여 8x8 블록을 변환하고 255를 초과하는 숫자를 얻는 것이 일반적입니다. 순방향 DCT의 저수준 구현은 일반적으로 8x8 부호없는 8 비트 샘플 부호있는 16 비트 샘플의 8x8 벡터를 입력 및 출력합니다.

실제로 JPEG 호환 코덱을 만들기를 원한다면 아직 공부할 몇 가지 주제가 있습니다. 우선, JPEG는 RGB를 압축하지 않습니다. RGB 데이터는 YUV로 변환되고 해당 블록이 변환됩니다 (양자화, 지그재그 및 엔트로피 코딩).

+0

나는 확실히 배우고있다. 당신이 위에서 말했던 것에 완전히 동의하고 또한 엔트로피 인코딩을해야한다는 것도 알고있다. 그러나 지금은 알파 성분을 제거하고 DCT와 IDCT를 적용하여 최종 이미지를 얻으려는 .rgb 이미지를 얻고 있습니다. 그리고 나는 프로그레시브 인코딩을하고 싶다. 이 일은 혼자서하고 있습니다. – Vizzard

+0

굉장합니다. 나는 사람들이 JPEG 해독기를 처음부터 멀티미디어 해킹을 배우는 데 관심이 있다면 자신이 선택한 언어로 쓰도록 조언하는 기사를 썼다. http://multimedia.cx/eggs/learn-multimedia-with-jpeg/; 당신은 압축 이론의 많은 토대에 대해 한 무리를 배울 것입니다. 이를 위해 먼저 디코더를 작성한 다음 엔코더를 작성하는 데 집중할 수 있습니다. 디코더로 시작하면 JPEG 조각을 더 잘 이해할 수 있습니다. –

+0

고마워, 나는 분명히 링크를 따라갈거야. – Vizzard