2017-12-24 18 views
0

私は入力としてbufferedImageを取り、すべての黒つぶれ色(R < 32、G < 32、B < 32)を黒にマッピングし、他のものを白にマッピングするプログラムを作成しようとしています(OCRエンジンはBufferedImageを入力として使用します)。ピクセルを反復処理せずにそれを行う方法はありますか? はつまり、私はBlackWhiteColorModelがJava BufferedImageのマップカラー

public class BlackWhiteColorModel extends ColorModel { 

public BlackWhiteColorModel(int bits) { 
    super(bits); 
} 

@Override 
public int getRed(int pixel) { 
    int[] rgb = getRgb(pixel); 

    if (rgb[0] < 32 && rgb[1] < 32 && rgb[2] < 32) { 
     return 0; 
    } else { 
     return 255; 
    } 
} 

@Override 
public int getGreen(int pixel) { 
    int[] rgb = getRgb(pixel); 

    if (rgb[0] < 32 && rgb[1] < 32 && rgb[2] < 32) { 
     return 0; 
    } else { 
     return 255; 
    } 
} 

@Override 
public int getBlue(int pixel) { 
    int[] rgb = getRgb(pixel); 

    if (rgb[0] < 32 && rgb[1] < 32 && rgb[2] < 32) { 
     return 0; 
    } else { 
     return 255; 
    } 
} 

@Override 
public int getAlpha(int pixel) { 
    return pixel; 
} 

private int[] getRgb(int pixel) { 
    int r = (pixel) & 0xFF; 
    int g = (pixel >> 8) & 0xFF; 
    int b = (pixel >> 16) & 0xFF; 
    int a = (pixel >> 24) & 0xFF; 

    return new int[]{r, g, b, a}; 
} 



} 

として定義されて

public static BufferedImage BlackAndWhite(BufferedImage image) { 

    ColorModel model = new BlackWhiteColorModel(DataBuffer.TYPE_INT); 
    WritableRaster raster = image.getRaster(); 

    BufferedImage newImage = new BufferedImage(model, raster, false, null); 

    return newImage; 
} 

を試してみましたが、私はisCompatibleRasterExceptionで終わります。誰かが私に助言をくれますか?

+0

あなたは**ブラック&ホワイトが必要です*です*画像か** GrayScale **のいずれか? – STaefi

答えて

0

(1)契約の方法のいずれかを実装していません:isCompatibleRaster。ここでは細かい問題文を与え走る過度に楽観的な実装です:

@Override 
public boolean isCompatibleRaster(Raster raster) { 
    return true; 
} 

(2)getRedgetGreengetBlueは同じコードを持っています。ここには、共通コードを、getColorという新しいメソッドに分解する完全なプログラムがあります。このプログラムはエラーなしで実行されます:あなたが欲しい

import java.awt.*; 
import java.awt.image.*; 

public class BlackWhiteColorModel extends ColorModel { 
    public static void main(String[] args) { 
     BufferedImage bufferedImage = new BufferedImage(200,200,BufferedImage.TYPE_INT_RGB); 
     Graphics g = bufferedImage.getGraphics(); 
     g.drawString("Hello, World", 20,20); 
     blackAndWhite(bufferedImage); 
    } 

    public static BufferedImage blackAndWhite(BufferedImage image) { 
     ColorModel model = new BlackWhiteColorModel(DataBuffer.TYPE_INT); 
     WritableRaster raster = image.getRaster(); 

     BufferedImage newImage = new BufferedImage(model, raster, false, null); 

     return newImage; 
    } 

    public BlackWhiteColorModel(int bits) { 
     super(bits); 
    } 

    private int getColor(int pixel) { 
     int[] rgb = getRgb(pixel); 

     if (rgb[0] < 32 && rgb[1] < 32 && rgb[2] < 32) { 
      return 0; 
     } else { 
      return 255; 
     } 
    } 

    @Override 
    public int getRed(int pixel) { 
     return getColor(pixel); 
    } 

    @Override 
    public int getGreen(int pixel) { 
     return getColor(pixel); 
    } 

    @Override 
    public int getBlue(int pixel) { 
     return getColor(pixel); 
    } 

    @Override 
    public int getAlpha(int pixel) { 
     return pixel; 
    } 

    @Override 
    public boolean isCompatibleRaster(Raster raster) { 
     return true; 
    } 

    private int[] getRgb(int pixel) { 
     int r = (pixel) & 0xFF; 
     int g = (pixel >> 8) & 0xFF; 
     int b = (pixel >> 16) & 0xFF; 
     int a = (pixel >> 24) & 0xFF; 

     return new int[]{r, g, b, a}; 
    } 
} 
+0

ありがとうございます。 しかし、別のcolorModelで新しいイメージを作成する私の方法は機能しません。 BlackAndWhite(BufferedImageイメージ)の出力を保存する場合、ファイルは作成されず、例外もスローされません。また、テキスト認識は機能しません。 他の(機能的な)方法、異なるColorModelで同じデータを使って新しいイメージを作成する方法について知っていますか? –

+0

あなたは質問を変更する範囲を拡大しています。この回答を受け入れ、拡張された範囲で新しい質問をしてください。 –

0

は、閾値操作例です: enter image description here

私はあなたがパフォーマンス上の問題のためのピクセルを反復処理したくないと思います。それが本当であるならば、私は非常には、ちょうどこのようOpenCVを使用することをお勧めします:あなたはより多くの画像処理を行う場合は特に

BufferedImage image = null; //use your image here 
//Convert image to OpenCv Mat 
byte[] pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData(); 
Mat mat = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC3); 
mat.put(0, 0, pixels); 

//do something with the Mat e.g: 
Imgproc.threshold(...); 

//Convert back 
mat.get(0, 0, pixels); 

パフォーマンスを少なくとも10倍速く

+0

ありがとうございます!私は休日中にそれをチェックするでしょう。 –

関連する問題