Lire les fichiers image

Important

Databricks recommande d’utiliser la source de données de fichier binaire pour charger des données d’image dans le DataFrame Spark sous forme d’octets bruts. Pour plus d’informations sur le flux de travail recommandé pour traiter les données d’image, consultez Solution de référence pour les applications image.

La source de données d’image fournit une API standard pour charger des fichiers image dans des DataFrames Spark en tant que struct décodé, ce qui vous donne un accès direct aux métadonnées d’image telles que la hauteur, la largeur, le nombre de canaux et les données de pixel brut. Il est principalement utilisé dans les pipelines de prétraitement machine learning où les champs d’image structurées sont requis en même temps que les données de pixels. Azure Databricks prend en charge la source de données d’image pour les lectures par lots, notamment la découverte de partition pour les répertoires d’images organisés. Pour lire les fichiers image, spécifiez format pour le image de la source de données.

Prerequisites

Azure Databricks ne nécessite pas de configuration supplémentaire pour utiliser la source de données d’image.

Options

Utilisez les méthodes et .options() les .option() méthodes de configuration de la source de DataFrameReader données d’image. Pour obtenir la liste complète des options prises en charge, consultez la référence des options d’API Spark.

Usage

Les exemples suivants illustrent le chargement de fichiers image à l’aide de l’API DataFrame Spark, la sélection des champs de métadonnées d’image, l’affichage des miniatures d’image et l’enregistrement des données d’image décodées dans une table Delta.

Lire les fichiers image

Utilisez l’API DataFrame Apache Spark pour charger des fichiers image dans un DataFrame. Vous pouvez importer une structure de répertoires imbriquée en fournissant un chemin d’accès au répertoire et en utilisant la découverte de partition en spécifiant un chemin d’accès avec un répertoire de partition (par exemple). /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)

Scala

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

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

SQL

-- Read all images from a directory
SELECT * FROM read_files(
  '/Volumes/<catalog>/<schema>/<volume>/images/',
  format => 'image'
)

Sélectionner les métadonnées d’image

Pour utiliser des dimensions d’image ou des informations de canal sans traiter les données en pixels complets, sélectionnez des champs spécifiques dans la colonne de image struct.

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)

Scala

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

SQL

SELECT image.origin, image.height, image.width, image.nChannels FROM read_files(
  '/Volumes/<catalog>/<schema>/<volume>/images/',
  format => 'image'
)

Affichage des données d’image

La fonction Databricks display restitue les miniatures d’image directement dans la colonne lors de l’utilisation image de la source de données d’image. Consultez Images pour connaître les options d’affichage prises en charge.

Python

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

Scala

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

SQL

SELECT * FROM read_files(
  '/Volumes/<catalog>/<schema>/<volume>/images/',
  format => 'image'
)

Enregistrer des données d’image dans une table Delta

Pour améliorer les performances de lecture lors du chargement des données d’image, enregistrez le DataFrame dans une table Delta.

Note

La source de données d’image stocke les données de pixel décodées, ce qui augmente l’utilisation du disque par rapport aux octets bruts. Pour une persistance efficace du stockage, utilisez plutôt la source de données de fichier binaire .

Python

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

Scala

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

Schéma de sortie

Les fichiers image sont chargés en tant que DataFrame contenant une colonne de type struct unique appelée image avec les champs suivants :

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)

Les champs suivants décrivent le fichier image et ses données de pixel décodées.

  • origin: chemin d’accès au fichier de l’image source.
  • height: hauteur de l’image en pixels.
  • width: largeur de l’image en pixels.
  • nChannels : Nombre de canaux de couleur. Les valeurs classiques sont 1 pour les images de nuances de gris, 3 pour les images colorées (par exemple, RVB) et 4 pour les images colorées avec canal alpha.
  • mode : Indicateur d’entier qui indique comment interpréter le champ de données. Il spécifie le type de données et l’ordre des canaux dans lesquels les données sont stockées. La valeur du champ est attendue (mais pas imposée) à correspondre à l’un des types OpenCV affichés dans le tableau suivant. Les types OpenCV sont définis pour 1, 2, 3 ou 4 canaux et plusieurs types de données pour les valeurs de pixels. L’ordre des canaux spécifie l’ordre dans lequel les couleurs sont stockées. Par exemple, si vous avez une image typique à trois canaux avec des composantes rouge, bleue et verte, il y a six ordres possibles. La plupart des bibliothèques utilisent soit RVB, soit BGR. Les types OpenCV à trois (quatre) canaux sont censés être dans l’ordre BGR(A).

Mappage de type à des nombres dans OpenCV (types de données x nombre de canaux)

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 : Données d’image stockées dans un format binaire. Les données d’image sont représentées sous forme de tableau 3 dimensions avec la forme de dimension (hauteur, largeur, nChannels) et les valeurs de tableau de type t spécifiées par le champ mode. Le tableau est stocké dans l’ordre row-major.

Limitations

Étant donné que la source de données image décode les fichiers image lors de la création de DataFrame, elle augmente la taille des données et présente les limitations suivantes :

  • Utilisation du disque lors de la persistance : les données d’image décodées sont nettement supérieures aux octets bruts. Si vous conservez le DataFrame dans une table Delta, stockez des octets bruts au lieu de données décodées pour économiser de l’espace disque.
  • Performances aléatoires : le déchiquetage des données d’image décodées nécessite davantage d’espace disque et de bande passante réseau, ce qui entraîne des opérations de shuffle plus lentes. Retarder le décodage aussi longtemps que possible dans votre pipeline.
  • Correction de la bibliothèque de décodage : la source de données d’image utilise la bibliothèque d’E/S d’image javax pour décoder des images, ce qui vous empêche d’utiliser d’autres bibliothèques de décodage pour de meilleures performances ou une logique de décodage personnalisée.

Pour éviter ces limitations, utilisez la source de données de fichier binaire pour charger des données d’image et décoder uniquement si nécessaire.

Ressources additionnelles

  • Lire des fichiers binaires : si votre charge de travail nécessite des octets d’image bruts plutôt qu’un struct décodé, la source de données de fichier binaire évite la surcharge de décodage et les limitations de la source de données d’image.