Как эффективно загружать тысячи фотографий HD в pandas df и конвертировать в HDF? - PullRequest
2 голосов
/ 10 января 2020

Я хочу загрузить тысячи изображений животных в pandas df, добавить функции и, возможно, преобразовать в HDF.

Я попробовал следующий подход, используя cv2.imread()

import cv2
import os
import numpy as np
import pandas as pd

def images_to_hdf(folder_path, label):
    """
    Save a folder of images to hdf format.
    Args:
        folder_path: Path to folder containing images.
        label: A string of the image content.
    Return:
        None
    """
    image_data = [np.array(cv2.imread(folder_path + img)) for img in os.listdir(folder_path)]
    data = pd.DataFrame()
    data['Images'] = image_data
    data['Label'] = label
    data.to_hdf(path, key)

Но это займет больше 1 минуты для чтения только 100 изображений плюс ошибка (слишком большое числовое значение для хранения ...), и я уверен, что это очень неэффективный способ сделать это.

Я пытался np.fromfile() вместо cv2.imread() это очень быстро по сравнению (я не совсем уверен, что он делает), но он возвращает массивы ранга 1, и я хочу, чтобы трехмерные данные изображения сохранялись в фрейме данных pd, чтобы добавить метки, которые я буду использовать обучить классификатор, и я думаю, что это может быть способ сделать это.

1 Ответ

1 голос
/ 10 января 2020

С помощью h5py вы можете напрямую сохранять изображения и метки в файл hdf5 (без использования pandas). Вот один пример, как это сделать (адаптация от здесь ):

import os
import glob
import cv2
import h5py
import numpy as np

def images_to_hdf5(images_path='/path/to/images',
                   label=0,
                   hdf5_path='/path/to/hdf5_file/file.hdf5'):

    image_names = glob.glob(os.path.join(images_path, '*.jpg'))
    n = len(image_names)
    labels = [label]*n

    hdf5_file = h5py.File(hdf5_path, mode='w')
    hdf5_file.create_dataset("Images", (n, 3, 224, 224), np.int8)
    hdf5_file.create_dataset("Labels", (n,), np.int8)
    hdf5_file["Labels"][...] = labels

    for i, image_name in enumerate(image_names):
        img = cv2.imread(image_name)        
        img = cv2.resize(img, (224, 224))  # shape (224, 224, 3)
        img = np.rollaxis(img, 2)[None]  # shape (1, 3, 224, 224)
        hdf5_file["Images"][i, ...] = img

    hdf5_file.close()

Чтобы открыть его:

hdf5_file = h5py.File(hdf5_path, "r")

Для доступа, например, к первому изображению и метке:

hdf5_file["Images"][0]
hdf5_file["Labels"][0]
#hdf5_file.close()
...