- Dataset ใช้จัดเก็บ multi-dimensional array และข้อมูลต้องเป็น homogeneous data type
- Groups เป็น data container ที่บรรจุได้ทั้ง datasets หรือ group
H5Py [2][3] คือ python package ที่ใช้ interface กับ HDF5 ที่ทำงานในระดับ low level สามารถใช้งานร่วมกับ Numpy เป็นอย่างดี การติดตั้งทำได้สองทาง คือ
python3 -m pip install h5py
กรณีที่ใช้ conda
conda install h5py
การบันทึกข้อมูล 1 dataset
import numpy as np
import h5py
#create 2 dimensiondummy data
dummy_data = np.random.randint(5,size=(10,10))
#create hdf file and store data on it
with h5py.File('random.hdf5', 'w') as f:
dset = f.create_dataset("demo_dataset", data=dummy_data)
ข้อมูลถูกบันทึกลงไฟล์ด้วย key ชื่อ "demo_dataset" ซึ่งจะถูกใช้อ้างอิงในการอ่านข้อมูล
import numpy as np
import h5py
with h5py.File('random.hdf5', 'r') as f:
data = f['demo_dataset']
print(data[:1,:])
ในกรณีที่ไม่ทราบว่าไฟล์ข้อมูลมี key อะไรบ้าง สามารถค้นหาด้วย function keys()
import numpy as np
import h5py
with h5py.File('random.hdf5', 'r') as f:
for key in f.keys():
print(key)
การบันทึกข้อมูลมากกว่า 1 dataset
import numpy as np
import h5py
#create dummy data
dummy_data_1 = np.random.randint(5,size=(10,10))
dummy_data_2 = np.random.randint(10,size=(5,5))
#create hdf file and store data on them
with h5py.File('multiple_dataset.hdf5', 'w') as f:
dset1 = f.create_dataset("dataset_1", data=dummy_data_1)
dset2 = f.create_dataset("dataset_2", data=dummy_data_2)
import numpy as np
import h5py
with h5py.File('multiple_dataset.hdf5', 'r') as f:
data_1 = f['dataset_1']
data_2 = f['dataset_2']
print(data1)
print(data2)
การกำหนด data type
ดูเรื่อง data type จาก http://docs.h5py.org/en/latest/faq.html และ https://docs.scipy.org/doc/numpy/reference/generated/numpy.dtype.html h5py ใช้ data type และสัญญลักษณ์เดียวกับ Numpy
import numpy as np
import h5py
#create dummy data
dummy_data_1 = np.random.randint(5,size=(10,10))
dummy_data_2 = np.random.randint(10,size=(5,5))
#create hdf file and store data on them
with h5py.File('multiple_dataset.hdf5', 'w') as f:
dset1 = f.create_dataset("dataset_1", data=dummy_data_1,dtype=np.int8)
dset2 = f.create_dataset("dataset_2", data=dummy_data_2,dtype=np.int8)
การกำหนด Group
ถ้าเทียบ dataset เป็นไฟล์ข้อมูลแล้ว group ก็เหมือนกับ folder หรือ directory ที่เก็บไฟล์ข้อมูลที่สอดคล้องกัน
เขียนข้อมูลลงไฟล์
import numpy as np
import h5py
#create dummy data
dummy_data_1 = np.random.randint(5,size=(10,10),dtype=np.int8)
dummy_data_2 = np.random.randint(10,size=(5,5),dtype=np.int8)
#create hdf file and store data on them
with h5py.File('group_demo.hdf5', 'w') as f:
g10 = f.create_group("group_10")
g11 = g10.create_group("group_11")
data_10 = g10.create_dataset('data_10',data=dummy_data_1)
data_11 = g11.create_dataset('data_11',data=dummy_data_2)
การอ่านข้อมูลจากไฟล์
import numpy as np
import h5py
#create hdf file and store data on them
with h5py.File('group_demo.hdf5', 'r') as f:
data_10 = f['group_10/data_10']
data_11 = f['group_10/group_11/data_11']
print(data_10[0])
print(data_11[0])
หากไม่ทราบ key หรือโครงสร้าง
import numpy as np
import h5py
def get_node_name(name):
print(name)
#create hdf file and store data on them
with h5py.File('group_demo.hdf5', 'r') as f:
f.visit(get_node_name)
การ resize dataset
ในกรณีที่ไม่สามารถกำหนดได้ว่าจะต้องการบันทึกข้อมูลจำนวนมากน้อยเท่าไหร่ h5py อนุญาตให้ทำการปรับขนาดของ dataset เพื่อเพิ่มจำนวน element ได้ (append data)
import numpy as np
import h5py
from PIL import Image
class ROI() :
def __init__(self,x1,y1,x2,y2):
self.x1 = x1
self.y1 = y1
self.x2 = x2
self.y2 = y2
def get_value(self):
return (self.x1,self.y1,self.x2,self.y2)
def parse_pts(pts_file):
coords=[]
with open(pts_file,"r") as f :
i = 1
for line in f :
if i < 3 :
i = i + 1
continue
if "{" in line or "}" in line :
continue
#split coordinate
p = line.split(" ")
x = float(p[0].strip())
y = float(p[1].strip())
coords.append([x,y])
return np.array(coords)
def crop_face(coords,img_file,pad=5):
img = Image.open(img_file)
min_x = img.size[0]
min_y = img.size[1]
max_x = 0.
max_y = 0.
for coord in coords :
if coord[0] < min_x :
min_x = coord[0]
if coord[1] < min_y :
min_y = coord[1]
if coord[0] > max_x :
max_x = coord[0]
if coord[1] > max_y :
max_y = coord[1]
min_x -= pad
min_y -= pad
max_x += pad
max_y += pad
w = max_x - min_x
h = max_y - min_y
if w > h :
dif = w - h
#expand y axis
min_y -= dif/2
max_y += dif/2
if w < h :
dif = h - w
#expand x axis
min_x -= dif/2
max_x += dif/2
#crop_area = (min_x , min_y , max_x ,max_y )
crop_area = ROI(min_x , min_y,max_x ,max_y )
#face = img.crop(crop_area)
face = img.crop(crop_area.get_value())
rs_face = face.resize((128,128),Image.ANTIALIAS)
return np.array(rs_face)
def write_data(img_file,pts_file,mode='w'):
land_mark = parse_pts(pts_file)
face_img = crop_face(land_mark,img_file,pad=5)
if mode=='w':
with h5py.File('resizable_demo.hdf5', 'w') as f:
im = f.create_dataset("image",(1,128,128,3),maxshape=(5000,128,128,3 ),dtype=np.uint8)
lb = f.create_dataset("labeled",(1,68,2),maxshape=(5000,68,2 ))
im[-1] = face_img
lb[-1] = land_mark
elif mode == 'a':
with h5py.File('resizable_demo.hdf5', 'a') as f:
img_ds = f['image']
lb_ds = f['labeled']
img_ds.resize((img_ds.shape[0]+1,128,128,3))
lb_ds.resize((lb_ds.shape[0]+1,68,2))
img_ds[-1] = face_img
lb_ds[-1] = land_mark
def read_image():
with h5py.File('resizable_demo.hdf5', 'r') as f:
img = f['image']
for i in range(img.shape[0]):
im = Image.fromarray(img[i].astype(np.uint8),'RGB')
im.show()
if __name__ == "__main__":
img_file = "indoor_001.png"
pts_file = "indoor_001.pts"
write_data(img_file,pts_file,mode='a')
read_image()
[1] https://portal.hdfgroup.org/display/knowledge/What+is+HDF5
[2] https://www.h5py.org/
[3] http://docs.h5py.org/en/stable/
Sign up here with your email
ConversionConversion EmoticonEmoticon