目次|前|次 |
Java 2D APIでは、3種類のイメージング・モデルがサポートされています。
次の表は、3種類のイメージング・モデルの機能を比較したものです。
この章では、直接方式イメージング・モデルのオブジェクトと技法について説明します。Java 2D APIの直接方式イメージング用のクラスとインタフェースでは、メモリーにデータが格納されているピクセルにマッピングされたイメージを扱うための方法が提供されています。このAPIは、さまざまな格納形式のイメージ・データへのアクセスと、何種類かのフィルタ・リング操作を使ったイメージ・データの処理をサポートしています。
Java 2D APIの直接方式イメージングAPIは、インタフェース、イメージ・データ・クラス、イメージ操作クラス、サンプル・モデル・クラス、カラー・モデル・クラスおよび例外の6つのカテゴリに分類できます。
クラス
|
説明
|
---|---|
ImagingOpException |
スーパー・クラス:
RuntimeException BufferedImageOpまたはRasterOpのフィルタ・メソッドがイメージを処理できない場合にスローされます。
|
RasterFormatException |
スーパー・クラス:
RuntimeException Rasterに無効なレイアウト情報がある場合にスローされます。
|
直接方式イメージング・モデルは、メモリーに格納されている固定解像度のイメージに対応しています。また、イメージ・データに対するフィルタ・リング操作もサポートしています。このモデルでは、多くのクラスとインタフェースが使われています。
図5-1に示すように、BufferedImage
はイメージの全体的な管理機能を提供します。BufferedImage
はメモリー内に直接作成でき、それを使って、ファイルまたはURLから取得したイメージ・データを保持および操作できます。BufferedImage
は、任意のGraphics2D
オブジェクトを使って画面装置に表示したり、適切なGraphics2D
コンテキストを使ってほかの出力先にレンダリングしたりできます。BufferedImage
オブジェクトには、ほかの2つのオブジェクト(Raster
オブジェクトとColorModel
オブジェクト)が含まれています。
Raster
クラスは、イメージ・データの管理機能を提供します。これは、イメージの矩形座標を表し、メモリーにイメージ・データを保持し、単一のイメージ・データ・バッファから複数のサブイメージを作成するメカニズムを提供します。また、イメージ内の特定のピクセルにアクセスするためのメソッドも提供しています。Rasterオブジェクトには、2つのオブジェクト(DataBuffer
オブジェクトとSampleModel
オブジェクト)が含まれています。
DataBuffer
クラスは、メモリー内にピクセル・データを保持します。
SampleModel
クラスは、バッファのデータを解釈し、それを個別のピクセルまたはピクセルの矩形範囲として提供します。
ColorModel
クラスは、イメージのサンプル・モデルで提供されるピクセル・データの色を解釈する機能を提供します。
imageパッケージでは、ほかに、BufferedImage
オブジェクトとRaster
オブジェクトに対するフィルタ・リング操作を定義するクラスが提供されています。イメージ処理のそれぞれの操作は、BufferedImageOp
インタフェースとRasterOp
インタフェースのどちらかまたはその両方を実装するクラスで具体化されています。操作クラスでは、実際のイメージ操作を行うfilter
メソッド群が定義されています。
図5-2は、Java 2D APIのイメージ処理の基本的なモデルを示しています。
イメージ操作では、次の機能がサポートされています。
イメージの表示と操作だけが必要な場合は、BufferedImage
クラスとフィルタ・リング操作クラスを理解するだけで十分です。一方、フィルタを記述したりイメージ・データに直接アクセスしたりする場合は、BufferedImage
クラスと関連のあるクラスを理解する必要があります。
次の用語は、このあとの説明で使われているものです。
データ要素: イメージ・データを記憶する単位として使われているプリミティブ型です。DataBuffer
配列の個々のメンバーです。データ・バッファ内の要素のレイアウトは、イメージのSampleModel
によって行われるピクセルとしてのデータの解釈には依存しません。
サンプル: イメージのピクセルを構成する個別のメンバーです。SampleModel
は、DataBuffer
の要素をピクセルとそのサンプルに変換するメカニズムを提供します。ピクセルのサンプルは、特定のカラー・モデルの基本的な値を表す場合があります。たとえば、RGBカラー・モデルのピクセルは、赤、緑、青という3つのサンプルで構成されています。
成分: 色の解釈に依存しないピクセルの値です。成分とサンプルの違いは、IndexColorModel
で役に立ちます。IndexColorModelの場合、ピクセルの成分はLookupTable
のインデックスになります。
バンド: イメージに含まれる同じ種類の全サンプルの集合です。たとえば、赤の全サンプルや緑の全サンプルなどです。ピクセル・データは様々な方法で格納できますが、Java 2D APIでは、バンド化方式とピクセル・インタリーブ化方式の2種類がサポートされています。バンド化記憶方式の場合、イメージ・データはバンドの単位で編成されて、ピクセルは各バンドの同じ位置にあるサンプル・データで構成されます。ピクセル・インタリーブ化記憶方式の場合は、イメージ・データはピクセル単位で編成されます。すべてのピクセルが1つの配列に含まれていて、バンドは各ピクセルの同じインデックス位置にあるサンプルのセットで構成されます。
原色: 特定のカラー・モデルにおけるカラー値の個別のメンバーです。たとえば、RGBモデルでは、原色の赤と緑と青からカラー値を生成します。
BufferedImage
クラスは、直接イメージング・モードのサポートで中心となるクラスです。メモリー内のイメージを管理し、ピクセル・データを格納および解釈したり、Graphics
コンテキストまたはGraphics2D
コンテキストにピクセル・データをレンダリングしたりする手段を提供しています。
BufferedImage
を作成するには、Component.createImage
メソッドを呼び出します。このメソッドからはBufferedImage
が返され、その描画特性は、オブジェクトの作成に使われたコンポーネントの描画特性に対応しています。作成されるイメージは不透明で、Component
のフォアグラウンドとバックグラウンドの色を持ち、イメージの透明度を調節することはできません。この方法を使用すると、コンポーネントのアニメーションでダブル・バッファリングの描画を行うことができます。詳細については、「オフスクリーン・バッファでの描画」を参照してください。
public Graphics2D createDemoGraphics2D(Graphics g) { Graphics2D g2 = null; int width = getSize().width; int height = getSize().height; if (offImg == null || offImg.getWidth() != width || offImg.getHeight() != height) { offImg = (BufferedImage) createImage(width, height); } if (offImg != null) { g2 = offImg.createGraphics(); g2.setBackground(getBackground()); } // .. clear canvas .. g2.clearRect(0, 0, width, height); return g2; }
いくつか提供されているコンストラクタ・メソッドを使って、空のBufferedImage
をメモリー内に作成することもできます。
BufferedImage
クラスを使うと、グラフィック要素をオフスクリーンの状態で用意し、それを画面にコピーできます。この方法は、グラフィックが複雑な場合、または1つのグラフィックを繰返し使う場合に、特に有効です。たとえば、複雑な図形を何度も表示する必要がある場合は、オフスクリーン・バッファにその図形を一度描画してから、ウィンドウの別の場所にそれをコピーします。一度描画した図形をコピーすることで、グラフィックの表示を高速化できます。
java.awt
パッケージでは、ウィンドウに描画する場合と同じ方法でImage
オブジェクトに描画できるので、簡単にオフスクリーン・バッファを使うことができます。オフスクリーン・イメージにレンダリングするときも、Java 2D APIのすべてのレンダリング機能を使用できます。
オフスクリーン・バッファは、アニメーションでよく使われます。たとえば、オフスクリーン・バッファを使用してオブジェクトを1回描画し、ウィンドウの中でそれを動き回らせるような使い方ができます。同様に、ユーザーがマウスを使用してグラフィックを移動させるときのフィードバックにも、オフスクリーン・バッファを利用できます。すべてのマウス位置でグラフィックを再描画するのではなく、1度オフスクリーン・バッファに描画したグラフィックを、ユーザーがマウスをドラッグするのに合わせて、マウスの位置にコピーします。1
図5-3は、オフスクリーン・イメージに描画してからそのイメージをウィンドウに何回もコピーしているプログラムの例です。最後にイメージをコピーするときは、イメージを変換しています。変換を指定してイメージを再描画する代わりに描画されているイメージを変換すると、不十分な結果になる場合があることに注意してください。
オフスクリーン・バッファとして使用できるイメージを作る場合は、Component
.createImage
メソッドを使うのがもっとも簡単な方法です。
色空間、色深度、およびピクセル・レイアウトが描画先のウィンドウと正確に一致するイメージを作ることで、イメージをグラフィックス装置に効率よくブリットできます。これにより、drawImage
はジョブをすばやく実行できます。
BufferedImage
オブジェクトを直接作成し、オフスクリーン・バッファとして使うこともできます。この方法は、オフスクリーン・イメージの型または透明度を制御する必要がある場合に便利です。
BufferedImage
でサポートされている定義済みのイメージ型を次に示します。
TYPE_3BYTE_BGR
TYPE_4BYTE_ABGR
TYPE_4BYTE_ABGR_PRE
TYPE_BYTE_BINARY
TYPE_BYTE_GRAY
TYPE_BYTE_INDEXED
TYPE_CUSTOM
TYPE_INT_ARGB_PRE
TYPE_INT_ARGB
TYPE_INT_BGR
TYPE_INT_RGB
TYPE_USHORT_555_RGB
TYPE_USHORT_565_RGB
TYPE_INT_GRAY
BufferedImage
オブジェクトは、アルファ・チャネルを含むことができます。図5-3では、アルファ・チャネルを使って、描画される領域と描画されない領域を区別し、すでに描画されているグラフィック(この場合はシェーディングされた矩形)の上に不規則な図形を表示できます。また、アルファ・チャネルを使うと、既存のイメージの色と新しいイメージの色を混合することもできます。
注: 透明度の指定のためにアルファ・イメージ・データが必要な場合以外は(つまり図5-2に示す不規則な形状のイメージを描画するような場合は)、アルファ情報を持つオフスクリーン・バッファの作成を避ける必要があります。必要がない場合にアルファ値を使うと、レンダリングのパフォーマンスが低下します。
GraphicsConfiguration
では、使っている構成と互換性のある形式で、バッファリングされたイメージを自動的に作成する便利なメソッドが提供されています。また、ウィンドウが存在するグラフィックス装置に関連付けられたグラフィックス構成を問い合わせて、互換性のあるBufferedImage
オブジェクトの作成に必要な情報を取得することもできます。
バッファのイメージに描画するには、そのBufferedImage.createGraphics
メソッドを呼び出します。このメソッドからは、Graphics2D
オブジェクトが返されます。このオブジェクトを使用すると、すべてのGraphics2D
メソッドを呼び出して、グラフィックス・プリミティブをレンダリングしたり、テキストを配置したり、イメージに他のイメージをレンダリングしたりできます。この描画技法は、2Dイメージング・パッケージで提供されているディザリングなどの拡張機能をサポートしています。次のコードは、オフスクリーン・バッファリングの使用方法を示したものです。
public void update(Graphics g){
Graphics2D g2 = (Graphics2D)g;
if(firstTime){
Dimension dim = getSize();
int w = dim.width;
int h = dim.height;
area = new Rectangle(dim);
bi = (BufferedImage)createImage(w, h); big = bi.createGraphics(); rect.setLocation(w/2-50, h/2-25); big.setStroke(new BasicStroke(8.0f)); firstTime = false; } // Clears the rectangle that was previously drawn. big.setColor(Color.white); big.clearRect(0, 0, area.width, area.height); // Draws and fills the newly positioned rectangle to the buffer. big.setPaint(strokePolka); big.draw(rect); big.setPaint(fillPolka); big.fill(rect); // Draws the buffered image to the screen. g2.drawImage(bi, 0, 0, this);
}
BufferedImage
に直接描画する以外に、2種類の方法で、イメージのピクセル・データに直接アクセスして操作できます。「イメージの処理と拡張」で説明されているように、この技法は、BufferedImageOp
のフィルタリング・インタフェースを実装する場合に役に立ちます。
BufferedImage
.setRGB
メソッドを使用すると、ピクセルまたはピクセル配列の値を特定のRGB値に直接設定できます。ただし、ピクセルを直接変更すると、ディザリングは行われません。また、BufferedImage
に関連するWritableRaster
オブジェクトを操作することによってピクセル・データを操作することもできます。詳細については、「Rasterの管理と操作」を参照してください。
BufferedImageOp
インタフェースを実装するオブジェクトを使って、BufferedImage
にフィルタ・リング操作を適用できます。フィルタリングおよびこのフィルタリング・インタフェースを提供するクラスについては、「イメージの処理と拡張」を参照してください。
バッファリングされたイメージを特定のコンテキストにレンダリングするには、コンテキストのGraphics
オブジェクトで提供されているdrawImage
メソッドのどれかを呼び出します。たとえば、Component
.paint
メソッドの中でレンダリングするときは、メソッドに渡されたグラフィックス・オブジェクトのdrawImage
メソッドを呼び出します。
public void paint(Graphics g) { if (getSize().width <= 0 || getSize().height <= 0) return; Graphics2D g2 = (Graphics2D) g; if (offImg != null && isShowing()) { g2.drawImage(offImg, 0, 0, this); } }
BufferedImage
オブジェクトは、Raster
を使ってピクセル・データの矩形配列を管理します。Raster
クラスでは、イメージの座標系のためのフィールドとして、幅、高さ、および原点が定義されています。Raster
オブジェクト自体は、DataBuffer
とSampleModel
という2つのオブジェクトを使って、ピクセル・データを管理します。DataBuffer
はラスターのピクセル・データを格納するオブジェクトで(を参照)、SampleModel
はDataBuffer
からのピクセル・データの解釈を提供します(を参照)。
ほとんどの場合、Raster
を直接作成する必要はありません。メモリーにBufferedImage
を作成すると、Rasterが必ず提供されます。ただし、BufferedImage
のコンストラクタ・メソッドの1つでは、WritableRaster
を渡してRaster
を作成できます。
Raster
クラスでは、DataBuffers
とSampleModels
を指定してRasters
を作成するためのstaticファクトリ・メソッドがいくつか提供されています。RasterOp
フィルタリング・クラスを実装するときは、これらのファクトリを使うことができます。
Raster
クラスには、親ラスターと子ラスターのコンセプトが組み込まれています。これにより、同じ親からいくつでもバッファリングされたイメージを作成できるので、ストレージの効率を向上させることができます。親とその子はすべて同じデータ・バッファを参照し、それぞれの子は、バッファ内で自分のイメージの位置を識別するために固有のオフセットと境界を持っています。子は、getParent
メソッドを使って所有権を識別します。
サブラスタを作成するには、Raster
.createSubRaster
メソッドを使います。サブラスタを作成する際には、サブラスタがカバーする親の領域と親の原点からのオフセットを指定します。
Raster
クラスでは、ピクセルとピクセル・データにアクセスするための様々な方法が定義されています。これらの方法は、RasterOp
インタフェースを実装するときまたは低レベルのピクセル操作を行う必要のあるメソッドを実装するときに、役に立ちます。RasterOpインタフェースは、イメージ・データに対するラスター・レベルのフィルタリングおよび操作を提供します。
Raster.getPixel
メソッドを使用すると、ピクセルを個別に取得できます。ピクセルは、配列の中の個別のサンプルとして返されます。Raster
.getDataElements
メソッドからは、指定した一連の解釈されていないイメージ・データがDataBuffer
から取り出されて返されます。Raster
.getSample
メソッドからは、個別のピクセルのサンプルが返されます。getSamples
メソッドからは、イメージの特定の範囲に対するバンドが返されます。
これらのメソッドのほかに、Raster
クラスのインスタンス変数を使用してデータ・バッファおよびサンプル・モデルにアクセスすることもできます。これらのオブジェクトでは、Raster
のピクセル・データにアクセスして解釈するための別の手段が提供されています。
WritableRaster
サブクラスでは、ピクセル・データとサンプルを設定するメソッドが提供されます。BufferedImage
に関連するRaster
は実際にはWritableRaster
であるため、ピクセル・データの操作に必要なすべてのアクセスが提供されます。
Raster
に属しているDataBuffer
は、イメージ・データの配列を表します。直接またはBufferedImage
のコンストラクタを使ってRaster
を作るときは、ピクセルで幅と高さを指定するとともに、イメージ・データのSampleModel
を指定します。この情報を使って、適切なデータ型とサイズのDataBuffer
が作成されます。
DataBuffer
には3つのサブクラスがあり、それぞれが異なる種類のデータ要素を表しています。
DataBufferByte
(8ビット値を表す)DataBufferInt
(32ビット値を表す)DataBufferShort
(16ビット値を表す)DataBufferUShort
(符号なしshort値を表す)前で定義したように、要素はデータ・バッファの配列の連続していないメンバーで、成分またはサンプルは、まとめられてピクセルを形成する不連続の値です。DataBuffer
に格納されている特定の種類の要素と、SampleModel
で表される特定の種類のピクセルの間には、さまざまなマッピングが考えられます。このようなマッピングを実装し、特定のDataBuffer
から特定のピクセルを取得する手段を提供することは、SampleModel
のさまざまなサブクラスの役割です。
DataBuffer
のコンストラクタは、特定のサイズで特定の数のバンクを持つバッファを作成するための手段を提供します。
DataBuffer
のイメージ・データには直接アクセスできますが、一般に、Raster
クラスとWritableRaster
クラスのメソッドを使ってアクセスする方が簡単で便利です。
抽象クラスのSampleModel
では、基になっているデータの格納方法を知らなくてもイメージのサンプルを抽出できるメソッドが定義されています。このクラスは、関連するDataBuffer
のイメージ・データの高さと幅を追跡するためのフィールドと、そのバッファのバンド数とデータ型を記述するためのフィールドを提供しています。SampleModel
のメソッド群はピクセルの集合としてイメージ・データを提供し、各ピクセルは多くのサンプルまたは成分で構成されています。
java.awt.image
パッケージでは、5種類のサンプル・モデルが提供されています。
ComponentSampleModel
- DataBuffer
の1つのバンクの独立したデータ配列要素群にサンプル・データが格納されているイメージからピクセルを抽出する。BandedSampleModel
- 個別のデータ要素に各サンプルが格納されているイメージからピクセルを抽出する。バンドは、連続したデータ要素に格納されている。PixelInterleavedSampleModel
- 個別のデータ要素に各サンプルが格納されているイメージからピクセルを抽出する。ピクセルは、連続したデータ要素に格納されている。MultiPixelPackedSampleModel
- 1つのデータ要素に1つのサンプルの複数のピクセルが格納されている単一バンド化されたイメージからピクセルを抽出する。SinglePixelPackedSampleModel
- DataBuffer
の最初のバンクにある1つのデータ配列要素に単一ピクセルのサンプル・データが格納されているイメージからサンプルを抽出する。データ・ソースの種類により、SampleModel
で表されるピクセル・データと特定のカラー・モデルのカラー・データ表現との間には、直接的な関連がある場合とない場合があります。たとえば、写真イメージ・データの場合、サンプルはRGBデータを表す場合があります。医療用画像装置のイメージ・データの場合は、温度や骨密度など、異なる種類のデータをサンプルが表している可能性があります。
イメージ・データにアクセスするためのメソッドには、3つの種類があります。getPixel
系メソッドは、サンプルごとに1つのエントリがある配列としてピクセル全体を返します。getDataElement
メソッドを使うと、DataBuffer
に格納されている解釈されていない未処理のデータにアクセスできます。getSample
メソッドは、特定のバンドのピクセル成分に対するアクセスを提供します。
Raster
オブジェクトはイメージ・データを管理するためのものですが、BufferedImage
クラスには、これ以外に、カラー・ピクセル値としてデータを解釈するColorModel
が含まれています。抽象クラスのColorModel
では、イメージのピクセル・データを対応するColorSpace
のカラー値に変換するメソッドが定義されています。
java.awt.image
パッケージでは、4種類のカラー・モデルが提供されています。
PackedColorModel
- 整数型ピクセルのビットに色成分が直接埋め込まれているピクセル値を表す抽象ColorModel
クラス。DirectColorModel
は、PackedColorModel
のサブクラスです。DirectColorModel
- ピクセル自体のビットにRGBの色成分が直接埋め込まれているピクセル値を表すColorModel
。DirectColorModel
モデルの表示はX11のTrueColorと類似しています。ComponentColorModel
- 任意のColorSpace
と色成分の配列を処理し、そのColorSpace
に適合させることのできるColorModel
。IndexColorModel
- sRGBの色空間にある固定カラー・マップへのインデックスであるピクセル値を表すColorModel
。DataBuffer
のデータに基づいて、SampleModel
はColorModel
にピクセルを提供し、ColorModel
はそのピクセルを色として解釈します。
ルックアップ表には、1つ以上のチャネルまたはイメージ成分のデータが含まれています。たとえば、赤と緑と青の独立した配列などです。java.awt.image
パッケージでは、バイト型のデータを含むもの(ByteLookupTable
)とshort型のデータを含むもの(ShortLookupData
)の2種類のルックアップ表が定義されていて、どれもLookupTable
抽象クラスを継承しています。
imageパッケージでは、BufferedImage
オブジェクトとRaster
オブジェクトに対する操作を定義する次の2つのインタフェースが提供されています。BufferedImageOp
およびRasterOp
。
これらのインタフェースを実装するクラスとしては、AffineTransformOp、
BandCombineOp、ColorConvertOp、ConvolveOp、
LookupOp、RescaleOp
があります。これらのクラスを使って、イメージに対する幾何学的変換、ぼかし、シャープ化、コントラスト強調、しきい値、色調補正などの処理を行うことができます。
図5-4は、輪郭の検出と強調の結果を示したものです。この操作は、イメージ内の輝度の大幅な変化を強調するものです。輪郭の検出は、普通、医療用画像処理アプリケーションや地図アプリケーションで使われます。輪郭の検出を使用すると、イメージ内の隣接する構造の間のコントラストが強くなり、より細部まで識別できるようになります。
次のコードは、輪郭の検出について記述したものです。
float[] elements = { 0.0f, -1.0f, 0.0f, -1.0f, 4.f, -1.0f, 0.0f, -1.0f, 0.0f}; ... BufferedImage bimg = new BufferedImage(bw,bh,BufferedImage.TYPE_INT_RGB); Kernel kernel = new Kernel(3, 3, elements); ConvolveOp cop = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null); cop.filter(bi,bimg);
図5-5は、ルックアップ表操作の例です。ルックアップ操作は、ピクセルの個別のコンポーネントを変更する場合に使用できます。
次のコードは、ルックアップ表操作について記述したものです。
byte reverse[] = new byte[256]; for (int j=0; j<200; j++){ reverse[j]=(byte)(256-j); } ByteLookupTable blut=new ByteLookupTable(0, reverse); LookupOp lop = new LookupOp(blut, null); lop.filter(bi,bimg);
図5-6は、再スケーリングの例です。再スケーリングでは、すべての点の輝度を強くしたり弱くしたりできます。再スケーリングを使うと、メリハリのないイメージのダイナミック・レンジを拡大して、平板に見える領域の細部を際立たせることができます。
次のコードは、再スケーリングについて記述したものです。
畳込みは、ほとんどの空間フィルタリング・アルゴリズムの基になっている処理です。畳込みでは、イメージの各ピクセルの値と周囲のピクセルの値の間で重み付けを行ったり、平均化したりする処理が行われます。これにより、カーネルで数学的に指定できる方法に従って、出力される各ピクセルに周囲の隣接するピクセルからの影響を反映させることができます。図5-7は、畳込みの例です。
次に示すコードの抜粋は、イメージ処理クラスの1つであるConvolveOp
の使用方法の例です。次の例では、ソース・イメージの各ピクセルは、隣接する8つのピクセルと均等に平均化されます。
float weight = 1.0f/9.0f;float[] elements = new float[9]; // create 2D array// fill the array with nine equal elements for (i = 0; i < 9; i++) { elements[i] = weight;}// use the array of elements as argument to create a Kernelprivate Kernel myKernel = new Kernel(3, 3, elements);public ConvolveOp simpleBlur = new ConvolveOp(myKernel); // sourceImage and destImage are instances of BufferedImagesimpleBlur.filter(sourceImage, destImage) // blur the image
変数simpleBlurには、BufferedImage
またはRaster
のぼかし操作を実装するConvolveOp
の新しいインスタンスが格納されます。sourceImageとdestImageは、BufferedImage
の2つのインスタンスとします。ConvolveOp
クラスの核となるメソッドのfilter
を呼び出すと、ソース・イメージのピクセルとそれを囲む8つのピクセルの値が平均化されて、デスティネーション・イメージの対応するピクセルの値に設定されます。
この例の畳込みカーネルは、4桁の有効数字で指定される要素を持つ次の行列で表されます。
イメージの畳込みでは、デスティネーション・イメージの各ピクセルの値は、そのピクセルの値と周囲のピクセルの値を平均化するときの荷重値の組としてカーネルを使って算出されます。この操作は、イメージのチャネルごとに行われます。
次の式は、畳込みを行うときにカーネルの荷重値をソース・イメージのピクセルと関連付ける方法を示しています。カーネルの各値は、イメージの空間位置に結び付けられます。
デスティネーション・ピクセルの値は、対応するソース・ピクセルの値をカーネルの加重値に掛けた積を合計したものです。多くの単純な操作では、カーネルは対称の正方行列であり、加重値を合計すると1になります。2
この例の畳込みカーネルは、比較的単純なものです。このカーネルでは、ソース・イメージの各ピクセルが均等に加重されます。ほかのカーネルを選択し、ソース・イメージに対する荷重レベルを高くしたり低くしたりすることで、デスティネーション・イメージの輝度を強くしたり弱くしたりできます。ConvolveOp
コンストラクタで設定されるKernel
オブジェクトで、実行されるフィルタ・リングの種類が決まります。ほかの値を設定すれば、ぼかし(ガウス、円形、移動など)、シャープ化、平滑化操作など、ほかの種類の畳込みを実行できます。図5-8は、畳込みを使ったシャープ化の例です。
次に示すコードは、畳込みを使ったシャープ化の例です。
float[] elements = { 0.0f, -1.0f, 0.0f, -1.0f, 5.f, -1.0f, 0.0f, -1.0f, 0.0f}; ... Kernel kernel = new Kernel(3,3,elements); ConvolveOp cop = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null); cop.filter(bi,bimg);
目次|前|次 |