2013-08-29 2 views
2

Java에서 이미지 처리를 위해 하나의 응용 프로그램을 작성했습니다. 버퍼링 된 이미지가있는 이미지를 처리했으며 이제 이진화 된 이미지의 바이트 배열을 얻어야하는 해당 처리 된 이미지에 대해 byte[]을 반환하려고합니다.버퍼링 된 이미지를 동일한 데이터가있는 2D 바이트 배열로 변환

여기 내 코드입니다 :

public static byte[][] binarizeImage(BufferedImage bfImage){ 

     int red; 
     int newPixel; 
     int h ; 
     int w ; 
     int threshold = otsuTreshold(bfImage); 
      // this function returns the threshold value 199 

     BufferedImage binarized = new BufferedImage(bfImage.getWidth(), bfImage.getHeight(), bfImage.getType()); 

     for(int i=0; i<bfImage.getWidth(); i++) { 
     for(int j=0; j<bfImage.getHeight(); j++) { 

      // Get pixels 
      red = new Color(bfImage.getRGB(i, j)).getRed(); 
      int alpha = new Color(bfImage.getRGB(i, j)).getAlpha(); 
      if(red > threshold) { 
       newPixel = 255; 
      } 
      else { 
       newPixel = 0; 
      } 
      newPixel = colorToRGB(alpha, newPixel, newPixel, newPixel); 
      binarized.setRGB(i, j, newPixel); 
     } 

    } 
      Raster raster = binarized.getData(); 

    h = raster.getHeight(); 
    w = raster.getWidth(); 

    byte[][] binarize_image = new byte[w][h]; 

    for(int i=0 ; i<w ; i++) 
    { 
     for(int j=0; j<h ; j++) 
     { 
      binarize_image[i][j]=raster.getSampleModel(); //error at this line 
     } 
    } 
    return binarize_image; 
} 

// Convert R, G, B, Alpha to standard 8 bit 
    private static int colorToRGB(int alpha, int red, int green, int blue) { 

     int newPixel = 0; 
     newPixel += alpha; 
     newPixel = newPixel << 8; 
     newPixel += red; newPixel = newPixel << 8; 
     newPixel += green; newPixel = newPixel << 8; 
     newPixel += blue; 

     return newPixel; 

    } 

그러나 그것은 작동하지 않습니다. 버퍼링 된 이미지를 동일한 이미지 데이터의 바이트 배열로 변환하려면 어떻게해야합니까?

+0

? 8 비트 흑백/8 비트 알파/픽셀? 그렇다면 픽셀 당 8 비트로 어떻게 저장할 것입니까? 이것은 내가 바이너리로 생각하는 것이 아니라 예술적 효과를 창출하는 것일까? 어쨌든 임시 "binarized"이미지없이 빠져 나와 첫 번째 루프의 값을'binarize_image'에 직접 설정하면됩니다. – haraldK

+0

코드를 작성하는 주된 목적은 회색 이미지를 이진화 된 이미지로 변환하고 싶습니다. 그리고 위의 코드로 시도하고 있습니다. – rachana

+0

"이진화 된"이미지 란 무엇입니까? 흑백과 같이 이진을 의미합니까? 입력 이미지가 항상 회색입니까? 8 비트? – haraldK

답변

2

이 컨텍스트에서 "binarize"라는 용어가 무슨 뜻인지 확신 할 수 없습니다. 이미지를 필터링 (예 : 특정 임계 값을 기준으로 빨간색 채널을 잘라내 기) 한 다음 결과를 byte[]으로 변환하기 만하면됩니다.

위의 내용이 올바른 것으로 가정하면 아래 코드를 확인하십시오. 32 비트 이미지의 경우 이미지를 byte[]으로 변환합니다. 다음을 고려하십시오 :

  • 먼저 이미지를 필터링하고 byte[]로 변환 할 필요가 없습니다. 전환하는 동안 그렇게 할 수 있습니다.
  • "표준 8 비트 RGB로 변환"당신이 컬러 채널 당 8 비트 을 의미하는 경우 다음이 괜찮습니다,하지만 당신은 8 비트 을 의미하는 경우 다음 픽셀 당은 압축/변환에 대해 얘기 (즉 당신은 약간의 정보/품질을 잃어 버릴 것입니다)이 경우 당신은 당신이 달성하기를 원하는 것에 대한 더 많은 정보를 제공해야합니다.
  • 결과로 얻은 byte[]의 크기는 4 * width * height이 아니며 width * height이 아닌 32 비트 이미지의 경우를 가정합니다. 다른 케이스를 처리해야하는 경우 BufferedImage (또는 적어도 관심있는 이미지 유형)에서 지원하는 사용 가능한 이미지 유형을 고려해야합니다.

아래의 코드는 아래처럼 각각의 변환 된 픽셀에 대한 정보를 인쇄합니다 (빨강 채널 필터링하는 방법을 참고) :

[0,0] Converting [ffaaccee] --> [0, cc, ee, ff]

package imageio.byteconversion; 

import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.io.InputStream; 
import javax.imageio.ImageIO; 

public class BufferedImageToBytes { 

    private static void log(String s) { 
     System.out.println(s); 
    } 

    private static String toByteString(int color) { 
     // Perform a bitwise AND for convenience while printing. 
     // Otherwise Integer.toHexString() interprets values as integers and a negative byte 0xFF will be printed as "ffffffff" 
     return Integer.toHexString(color & 0xFF); 
    } 

