Cómo procesar archivos en una carpeta#
En este cuaderno programaremos un bucle que recorre una carpeta de imágenes. Además, el bucle llamará a una función de Python que analiza las imágenes una por una. Por lo tanto, procesaremos todas las imágenes en esa carpeta utilizando el mismo procedimiento.
Ver también
import os
from skimage.io import imread
from matplotlib.pyplot import imshow, show
from skimage.io import imread
import numpy as np
Para fines de demostración, reutilizamos una carpeta de imágenes que muestran rodajas de plátano fotografiadas mediante imágenes de resonancia magnética (Cortesía de Nasreddin Abolmaali, OncoRay, TU Dreesden)
# define the location of the folder to go through
directory = '../../data/banana/'
# get a list of files in that folder
file_list = os.listdir(directory)
file_list
['banana0002.tif',
'banana0003.tif',
'banana0004.tif',
'banana0005.tif',
'banana0006.tif',
'banana0007.tif',
'banana0008.tif',
'banana0009.tif',
'banana0010.tif',
'banana0011.tif',
'banana0012.tif',
'banana0013.tif',
'banana0014.tif',
'banana0015.tif',
'banana0016.tif',
'banana0017.tif',
'banana0018.tif',
'banana0019.tif',
'banana0020.tif',
'banana0021.tif',
'banana0022.tif',
'banana0023.tif',
'banana0024.tif',
'banana0025.tif',
'banana0026.tif',
'image_source.txt']
Obviamente, no solo hay imágenes en esa carpeta. Podemos filtrar esa lista con una breve declaración for:
image_file_list = [file for file in file_list if file.endswith(".tif")]
image_file_list
['banana0002.tif',
'banana0003.tif',
'banana0004.tif',
'banana0005.tif',
'banana0006.tif',
'banana0007.tif',
'banana0008.tif',
'banana0009.tif',
'banana0010.tif',
'banana0011.tif',
'banana0012.tif',
'banana0013.tif',
'banana0014.tif',
'banana0015.tif',
'banana0016.tif',
'banana0017.tif',
'banana0018.tif',
'banana0019.tif',
'banana0020.tif',
'banana0021.tif',
'banana0022.tif',
'banana0023.tif',
'banana0024.tif',
'banana0025.tif',
'banana0026.tif']
Alternativamente, también podemos escribir un bucle for más largo y verificar si los archivos son imágenes. Este código hace exactamente lo mismo, solo está escrito de una manera diferente.
# go through all files in the folder
for file in file_list:
# if the filename is of a tif-image, print it out
if file.endswith(".tif"):
print(file)
banana0002.tif
banana0003.tif
banana0004.tif
banana0005.tif
banana0006.tif
banana0007.tif
banana0008.tif
banana0009.tif
banana0010.tif
banana0011.tif
banana0012.tif
banana0013.tif
banana0014.tif
banana0015.tif
banana0016.tif
banana0017.tif
banana0018.tif
banana0019.tif
banana0020.tif
banana0021.tif
banana0022.tif
banana0023.tif
banana0024.tif
banana0025.tif
banana0026.tif
Como puedes ver arriba, image_file_list es una lista de cadenas. Almacenar el nombre de la imagen en una lista significa mucho menos poder computacional que almacenar las imágenes mismas en la lista. Tiene sentido usar imread en las imágenes en el último momento posible, aquí en el bucle for a continuación. Si estás interesado en estructuras de carpetas y cómo especificar estos directorios, puedes consultar estos dos cuadernos de Jupyter aquí y aquí.
Para mostrar todas las imágenes, necesitamos abrirlas desde el directory correcto:
# go through all files in the folder
for image_file in image_file_list:
image = imread(directory + image_file)
imshow(image)
show()
Las funciones personalizadas nos ayudan a mantener el código organizado. Por ejemplo, podemos poner el código de análisis de imágenes en una función y luego simplemente llamarlo:
def load_and_measure(filename):
"""
This function opens an image and returns its mean intensity.
"""
image = imread(filename)
# return mean intensity in the image
return np.mean(image)
# for testing
load_and_measure(directory + "banana0010.tif")
69.15106201171875
Con una función personalizada así, también podemos hacer uso de la forma corta para escribir bucles for:
mean_intensities_of_all_images = [load_and_measure(directory + file) for file in image_file_list]
mean_intensities_of_all_images
[12.94198947482639,
25.04678683810764,
39.627543131510414,
49.71319580078125,
56.322109646267364,
60.08679877387153,
63.94538031684028,
66.04618326822917,
69.15106201171875,
70.85603162977431,
74.40909152560764,
77.48423936631944,
81.77360026041667,
85.44072129991319,
91.22532823350694,
94.36199951171875,
98.47229682074652,
99.3980712890625,
102.34300401475694,
101.50947401258681,
97.14067247178819,
80.13118489583333,
49.77497694227431,
28.36090766059028,
18.806070963541668]
Ejercicio#
Abre todas las imágenes del conjunto de datos de plátanos, segmenta las imágenes y mide el centroide de las rodajas de plátano en una tabla. Escribe los resultados de las mediciones en “banana.csv”.
Pista: En lugar del comando imshow en el último ejemplo, ejecuta tu flujo de trabajo de procesamiento de imágenes. Configura primero el flujo de trabajo de procesamiento de imágenes, por ejemplo, en una función personalizada. Programa la iteración sobre los archivos en una carpeta al final, después de que el procesamiento de imágenes funcione.