Извлечение изображений из файла .idx3-ubyte или GZIP через Python

Я создал простую функцию для facerecognition, используя facerecognizer из OpenCV. Он отлично работает с изображениями людей.

Теперь я хотел бы сделать тест, используя персональные символы вместо людей. Я наткнулся на набор данных MNIST, но они хранят изображения в странном файле, который я никогда раньше не видел.

Мне просто нужно извлечь несколько изображений из:

train-images.idx3-ubyte

и сохраните их в папке как .gif

Или я не понимаю, что это MNIST. Если да, где я могу получить такой набор данных?

ИЗМЕНИТЬ

У меня также есть файл gzip:

train-images-idx3-ubyte.gz

Я пытаюсь прочитать содержимое, но show() не работает, и если я read(), я вижу случайные символы.

images = gzip.open("train-images-idx3-ubyte.gz", 'rb')
print images.read()

ИЗМЕНИТЬ

Удалось получить полезный вывод с помощью:

with gzip.open('train-images-idx3-ubyte.gz','r') as fin:
    for line in fin:
        print('got line', line)

Как-то мне нужно преобразовать это сейчас в изображение, вывод:

введите описание изображения здесь

Ответ 1

Загрузите обучающие/тестовые изображения и ярлыки:

  • train-images-idx3-ubyte.gz: обучающий набор изображений
  • train-tags-idx1-ubyte.gz: ярлыки обучающего набора
  • t10k-images-idx3-ubyte.gz: тестовый набор изображений
  • t10k-tags-idx1-ubyte.gz: тестовый набор меток

И распакуйте их в рабочий каталог, скажем samples/.

Получите пакет python-mnist от PyPi:

pip install python-mnist

Импортируйте пакет mnist и прочитайте обучающие/тестовые изображения:

from mnist import MNIST

mndata = MNIST('samples')

images, labels = mndata.load_training()
# or
images, labels = mndata.load_testing()

Чтобы отобразить изображение на консоли:

index = random.randrange(0, len(images))  # choose an index ;-)
print(mndata.display(images[index]))

Вы получите что-то вроде этого:

............................
............................
............................
............................
............................
[email protected]@.........
[email protected]@@@@.........
[email protected]@@@............
[email protected]@................
[email protected]
[email protected]
[email protected]
[email protected]@............
[email protected]@@@@[email protected]
[email protected]@@[email protected]@.........
[email protected]@[email protected]
[email protected]
[email protected]@........
[email protected]@........
[email protected]
[email protected]@.........
[email protected]@..........
[email protected]@@..........
[email protected]@@@............
[email protected]
............................
............................
............................

Объяснение:

  • Каждое изображение списка изображений представляет собой list Python без знака байтов.
  • Ярлыки - это Python- array байтов без знака.

Ответ 2

(Используя только matplotlib, gzip и numpy)
Извлечь данные изображения:

import gzip
f = gzip.open('train-images-idx3-ubyte.gz','r')

image_size = 28
num_images = 5

import numpy as np
f.read(16)
buf = f.read(image_size * image_size * num_images)
data = np.frombuffer(buf, dtype=np.uint8).astype(np.float32)
data = data.reshape(num_images, image_size, image_size, 1)

Распечатать изображения:

import matplotlib.pyplot as plt
image = np.asarray(data[2]).squeeze()
plt.imshow(image)
plt.show()

enter image description here

Напечатайте первые 50 этикеток:

f = gzip.open('train-labels-idx1-ubyte.gz','r')
f.read(8)
for i in range(0,50):   
    buf = f.read(1)
    labels = np.frombuffer(buf, dtype=np.uint8).astype(np.int64)
    print(labels)

Ответ 3

Используйте это для извлечения базы данных mnist для изображений и ярлыков csv в python:

https://github.com/sorki/python-mnist

Ответ 4

Вы действительно можете использовать пакет idx2numpy, доступный на PyPI. Он чрезвычайно прост в использовании и напрямую преобразует данные в массивы. Вот что вы должны сделать:

Загрузка данных

Загрузите набор данных MNIST с официального сайта.
Если вы используете Linux, вы можете использовать wget, чтобы получить его из командной строки. Просто беги:

wget http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz
wget http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz
wget http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz
wget http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz

Распаковка данных

Распакуйте или распакуйте данные. В Linux вы можете использовать gzip

В конечном итоге у вас должны быть следующие файлы:

data/train-images-idx3-ubyte
data/train-labels-idx1-ubyte
data/t10k-images-idx3-ubyte
data/t10k-labels-idx1-ubyte

Префикс data/ только потому, что я извлек их в папку с именем data. Ваш вопрос выглядит так, как будто вы все сделали до сих пор, так что продолжайте читать.

Использование idx2numpy

Вот простой код Python для чтения всего из распакованных файлов в виде массивов.

import idx2numpy
import numpy as np
file = 'data/train-images-idx3-ubyte'
arr = idx2numpy.convert_from_file(file)
# arr is now a np.ndarray type of object of shape 60000, 28, 28

Теперь вы можете использовать его с OpenCV Juts таким же образом, как вы отображаете любое другое изображение, используя что-то вроде

cv.imshow("Image", arr[4])

Чтобы установить idx2numpy, вы можете использовать PyPI (менеджер пакетов pip). Просто запустите команду:

pip install idx2numpy