サポートされない形式のイメージ ファイルに対するブロック処理の実行
関数 blockproc
は、TIFF または JPEG2000 ファイルを読み取ったり、TIFF ファイルに書き込んだりするだけでなく、他の形式でも読み取りや書き込みができます。別のファイル形式でイメージ データを操作するには、ImageAdapter
クラスから継承するクラスを作成しなければなりません。ImageAdapter
クラスは Image Processing Toolbox™ ソフトウェアの一部である抽象クラスです。これは、blockproc
がディスク上のイメージのファイル I/O に使用するメソッドのシグネチャを定義します。イメージ アダプター クラスのインスタンスをファイルに関連付け、blockproc
への引数として使用してファイルベースのブロック処理を行うことができます。
このセクションでは、サンプル クラス (LanAdapter
クラス) について説明して、イメージ アダプター クラスの書き込みプロセスを示します。LanAdapter
クラスはツールボックスの一部です。この単純な読み取り専用のクラスを使用して、任意の大きさの uint8
LAN ファイルを blockproc
で処理します。
LAN ファイル形式の詳細
LanAdapter
クラスの動作について理解するには、まず LAN ファイル形式について知らなければなりません。Landsat Thematic Mapper 撮影画像が Erdas LAN ファイル形式で格納されています。Erdas LAN ファイルには 128 バイトのヘッダーが含まれ、その後にデータの 1 つ以上のスペクトル バンド、ライン挟み込みバンド並び (BIL) が帯域番号の昇順で含まれています。データはリトルエンディアンの順番で格納されています。ヘッダーには、サイズ、データ型、ファイル内の撮影画像の帯域数などのファイルに関する複数の重要情報が含まれています。LAN ファイル形式の仕様は、次の表に示すように、ファイル ヘッダーの最初の 24 バイトを定義します。
ファイル ヘッダーの内容
バイト | データ型 | 内容 |
---|---|---|
1–6 | ファイル形式のバージョンを識別する 6 バイトの文字配列 | 'HEADER' または 'HEAD74' (7.4 以前のファイルは 'HEADER' を表示) |
7–8 | 16 ビット整数 | ファイルのパック タイプ (ビット深度を示す) |
9–10 | 16 ビット整数 | データの帯域数 |
11–16 | 6 バイト | 未使用 |
17–20 | 32 ビット整数 | データの列数 |
21–24 | 32 ビット整数 | データの行数 |
残りの 104 バイトにはファイルの他のさまざまなプロパティが含まれていますが、この例では使用しません。
ヘッダーの解析
通常、LAN ファイルを操作するときは、最初にヘッダーを解析してファイルの詳細を調べます。次のコードは、rio.lan
ファイルのヘッダーを解析する方法を示しています。
ファイルを開きます。
file_name = 'rio.lan'; fid = fopen(file_name,'r');
ヘッダーの最初の 6 バイトを読み取ります。
headword = fread(fid,6,'uint8=>char')'; fprintf('Version ID: %s\n',headword);
パック タイプを読み取ります。
pack_type = fread(fid,1,'uint16',0,'ieee-le'); fprintf('Pack Type: %d\n',pack_type);
スペクトル バンド数を読み取ります。
num_bands = fread(fid,1,'uint16',0,'ieee-le'); fprintf('Number of Bands: %d\n',num_bands);
イメージの幅と高さを読み取ります。
unused_bytes = fread(fid,6,'uint8',0,'ieee-le'); width = fread(fid,1,'uint32',0,'ieee-le'); height = fread(fid,1,'uint32',0,'ieee-le'); fprintf('Image Size (w x h): %d x %d\n',width,height);
ファイルを閉じます。
fclose(fid);
以下のような出力が表示されます。
Version ID: HEAD74 Pack Type: 0 Number of Bands: 7 Image Size (w x h): 512 x 512
rio.lan
ファイルは 512 行 512 列のサイズで、7 バンド イメージです。パック タイプ 0 は、各サンプルが 8 ビットの符号なし整数 (uint8
データ型) であることを示しています。
ファイルの読み取り
一般的なインメモリ ワークフローの場合、関数 multibandread
を使用してこの LAN ファイルを読み取ります。LAN 形式にはそれぞれバンド 3、2、1 の可視スペクトルの RGB データが格納されています。トゥルーカラー イメージを作成して、処理を進めることができます。
truecolor = multibandread('rio.lan', [512, 512, 7],... 'uint8=>uint8', 128,'bil', 'ieee-le', {'Band','Direct',[3 2 1]});
ただし、非常に大きな LAN ファイルの場合、システム機能によっては multibandread
を使用してメモリ内のイメージ全体を読み取って処理することが現実的でない場合があります。メモリ制限を回避するには、関数 blockproc
を使用します。blockproc
を使用すると、ファイルベースのワークフローでイメージを処理できます。一度に 1 ブロックを読み取って処理し、結果を書き込むことができます。
関数 blockproc
は特定のファイル形式の読み取りと書き込みのみをサポートしていますが、ImageAdapter
クラスを介して拡張できます。特定のファイル形式でイメージ アダプター クラスを書き込むには、次の操作が可能でなければなりません。
ディスク上のファイル サイズをクエリする
ファイルからデータの四角形ブロックを読み取る
これら 2 つの条件を満たす場合、LAN ファイルでイメージ アダプター クラスを書き込むことができます。イメージ ヘッダーを解析してファイル サイズをクエリし、multibandread
への呼び出しを変更して、データの特定のブロックを読み取ることができます。これらの 2 つの目的関数のコードをイメージ アダプター クラス構造体にカプセル化してから、関数 blockproc
を使用して大きな LAN ファイルを直接操作できます。LanAdapter
クラスは LAN ファイルのイメージ アダプター クラスであり、Image Processing Toolbox ソフトウェアの一部です。
LanAdapter クラスの検証
この節では、LanAdapter
クラスのコンストラクター、プロパティ、およびメソッドについて説明します。LanAdapter
クラスについて学習すると、独自のイメージ アダプター クラスの記述の準備に役立ちます。オブジェクト指向プログラミングを初めて使用する場合、クラス記述の一般的な情報については、クラスの開発 — 一般的なワークフローを参照してください。
LanAdapter.m
を開いて、LanAdapter
クラスの実装について確認しましょう。
Classdef
LanAdapter
クラスはキーワード classdef
で開始されます。classdef
セクションはクラスの名前を定義し、LanAdapter
が ImageAdapter
スーパークラスから継承されることを示します。ImageAdapter
から継承すると、新しいクラスでは次のことができます。
blockproc
とのやり取り共通の
ImageAdapter
プロパティの定義blockproc
が LAN ファイルの読み取りおよび書き込みに使用するインターフェイスの定義
プロパティ
classdef
セクションの後の LanAdapter
クラスには、クラス プロパティの 2 つのブロックが含まれています。最初のブロックには、公開表示できるが公開変更できないプロパティが含まれています。2 番目のブロックには完全にパブリックなプロパティが含まれています。LanAdapter
クラスは、ファイル ヘッダーの一部の情報をクラス プロパティとして格納します。ImageAdapter
から継承するが別のファイル形式をサポートする他のクラスには、別のプロパティがある場合があります。
classdef LanAdapter < ImageAdapter properties(GetAccess = public, SetAccess = private) Filename NumBands end properties(Access = public) SelectedBands end
LanAdapter.m
に定義されたプロパティに加え、クラスは ImageAdapter
スーパークラスから ImageSize
プロパティを継承します。新しいクラスはコンストラクター内に ImageSize
プロパティを設定します。
メソッド: クラス コンストラクター
クラス コンストラクターは LanAdapter
オブジェクトを初期化します。LanAdapter
コンストラクターは LAN ファイルのヘッダー情報を解析し、クラス プロパティを設定します。methods
ブロック内のコンストラクター、つまりクラス メソッドを実装します。
コンストラクターには、LAN ファイルのヘッダーの解析に使用したものと同じコードの大部分が含まれています。LanAdapter
クラスは uint8
データ型のファイルしかサポートしないので、コンストラクターは LAN ファイルのパック タイプとヘッドワードを検証します。クラス プロパティにはその他の情報が格納されます。ピクセル データの読み取りを行うメソッドではこれらのプロパティを使用します。SelectedBands
プロパティを使用すると、すべてのバンドを読み取るという既定の設定で、バンドのサブセットを読み取ることができます。
methods function obj = LanAdapter(fname) % LanAdapter constructor for LanAdapter class. % When creating a new LanAdapter object, read the file % header to validate the file as well as save some image % properties for later use. % Open the file. obj.Filename = fname; fid = fopen(fname,'r'); % Verify that the file begins with the headword 'HEADER' or % 'HEAD74', as per the Erdas LAN file specification. headword = fread(fid,6,'uint8=>char'); if ~(strcmp(headword','HEADER') || strcmp(headword',... 'HEAD74')) error('Invalid LAN file header.'); end % Read the data type from the header. pack_type = fread(fid,1,'uint16',0,'ieee-le'); if ~isequal(pack_type,0) error(['Unsupported pack type. The LanAdapter example ' ... 'only supports reading uint8 data.']); end % Provide band information. obj.NumBands = fread(fid,1,'uint16',0,'ieee-le'); % By default, return all bands of data obj.SelectedBands = 1:obj.NumBands; % Specify image width and height. unused_field = fread(fid,6,'uint8',0,'ieee-le'); width = fread(fid,1,'uint32',0,'ieee-le'); height = fread(fid,1,'uint32',0,'ieee-le'); obj.ImageSize = [height width]; % Close the file handle fclose(fid); end % LanAdapter
メソッド: 必須
アダプター クラスには、抽象スーパークラス ImageAdapter
内に定義された 2 つの必須メソッドがあります。すべてのイメージ アダプター クラスはこれらのメソッドを実装しなければなりません。関数 blockproc
は最初のメソッド readRegion
を使用してディスク上のファイルからデータのブロックを読み取ります。第 2 のメソッド close
はイメージ アダプター オブジェクトで必要なクリーンアップを実行します。
function data = readRegion(obj, region_start, region_size) % readRegion reads a rectangular block of data from the file. % Prepare various arguments to MULTIBANDREAD. header_size = 128; rows = region_start(1):(region_start(1) + region_size(1) - 1); cols = region_start(2):(region_start(2) + region_size(2) - 1); % Call MULTIBANDREAD to get data. full_size = [obj.ImageSize obj.NumBands]; data = multibandread(obj.Filename, full_size,... 'uint8=>uint8', header_size, 'bil', 'ieee-le',... {'Row', 'Direct', rows},... {'Column','Direct', cols},... {'Band', 'Direct', obj.SelectedBands}); end % readRegion
readRegion
には 2 つの入力引数 region_start
および region_size
があります。region_start
引数は [row col]
という形式の 2 つの要素のベクトルで、データのリクエスト ブロック内の最初のピクセルを定義します。region_size
引数は [num_rows num_cols]
という形式の 2 つの要素のベクトルで、データのリクエストされたブロックのサイズを定義します。readRegion
メソッドはこれらの入力引数を使用して、イメージからデータのリクエストされたブロックを読み取って、返します。
readRegion
メソッドは、特定のファイルの読み取りにどのツールを使用できるかによって、さまざまなファイル形式で異なる実装が行われます。LanAdapter
クラスの readRegion
メソッドでは、入力引数を使用して multibandread
のカスタム入力を準備します。LAN ファイルの場合、multibandread
ではイメージの特定のサブセクションを読み取る便利な方法を使用できます。
この他に必要とされるメソッドは close
です。LanAdapter
クラスの close
メソッドは次のように表示されます。
function close(obj) % Close the LanAdapter object. This method is a part % of the ImageAdapter interface and is required. % Since the readRegion method is "atomic", there are % no open file handles to close, so this method is empty. end end % public methods end % LanAdapter
コメントが示すように、LanAdapter
の close
メソッドには実行するものがなく、close
は空です。関数 multibandread
は開いているファイル ハンドルの保守が必要ないため、close
メソッドにはクリーンアップするハンドルがありません。他のファイル形式のイメージ アダプター クラスには、ファイル ハンドルの終了や他のクラスのクリーンアップの役割の実行などの、さらに多くの close
メソッドがあります。
メソッド (オプション)
前述のように、LanAdapter
クラスは LAN ファイルを読み取れますが書き込めません。LAN 形式のファイル、または blockproc
でサポートされていない形式のファイルに出力を書き込むには、writeRegion
のオプションのメソッドを実装します。次に、クラスを blockproc
の 'Destination'
パラメーターとして指定して、選択した形式のファイルに出力を書き込むことができます。
writeRegion
メソッドのシグネチャは以下のとおりです。
function [] = writeRegion(obj, region_start, region_data)
最初の引数 region_start
は、writeRegion
メソッドが書き込むブロックの最初のピクセルを示します。2 番目の引数 region_data
には、メソッドがファイルに書き込む新しいデータが含まれています。
writeRegion
メソッドを実装するクラスは LanAdapter
よりもさらに複雑である場合があります。書き込み可能なイメージ アダプター オブジェクトを作成するとき、クラスはクラス コンストラクターに新しいファイルをさらに作成しなければならない場合がよくあります。このファイル作成ではコンストラクター内にさらに複雑な構文が必要です。ここでは、作成する新しいファイルのサイズとデータ型を指定しなければならない場合があります。また、新しいファイルを作成するコンストラクターでも、オペレーティング システムのファイル アクセス許可や難しいファイル作成コードなどの他の問題が発生することがあります。
blockproc
での LanAdapter クラスの使用
これで、LanAdapter
クラスの動作を理解できました。このクラスを使用して LAN ファイルの可視帯域を強化できます。関数 blockproc
が LanAdapter
クラスをどのように処理するかについては、大きなイメージの統計値の計算の例を参照してください。
参考
blockproc
| ImageAdapter
| multibandread