Ler arquivos de imagem
Databricks recomenda que o senhor use o arquivo binário fonte de dados para carregar dados de imagem no site Spark DataFrame como bytes brutos. Consulte Soluções de referência para aplicativos de imagem para obter o fluxo de trabalho recomendado para lidar com dados de imagem.
A fonte de dados de imagem fornece uma API padrão para carregar arquivos de imagem em DataFrames do Spark como uma estrutura decodificada, dando a você acesso direto a metadados de imagem, como altura, largura, contagem de canais e dados brutos de pixel. É usado principalmente em pipelines de pré-processamento de machine learning onde campos de imagem estruturados são necessários juntamente com dados de pixel. O Databricks oferece suporte à fonte de dados de imagem para leituras em lote, incluindo a descoberta de partição para diretórios de imagem organizados. Para ler arquivos de imagem, especifique a fonte de dados format como image.
Pré-requisitos
A Databricks não exige configuração adicional para usar a fonte de dados de imagem.
Opções
Utilize os métodos .option() e .options() de DataFrameReader para configurar a fonte de dados de imagem. Para obter uma lista completa das opções com suporte, consulte a referência de opções da Spark API.
Uso
Os exemplos a seguir demonstram o carregamento de arquivos de imagem usando a API do Spark DataFrame, a seleção de campos de metadados de imagem, a exibição de miniaturas de imagem e o salvamento de dados de imagem decodificados em uma tabela Delta.
Ler arquivos de imagem
Use a API do Apache Spark DataFrame para carregar arquivos de imagem em um DataFrame. Você pode importar uma estrutura de diretório aninhada fornecendo um caminho de diretório e usar a descoberta de partição especificando um caminho com um diretório de partição (por exemplo, /path/to/dir/date=2018-01-02/category=automobile).
- Python
- Scala
- SQL
# 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)
// 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()
-- Read all images from a directory
SELECT * FROM read_files(
'/Volumes/<catalog>/<schema>/<volume>/images/',
format => 'image'
)
Selecionar metadados da imagem
Para trabalhar com dimensões de imagem ou informação de canal sem processar os dados completos de pixel, selecione campos específicos da coluna de estrutura image.
- Python
- Scala
- SQL
df = spark.read.format("image").load("/Volumes/<catalog>/<schema>/<volume>/images/")
metadata = df.select("image.origin", "image.height", "image.width", "image.nChannels")
display(metadata)
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()
SELECT image.origin, image.height, image.width, image.nChannels FROM read_files(
'/Volumes/<catalog>/<schema>/<volume>/images/',
format => 'image'
)
Exibir dados da imagem
A função display do Databricks renderiza miniaturas de imagem diretamente na coluna image ao trabalhar com a fonte de dados de imagem. Veja Imagens para opções de exibição compatíveis.
- Python
- Scala
- SQL
df = spark.read.format("image").load("/Volumes/<catalog>/<schema>/<volume>/images/")
display(df)
val df = spark.read.format("image").load("/Volumes/<catalog>/<schema>/<volume>/images/")
df.show()
SELECT * FROM read_files(
'/Volumes/<catalog>/<schema>/<volume>/images/',
format => 'image'
)
Salvar dados de imagem em uma tabela Delta
Para melhorar o desempenho de leitura ao recarregar dados de imagem, salvar o DataFrame em uma tabela Delta.
A fonte de dados de imagens armazena dados de pixel decodificados, o que aumenta o uso de disco em comparação com bytes brutos. Para persistência eficiente em armazenamento, use a fonte de dados de arquivo binário em vez disso.
- Python
- Scala
df = spark.read.format("image").load("/Volumes/<catalog>/<schema>/<volume>/images/")
df.write.format("delta").saveAsTable("<catalog>.<schema>.<table>")
val df = spark.read.format("image").load("/Volumes/<catalog>/<schema>/<volume>/images/")
df.write.format("delta").saveAsTable("<catalog>.<schema>.<table>")
Esquema de saída
Os arquivos de imagem são carregados como um DataFrame que contém uma única coluna do tipo struct chamada image com os seguintes campos:
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)
Os campos a seguir descrevem o arquivo de imagem e seus dados de pixel decodificados.
origin: O caminho do arquivo da imagem de origem.height: A altura da imagem em pixels.width: A largura da imagem em pixels.nChannels: O número de canais de cores. Os valores típicos são 1 para imagens em escala de cinza, 3 para imagens coloridas (por exemplo, RGB) e 4 para imagens coloridas com canal alfa.mode: sinalizador de número inteiro que indica como interpretar o campo de dados. Ele especifica o tipo de dados e a ordem do canal em que os dados são armazenados. Espera-se (mas não imposto) que o valor do campo seja mapeado para um dos tipos de OpenCV exibidos na tabela a seguir. Os tipos do OpenCV são definidos para 1, 2, 3 ou 4 canais e vários tipos de dados para os valores de pixel. canal order especifica a ordem em que as cores são armazenadas. Por exemplo, se o senhor tiver uma imagem típica de três canais com componentes vermelhos, azuis e verdes, há seis ordenações possíveis. A maioria das bibliotecas usa RGB ou BGR. Espera-se que três (quatro) tipos de canal OpenCV estejam na ordem BGR(A).
Mapeamento de tipos para números no OpenCV (tipos de dados x número de canais)
Tipo | 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: dados de imagem armazenados em formato binário. Os dados da imagem são representados como uma matriz tridimensional com a forma da dimensão (altura, largura, nChannels) e os valores da matriz do tipo t especificados pelo campo mode. A matriz é armazenada na ordem principal da linha.
Limitações
Uma vez que a fonte de dados de imagem decodifica arquivos de imagem durante a criação do DataFrame, aumenta o tamanho dos dados e apresenta as seguintes limitações:
- Uso do disco ao persistir : dados de imagem decodificados são significativamente maiores que bytes brutos. Se o DataFrame for persistido em uma tabela Delta, armazene bytes brutos em vez de dados decodificados para economizar espaço em disco.
- Desempenho de shuffle : A reordenação de dados de imagem decodificados requer mais espaço em disco e largura de banda da rede, resultando em operações de shuffle mais lentas. Atrasar a decodificação o máximo possível em seu pipeline.
- Biblioteca de decodificação fixa : A fonte de dados de imagem usa a biblioteca javax Image IO para decodificar imagens, o que impede o uso de bibliotecas de decodificação alternativas para um melhor desempenho ou lógica de decodificação personalizada.
Para evitar essas limitações, use a fonte de dados de arquivo binário para carregar dados de imagem e decodificar somente quando necessário.
Recursos adicionais
- Ler arquivos binários: Se sua carga de trabalho exigir bytes de imagem brutos em vez de um struct decodificado, a fonte de dados de arquivo binário evita a sobrecarga de decodificação e as limitações da fonte de dados de imagem.