Caffe: Чтение LMDB из Python

Я извлек функции, используя caffe, который создает файл .mdb. Затем я пытаюсь прочитать его с помощью Python и отображать его как читаемое число.

import lmdb

lmdb_env = lmdb.open('caffefeat')
lmdb_txn = lmdb_env.begin()
lmdb_cursor = lmdb_txn.cursor()

for key, value in lmdb_cursor:
    print str(value)

Это выводит очень длинную строку нечитаемых, сломанных символов.

Затем я попробовал распечатать int (value), который возвращает следующее:

ValueError: invalid literal for int() with base 10: '\x08\x80 \x10\x01\x18\x015\x8d\x80\xad?5'

float (value) дает следующее:

ValueError: could not convert string to float:? 5????5

Это проблема с самим файлом lmdb или связана с преобразованием типа данных?

Ответы

Ответ 1

Здесь рабочий код, который я понял,

import caffe
import lmdb

lmdb_env = lmdb.open('directory_containing_mdb')
lmdb_txn = lmdb_env.begin()
lmdb_cursor = lmdb_txn.cursor()
datum = caffe.proto.caffe_pb2.Datum()

for key, value in lmdb_cursor:
    datum.ParseFromString(value)
    label = datum.label
    data = caffe.io.datum_to_array(datum)
    for l, d in zip(label, data):
            print l, d

Ответ 2

Если вы закодировали изображения в lmdb, вы, вероятно, увидите эту ошибку при использовании кода @ytrewq

ValueError: total size of new array must be unchanged

Используйте эту функцию вместо:

import caffe
import lmdb
import PIL.Image
from StringIO import StringIO
import numpy as np

def read_lmdb(lmdb_file):
    cursor = lmdb.open(lmdb_file, readonly=True).begin().cursor()
    datum = caffe.proto.caffe_pb2.Datum()
    for _, value in cursor:
        datum.ParseFromString(value)
        s = StringIO()
        s.write(datum.data)
        s.seek(0)

        yield np.array(PIL.Image.open(s)), datum.label

Пример:

lmdb_dir = '/save/jobs/20160613-125532-958f/train_db/'
for im, label in read_lmdb(lmdb_dir):
    print label, im