    public static void main(String[] args) throws IOException { 

     // Load the image. This expects the image to be in the same package with this class 
     InputStream stream = BufferedImageToBytes.class.getResourceAsStream("test.png"); 
     BufferedImage image = ImageIO.read(stream); 
     int iw = image.getWidth(); 
     int ih = image.getHeight(); 
     log("Image loaded succesfully, width=" + iw + " height=" + ih); 
     stream.close(); 

     log("Image color model: " + image.getColorModel()); 
     log("Image sample model: " + image.getSampleModel()); 
     log("Image raster: " + image.getRaster()); 

     int bands = image.getSampleModel().getNumBands(); 
     log("Color bands: " + bands); 
     if (bands != 4) { 
      throw new RuntimeException("The image does not have 4 color bands. Are you sure this is a 32-bit image?"); 
     } 

     int threshold = 199; // <-- decide your threshold here 

     byte bytes[] = new byte[4 * iw * ih]; 
     int index = 0; 

     // note that image is processed row by row top to bottom 
     for(int y = 0; y < ih; y++) { 
      for(int x = 0; x < iw; x++) { 

       // returns a packed pixel where each byte is a color channel 
       // order is the default ARGB color model 
       int pixel = image.getRGB(x, y); 

       // Get pixels 
       int alpha = (pixel >> 24) & 0xFF; 
       int red = (pixel >> 16) & 0xFF; 
       int green = (pixel >> 8) & 0xFF; 
       int blue = pixel & 0xFF; 

       // perform filtering here depending on threshold 
       if (red > threshold) { 
        red = 255; 
       } else { 
        red = 0; 
       } 

       log("[" + x + "," + y + "]" + " Converting [" + Integer.toHexString(pixel) + "] --> [" 
         + toByteString(red) + ", " + toByteString(green) + ", " 
         + toByteString(blue) + ", " + toByteString(alpha) 
         + "]"); 

       bytes[index++] = (byte) red; 
       bytes[index++] = (byte) green; 
       bytes[index++] = (byte) blue; 
       bytes[index++] = (byte) alpha; 
      } 
     } 
    } 
} 
+0

답장을 보내 주셔서 감사합니다. 위의 코드가 회색 이미지이므로 이진화하고 싶습니다. – rachana

+0

@rachana _ "binarize"란 무엇을 의미합니까? 'byte []'로 변환 하시겠습니까? 그렇다면 위의 코드가 작동합니다 (더 많은 공간을 절약 할 수는 있지만). 예외를 throw하는 검사를 제거하십시오. 회색 이미지로 변환 하시겠습니까? 어떤 이미지를 소스에 사용하고 원하는 출력이 무엇인지 명확히하십시오. –

+0

이미지의 바이너리 화는 회색 이미지를 흑백 형식으로 변환한다는 것을 의미하며, 그 코드로 수행하려고 시도하는 것입니다. 또한 이진 후에도 변환하려고합니다. 이미지를 처리하는 다른 작업이 바이트 배열을 필요로하므로 바이트 배열로 이진화 된 버퍼링 된 이미지가 필요합니다. – rachana

1

을하는 방법에 대해 :

BufferedImage input; 

BufferedImage binary = new BufferedImage(input.getWidth(), input.getHeight(), BufferedImage.TYPE_BYTE_BINARY); 

Graphics2D g = binary.createGraphics(); 
try { 
    g.drawImage(input, 0, 0, null); 
} 
finally { 
    g.dispose(); 
} 

otsuTreshold을 사용하지 않으며 이미지를 디더링하지만 작업을 수행합니다 (아마). 최소량의 메모리를 사용하여 이진 (흑백 전용)으로 만듭니다.

2

왜 Catalano Framework로 libs를 사용하려고하지 않습니까? 당신`binarize_image`처럼 변환 후 포함하는 것이 무엇 http://code.google.com/p/catalano-framework/

FastBitmap fb = new FastBitmap("c:\\files\\image.jpg"); 
fb.toGrayscale(); 

OtsuThreshold otsu = new OtsuThreshold(); 
otsu.applyInPlace(fb); 

int[][] image = new int[fb.getHeight()][fb.getWidth()]; 
fb.toArrayGray(image); 
1
try { 
        // get the BufferedImage, using the ImageIO class 
        Bitmap image = 
        BitmapFactory.decodeStream(getAssets() 
          .open("aa.bmp")); 
        marchThroughImage(image); 
       } catch (IOException e) { 
        System.err.println(e.getMessage()); 
       } 
     } 
    }); 


} 
public void printPixelARGB(int pixel) { 
    int alpha = (pixel >> 24) & 0xff; 
    int red = (pixel >> 16) & 0xff; 
    int green = (pixel >> 8) & 0xff; 
    int blue = (pixel) & 0xff; 
    System.out.println("argb: " + alpha + ", " + red + ", " + green + ", " + blue); 
    } 
private void marchThroughImage(Bitmap image) { 
    int w = image.getWidth(); 
    int h = image.getHeight(); 
    System.out.println("width, height: " + w + ", " + h); 

    for (int i = 0; i < h; i++) { 
     for (int j = 0; j < w; j++) { 
     System.out.println("x,y: " + j + ", " + i); 
     int pixel = image.getPixel(j, i); 
     printPixelARGB(pixel); 
     System.out.println(""); 
     } 
    } 
    } 
관련 문제