我需要读取SVHN数据集并尝试读取第一个图像的文件名。
我正在努力了解HDF5的结构,特别是在理解SVHN数据集的层次结构/结构方面
这两种读取图像名称的方法有什么区别?
我在getName()
函数的定义中遇到了这个脚本中的方法1:https://github.com/bdiesel/tensorflow-svhn/blob/master/digit_struct.py
我玩了hdf5格式文件并提出了方法2,同时尝试了显示相同结果的不同内容。
# Both these methods read the first character of the name of the 1st
# image in svhn dataset
f = h5py.File(path_to_svhn_dataset,'r')
# method 1
f[f['digitStruct']['name'][0][0]].value
# method 2
f[f['digitStruct']['name'].value[0].item()].value[0][0]
第一个图像是文件名为“1.png”的文件。上面提到的获取文件名的第一个字符的方法都会给我们相当于ascii'1' - > 49的int
首先,两种方法的输出存在细微差别。 方法1:返回完整数组(编码文件名) 方法2:仅返回数组的第一个元素(字符)
让我们解构您的代码以了解您拥有的内容。
第一部分涉及h5py
数据对象。
f['digitStruct']
- >返回一个h5py组对象
f['digitStruct']['name']
- >返回一个h5py数据集对象
f['digitStruct']['name'].name
- >返回数据集对象的名称(路径)
注意:
/digitStruct/name
数据集包含“对象引用”。每个数组条目都是指向另一个h5py对象的指针(在本例中是另一个数据集)。例如(用于描述2个对象引用的空格):
f[ f['digitStruct']['name'][0][0] ]
- >返回[0] [0]处引用的对象
因此,外部f[ obj_ref ]
就像其他对象引用一样。
在f['digitStruct']['name'][0][0]
的情况下,这是指向数据集/#refs#/b
的对象换句话说,f['digitStruct']['name'][0][0]
引用相同的对象:f['#refs#']['b']
或f['/#refs#/b']
对于h5py对象引用来说太多了。 让我们继续使用方法1从此对象引用中获取数据。
f[f['digitStruct']['name'][0][0]].value
- >将整个/#refs#/b
数据集作为NumPy数组返回。
但是,dataset.value
已弃用,NumPy索引是首选,如下所示:f[f['digitStruct']['name'][0][0]][:]
(获取整个数组)
注意:这两个都返回整个编码字符数组。在这一点上,获得名称是Python和NumPy功能。使用此命令将文件名作为字符串返回:
f[f['digitStruct']['name'][0][0]][:].tostring().decode('ascii')
现在让我们解构您用于方法2的对象引用。
f['digitStruct']['name'].value
- >将整个/digitStruct/name
数据集作为NumPy数组返回。它有13,068行对象引用
f['digitStruct']['name'].value[0]
- >是第一行
f['digitStruct']['name'].value[0].item()
- >将该数组元素复制到python标量
所以所有这些都指向同一个对象:
方法1:f['digitStruct']['name'][0][0]
方法2:f['digitStruct']['name'].value[0].item()
对于这个例子,它们都与f['#refs#']['b']
或f['/#refs#/b']
相同。
与方法1一样,获取字符串是Python和NumPy功能。
f[f['digitStruct']['name'].value[0].item()][:].tostring().decode('ascii')
是的,对象引用很复杂......
我的建议:
使用NumPy索引而不是.value
从对象中提取NumPy数组(如上面的修改方法1所示)。
完整性的示例代码。中间打印语句用于显示正在发生的事情。
import h5py
# Both of these methods read the name of the 1st
# image in svhn dataset
f = h5py.File('test_digitStruct.mat','r')
print (f['digitStruct'])
print (f['digitStruct']['name'])
print (f['digitStruct']['name'].name)
# method 1
print('\ntest method 1')
print (f[f['digitStruct']['name'][0][0]])
print (f[f['digitStruct']['name'][0][0]].name)
# both of these get the entire array / filename:
print (f[f['digitStruct']['name'][0][0]].value)
print (f[f['digitStruct']['name'][0][0]][:]) # same as .value above
print (f[f['digitStruct']['name'][0][0]][:].tostring().decode('ascii'))
# method 2
print('\ntest method 2')
print (f[f['digitStruct']['name'].value[0].item()])
print (f[f['digitStruct']['name'].value[0].item()].name)
# this only gets the first array member / character:
print (f[f['digitStruct']['name'].value[0].item()].value[0][0])
print (f[f['digitStruct']['name'].value[0].item()].value[0][0].tostring().decode('ascii'))
# this gets the entire array / filename:
print (f[f['digitStruct']['name'].value[0].item()][:])
print (f[f['digitStruct']['name'].value[0].item()][:].tostring().decode('ascii'))
每种方法的最后2个打印语句的输出相同:
[[ 49]
[ 46]
[112]
[110]
[103]]
1.png