| 目次|前|次 |
Java 2D APIでは、3種類のイメージング・モデルがサポートされています。
次の表は、3種類のイメージング・モデルの機能を比較したものです。
この章では、直接方式イメージング・モデルのオブジェクトと技法について説明します。 Java 2D APIの直接方式イメージング用のクラスとインタフェースでは、メモリーにデータが格納されているピクセルにマッピングされたイメージを扱うための方法が提供されています。 このAPIは、さまざまな格納形式のイメージ・データへのアクセスと、何種類かのフィルタ・リング操作を使ったイメージ・データの処理をサポートしています。
Java 2D APIの直接方式イメージングAPIは、インタフェース、イメージ・データ・クラス、イメージ操作クラス、サンプル・モデル・クラス、カラー・モデル・クラスおよび例外の6つのカテゴリに分類できます。
|
クラス
|
説明
|
|---|---|
ImagingOpException |
スーパー・クラス:
RuntimeExceptionBufferedImageOpまたはRasterOpのフィルタ・メソッドがイメージを処理できない場合にスローされます。
|
RasterFormatException |
スーパー・クラス:
RuntimeExceptionRasterに無効なレイアウト情報がある場合にスローされます。
|
直接方式イメージング・モデルは、メモリーに格納されている固定解像度のイメージに対応しています。 また、イメージ・データに対するフィルタ・リング操作もサポートしています。 このモデルでは、多くのクラスとインタフェースが使われています。

図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_BGRTYPE_4BYTE_ABGRTYPE_4BYTE_ABGR_PRETYPE_BYTE_BINARYTYPE_BYTE_GRAYTYPE_BYTE_INDEXEDTYPE_CUSTOMTYPE_INT_ARGB_PRETYPE_INT_ARGBTYPE_INT_BGRTYPE_INT_RGBTYPE_USHORT_555_RGBTYPE_USHORT_565_RGBTYPE_INT_GRAYBufferedImageオブジェクトは、アルファ・チャネルを含むことができます。 図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);
| 目次|前|次 |