メインコンテンツまでスキップ

画像ファイルの読み取り

重要

Databricks では、 バイナリ ファイル データソースを使用して、イメージ データを生のバイトとして Spark データフレーム にロードすることをお勧めします。 画像データの処理に推奨されるワークフローについては、 画像アプリケーションのリファレンス ソリューション を参照してください。

イメージデータソースは、イメージファイルをデコードされた構造体としてSpark DataFramesにロードするための標準APIを提供し、高さ、幅、チャンネル数、生ピクセルデータなどのイメージメタデータに直接アクセスできます。ピクセルデータと並行して構造化された画像フィールドが必要とされる機械学習の前処理パイプラインで、主に使用されます。Databricksは、整理された画像ディレクトリのパーティション検出を含め、バッチ読み込み向けの画像データソースをサポートしています。画像ファイルを読み取るには、データソース formatimage として指定します。

前提条件

Databricks はイメージデータソースを使用するのに追加の設定は必要ありません。

オプション

画像データソースを構成するには、DataFrameReader.option().options()のメソッドを使用します。サポートされているオプションの完全なリストについては、Spark API オプション参照をご覧ください。

使い方

次の例では、Spark DataFrame API を使用した画像ファイルの読み込み、画像メタデータフィールドの選択、画像サムネイルの表示、およびデコードされた画像データの Delta テーブルへの保存について説明します。

画像ファイルの読み取り

Apache Spark DataFrame API を使用して、画像ファイルを DataFrame に読み込みます。ディレクトリパスを指定することで、入れ子になったディレクトリ構造をインポートできます。また、パーティションディレクトリのパス(例:/path/to/dir/date=2018-01-02/category=automobile)を指定してパーティション検出機能を使用できます。

Python
# Read all images from a directory
df = spark.read.format("image").load("/Volumes/<catalog>/<schema>/<volume>/images/")
display(df)

# Use partition discovery by specifying a partitioned path
df = spark.read.format("image").load("/Volumes/<catalog>/<schema>/<volume>/images/date=2024-01-01/category=dogs/")
display(df)

画像メタデータを選択します

完全なピクセルデータを処理することなく、画像の寸法やチャンネル情報を扱うには、image 構造体列から特定のフィールドを選択します。

Python
df = spark.read.format("image").load("/Volumes/<catalog>/<schema>/<volume>/images/")
metadata = df.select("image.origin", "image.height", "image.width", "image.nChannels")
display(metadata)

画像データの表示

画像データソースを使用する場合、Databricks display 関数はimage列に画像を直接表示します。サポートされている表示オプションについては、「画像」を参照してください。

Python
df = spark.read.format("image").load("/Volumes/<catalog>/<schema>/<volume>/images/")
display(df)

画像データをDeltaテーブルに保存します

画像データを再度読み込む際の読み取りパフォーマンスを向上させるには、DataFrameをDeltaテーブルに保存してください。

注記

イメージデータソースは、デコードされたピクセルデータを保存し、生のバイトと比較してディスク使用量が増加します。ストレージ効率の高い永続化には、代わりにバイナリファイルデータソースを使用してください。

Python
df = spark.read.format("image").load("/Volumes/<catalog>/<schema>/<volume>/images/")
df.write.format("delta").saveAsTable("<catalog>.<schema>.<table>")

出力スキーマ

イメージ ファイルは、次のフィールドを持つ image という 1 つの構造体型列を含む データフレーム として読み込まれます。

root
|-- image: struct (nullable = true)
| |-- origin: string (nullable = true)
| |-- height: integer (nullable = false)
| |-- width: integer (nullable = false)
| |-- nChannels: integer (nullable = false)
| |-- mode: integer (nullable = false)
| |-- data: binary (nullable = false)

以下のフィールドは、イメージファイルおよびそのデコードされたピクセルデータについて説明します。

  • originソース画像のファイルパスです。
  • height:画像の高さ(ピクセル)です。
  • width:画像の幅はピクセル単位です。
  • nChannels: カラーチャンネルの数。 一般的な値は、グレースケール画像の場合は 1、カラー画像 (RGB など) の場合は 3、アルファチャンネル付きのカラー画像の場合は 4 です。
  • mode: データ フィールドの解釈方法を示す整数フラグ。 これは、データが格納されるデータ型とチャンネルの順序を指定します。 フィールドの値は、次の表に示す OpenCV タイプのいずれかにマップされることが想定されます (ただし、強制されません)。 OpenCV タイプは、1、2、3、または 4 チャンネルと、ピクセル値に対していくつかのデータ型に対して定義されます。 チャンネルの順序は、色が保存される順序を指定します。 たとえば、赤、青、緑のコンポーネントを含む一般的な 3 つのチャンネル画像がある場合、6 つの順序が可能です。 ほとんどのライブラリは RGB または BGR を使用します。 OpenCVの3種類はBGR(A)順になる予定です。

OpenCVにおけるタイプから数値へのマップ (データ型 × チャンネル数)

Type

C1

C2

C3

C4

CV_8U

0

8

16 時間

24

CV_8S

1

9

17

25

CV_16U

2

10

18

26

CV_16S

3

11

19

27

CV_32U

4

12

20

28

CV_32S

5

13

21

29

CV_64F

6

14

22

30

  • data: バイナリ形式で保存された画像データ。 イメージ データは、次元形状 (height、width、nChannels) と mode フィールドで指定されたタイプ t の配列値を持つ 3 次元配列として表されます。 配列は、行優先の順序で格納されます。

制限事項:

イメージ データソースは、DataFrame の作成時に画像ファイルをデコードするため、データサイズが増加し、以下の制限があります。

  • 永続化時のディスク使用量 :デコードされた画像データは、生のバイトよりもかなり大きくなります。DataFrame を Delta テーブルに永続化する場合、デコードされたデータの代わりに生のバイトを保存し、ディスク領域を節約してください。
  • シャッフルパフォーマンス :デコードされた画像データのシャッフルには、より多くのディスク領域とネットワーク帯域幅が必要となるため、シャッフル操作が遅くなります。パイプラインでは、デコード処理を可能な限り遅らせてください。
  • 固定デコードライブラリ :image データソースは、画像をデコードするために javax Image IO ライブラリを使用しています。これにより、パフォーマンスの向上やカスタムデコードロジックのための代替デコードライブラリを使用することができません。

これらの制限を回避するには、バイナリファイルデータソースを使用してイメージデータをロードし、必要な場合にのみデコードしてください。

その他のリソース

  • バイナリファイルの読み取り: ワークロードでデコードされた構造体ではなく生の画像バイトが必要な場合、バイナリファイルデータソースは画像データソースのデコードのオーバーヘッドと制限を回避します。