目次 | 前へ | 次へ |
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 クラスは、イメージの矩形座標を表し、メモリーにイメージデータを保持し、単一のイメージデータバッファーから複数のサブイメージを作成するメカニズムを提供します。また、イメージ内の特定のピクセルにアクセスするためのメソッドも提供しています。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
図 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
はラスタのピクセルデータを格納するオブジェクトで (「イメージデータと DataBuffer」を参照)、SampleModel
は DataBuffer
からのピクセルデータの解釈を提供します (「SampleModel からのピクセルデータの抽出」を参照)。
ほとんどの場合、Raster
を直接作る必要はありません。メモリーに BufferedImage
を作ると、Raster が必ず提供されます。ただし、BufferedImage
のコンストラクタメソッドを使うと、WritableRaster
を渡して Raster
を作成できます。
Raster
クラスでは、DataBuffers
と SampleModels
を指定して Rasters
を作成するための static ファクトリメソッドがいくつか提供されています。RasterOp
フィルタリングクラスを実装するときは、これらのファクトリを使うことができます。
Raster
クラスには、親ラスタと子ラスタのコンセプトが組み込まれています。これにより、同じ親からいくつでもバッファリングされたイメージを作成できるので、ストレージの効率を向上させることができます。親とその子はすべて同じデータバッファーを参照し、それぞれの子は、バッファー内で自分のイメージの位置を識別するために固有のオフセットと境界を持っています。子は、getParent
メソッドを使って所有権を識別します。
サブラスタを作成するには、Raster
.createSubRaster
メソッドを使います。サブラスタを作成する際には、サブラスタがカバーする親の領域と親の原点からのオフセットを指定します。
Raster
クラスでは、ピクセルとピクセルデータにアクセスするためのさまざまな方法が定義されています。これらの方法は、RasterOp
インタフェースを実装するとき、または低レベルのピクセル操作を行う必要のあるメソッドを実装するときに、役に立ちます。RasterOp インタフェースは、イメージデータに対するラスタレベルのフィルタリングおよび操作を提供します。
Raster.getPixel
メソッドを使うと、ピクセルを個別に取得できます。ピクセルは、配列の中の個別のサンプルとして返されます。Raster
.getDataElements
メソッドからは、指定した一連の解釈されていないイメージデータが DataBuffer
から取り出されて返されます。Raster
.getSample
メソッドからは、個別のピクセルのサンプルが返されます。getSamples
メソッドからは、イメージの特定の範囲に対するバンドが返されます。
これらのメソッドのほかに、Raster
クラスのインスタンス変数を使用して DataBuffer およびサンプルモデルにアクセスすることもできます。これらのオブジェクトでは、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
。ComponentColorModel
と PackedColorModel
は、Java™ 2 SDK で新しく導入されたものです。
DataBuffer
のデータに基づいて、SampleModel
は ColorModel
にピクセルを提供し、ColorModel
はそのピクセルを色として解釈します。
ルックアップテーブルには、1 つ以上のチャネルまたはイメージ成分のデータが含まれています。たとえば、赤と緑と青の独立した配列などです。java.awt.image
パッケージでは、バイト型のデータを含むもの (ByteLookupTable
) と short 型のデータを含むもの (ShortLookupData
) の 2 種類のルックアップテーブルが定義されていて、どれも abstract 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);
目次 | 前へ | 次へ |