hdf5 的使用

可以重点参考这篇博客中的内容。

python 上的使用

import h5py

文件创建和打开

import h5py
# 以写入方式打开文件
# r  只读,文件必须已存在
# r+ 读写,文件必须已存在
# w  新建文件,若存在覆盖
# w- 或x,新建文件,若存在报错
# a  如存在则读写,不存在则创建(默认)
file = h5py.File('file.h5', 'w')
file.close()

# 打开文件
file_open = h5py.File('file.h5', 'r+')
file_open.close()

保存hdf5文件

# Write numpy array data and label to h5_filename
def save_h5(h5_filename, data, label, data_dtype='uint8', label_dtype='uint8'):
	'''
	svae_h5 用于创建并存储h5文件
	'''
    h5_fout = h5py.File(h5_filename)
    h5_fout.create_dataset(
            'data', data=data,
            compression='gzip', compression_opts=4,
            dtype=data_dtype)
    h5_fout.create_dataset(
            'label', data=label,
            compression='gzip', compression_opts=1,
            dtype=label_dtype)
    h5_fout.close()

'''存储str数据'''
import h5py
import numpy as np
dt = h5py.special_dtype(vlen=str)
data = np.array([['123'],['456']])
with h5py.File('testdict.h5','w') as f:
    ds = f.create_dataset('test_dict', data.shape , dtype=dt)
    ds[:] = data
    #f.create_dataset('test_dict', data.shape , dtype=dt,data=data)	#对于字符串,这么操作会出现错误!!!

读取hdf5文件

# Read numpy array data and label from h5_filename
def load_h5(h5_filename):
	'''
	load_h5 用来加载 h5 文件
	'''
    f = h5py.File(h5_filename)
    data = f['data'][:]
    label = f['label'][:]
    return (data, label)

c++ 上的使用

保存hdf5文件(2维数组)

#include <iostream>
#include <string>
#include "hdf5.h"
/*写入程序*/
int main(int argc, char* argv[]) {
	// 为矩阵matrix进行内存分配,这里采用了技巧分配了连续内存
	int rows = 10;
	int columns = 8;
	double* data_mem = new double[rows*columns];
	double** matrix = new double*[rows];
	for (int i = 0; i < rows; i++)
		matrix[i] = data_mem + i*columns;
	// 为matrix矩阵填入数据,元素个数的整数部分为行号,分数部分为列号
	for (int r = 0; r < rows; r++) {
		for (int c = 0; c < columns; c++) {
			matrix[r][c] = r + 0.01*c;
		}
	}

	// 打开HDF5文件
	hid_t file_id;
	herr_t status;
	file_id = H5Fcreate("my_file.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);

	// 创建数据集的metadata中的dataspace信息项目
	unsigned rank = 2;
	hsize_t dims[2];
	dims[0] = rows;
	dims[1] = columns;
	hid_t dataspace_id;  // 数据集metadata中dataspace的id
	// dataspace_id = H5Screate_simple(int rank, 空间维度
	//              const hsize_t* current_dims, 每个维度元素个数
	//                    - 可以为0,此时无法写入数据
	//                  const hsize_t* max_dims, 每个维度元素个数上限
	//                    - 若为NULL指针,则和current_dim相同,
	//                    - 若为H5S_UNLIMITED,则不舍上限,但dataset一定是分块的(chunked).
	dataspace_id = H5Screate_simple(rank, dims, NULL);

	// 创建数据集中的数据本身
	hid_t dataset_id;    // 数据集本身的id
	// dataset_id = H5Dcreate(loc_id, 位置id
	//              const char *name, 数据集名
	//                hid_t dtype_id, 数据类型
	//                hid_t space_id, dataspace的id
	//             连接(link)创建性质,
	//                 数据集创建性质,
	//                 数据集访问性质)
	dataset_id = H5Dcreate(file_id, "/dset", H5T_NATIVE_DOUBLE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

	// 将数据写入数据集
	// herr_t 写入状态 = H5Dwrite(写入目标数据集id,
	//                               内存数据格式,
	//                       memory_dataspace_id, 定义内存dataspace和其中的选择
	//                          - H5S_ALL: 文件中dataspace用做内存dataspace,file_dataspace_id中的选择作为内存dataspace的选择
	//                         file_dataspace_id, 定义文件中dataspace的选择
	//                          - H5S_ALL: 文件中datasapce的全部,定义为数据集中dataspace定义的全部维度数据
	//                        本次IO操作的转换性质,
	//                          const void * buf, 内存中数据的位置
	status = H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, matrix[0]);

	// 关闭dataset相关对象
	status = H5Dclose(dataset_id);
	status = H5Sclose(dataspace_id);

	// 关闭文件对象
	status = H5Fclose(file_id);

	// 释放动态分配的内存
	delete[] matrix;
	delete[] data_mem;

	return 0;
}

保存hdf5文件(4维数组)

void vector2hdf5(vector<Mat> &data, Mat &label, const char * filepath, string dataset1, string dataset2)
{
	int data_rows = data.size();
	int data_channel = 15;
	int image_width = 96;
	int image_height = 96;
 
	int label_cols = label.cols;
	int label_rows = label.rows;
	hid_t file_id;
	herr_t status;
	file_id = H5Fcreate(filepath, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
 
	int rank_data = 4, rank_label = 2;
 
	hsize_t dims_data[4];
	hsize_t dims_label[2];
 
	dims_data[0] = data_rows;
	dims_data[1] = data_channel;
	dims_data[2] = image_height;
	dims_data[3] = image_width;
 
	dims_label[0] = label_rows;
	dims_label[1] = label_cols;
 
 
	hid_t data_id = H5Screate_simple(rank_data, dims_data, NULL);
	hid_t label_id = H5Screate_simple(rank_label, dims_label, NULL);
 
 
	hid_t dataset_id = H5Dcreate2(file_id, dataset1.c_str(), H5T_NATIVE_FLOAT, data_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
	hid_t labelset_id = H5Dcreate2(file_id, dataset2.c_str(), H5T_NATIVE_INT, label_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
 
	cout << data[0].channels() << "  "<< data[0].rows<< "  "<< data[0].cols<< endl;
	float* data_mem = new float[data_rows * data_channel * image_height * image_width];
	float **array_data = new float*[data_rows];
	for (int j = 0; j < data_rows; j++) {
		array_data[j] = data_mem + j * data_channel * image_height * image_width;//非常有必要,因为要让array_data占用的内存是连续的!!!
		//for (int i = 0; i < image_height; i++)
		//{
		//	float * ptr = data[j].ptr<float>(i);
		//	for (size_t k = 0; k < data_channel * image_width; k++)
		//	{
		//		array_data[j][i * data_channel * image_width + k] = ptr[k];
		//		//cout << ptr[k] << endl;
		//	}
		//}
        //这儿 就是 文中提到的坑 H5 的保存数据顺序更 Mat 的不一样
        //H5:[num][15][96][96]  Mat:[96][96][15] 所以保存时 一定做好转换
		for (int n = 0; n < 15; n++)
		{
			for (int i = 0; i < image_height; i++)
			{
				float * ptr = data[j].ptr<float>(i);
				for (size_t k = 0; k < image_width; k++)
				{
					array_data[j][n*image_width *image_height +i*image_width + k] = ptr[k*data_channel + n];
				}
			}
		}
	}
	
	int * label_mem = new int[label_rows*label_cols];
	int **array_label = new int*[label_rows];
	for (int j = 0; j < label_rows; j++) {
		array_label[j] = label_mem + j*label_cols;
		for (int i = 0; i < label_cols; i++)
		{
			array_label[j][i] = (int)label.at<int>(j, i);
		}
	}
 
	status = H5Dwrite(dataset_id, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, array_data[0]);
	status = H5Dwrite(labelset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, array_label[0]);
 
	//关闭
 
	status = H5Sclose(data_id);
	status = H5Sclose(label_id);
 
	status = H5Dclose(dataset_id);
	status = H5Dclose(labelset_id);
 
	status = H5Fclose(file_id);
 
	delete[] array_data;
	delete[] array_label;
}

其中还特意测试了一下上面那样给数组分配连续内存的方式,会有什么样的效果:

	float * p = new float[5 * 4];
	float **pp = new float*[5];
	for (int i = 0; i < 5; i++){
		pp[i] = p + i * 4;//这样会让pp[i]均为 float[5*4]的数组,不过也没有办法,暂时想不到在连续的float[5*4]内存块上,将其分成5个float[4]的内存块。
	}
	for (int i = 0; i < 5; i++)
	{
		for (int j = 0; j < 4; j++){
			pp[0][i * 4 + j] = 0;
		}
	}
	float monitor_0 = pp[0][0];
	float monitor_1 = pp[1][0];
	float monitor_2 = pp[2][0];
	float monitor_3 = pp[3][0];
	float monitor_4 = pp[4][0];
	float out_monitor_1 = pp[1][19];
	float out_monitor_2 = pp[2][19];
	float out_monitor_3 = pp[3][19];
	float out_monitor_4 = pp[4][19];

	for (int i = 0; i < 5; i++)
	{
		for (int j = 0; j < 4; j++){
			pp[1][i * 4 + j] = 1;
		}
	}
	monitor_0 = pp[0][0];
	monitor_1 = pp[1][0];
	monitor_2 = pp[2][0];
	monitor_3 = pp[3][0];
	monitor_4 = pp[4][0];
	out_monitor_1 = pp[1][19];
	out_monitor_2 = pp[2][19];
	out_monitor_3 = pp[3][19];
	out_monitor_4 = pp[4][19];

	for (int i = 0; i < 5; i++)
	{
		for (int j = 0; j < 4; j++){
			pp[2][i * 4 + j] = 2;
		}
	}
	monitor_0 = pp[0][0];
	monitor_1 = pp[1][0];
	monitor_2 = pp[2][0];
	monitor_3 = pp[3][0];
	monitor_4 = pp[4][0];
	out_monitor_1 = pp[1][19];
	out_monitor_2 = pp[2][19];
	out_monitor_3 = pp[3][19];
	out_monitor_4 = pp[4][19];

	for (int i = 0; i < 5; i++)
	{
		for (int j = 0; j < 4; j++){
			pp[3][i * 4 + j] = 3;
		}
	}
	monitor_0 = pp[0][0];
	monitor_1 = pp[1][0];
	monitor_2 = pp[2][0];
	monitor_3 = pp[3][0];
	monitor_4 = pp[4][0];
	out_monitor_1 = pp[1][19];
	out_monitor_2 = pp[2][19];
	out_monitor_3 = pp[3][19];
	out_monitor_4 = pp[4][19];
	for (int i = 0; i < 5; i++)
	{
		for (int j = 0; j < 4; j++){
			pp[4][i * 4 + j] = 4;
		}
	}
	monitor_0 = pp[0][0];
	monitor_1 = pp[1][0];
	monitor_2 = pp[2][0];
	monitor_3 = pp[3][0];
	monitor_4 = pp[4][0];
	out_monitor_1 = pp[1][19];
	out_monitor_2 = pp[2][19];
	out_monitor_3 = pp[3][19];
	out_monitor_4 = pp[4][19];	

读取hdf5文件

/*读出程序*/
#include <iostream>
#include <string>
#include "hdf5.h"
int main(int argc, char* argv[]) {
	// 为矩阵matrix进行内存分配,这里采用了技巧分配了连续内存
	int rows = 10;
	int columns = 8;
	double* data_mem = new double[rows*columns];
	double** matrix = new double*[rows];
	for (int i = 0; i < rows; i++)
		matrix[i] = data_mem + i*columns;

	// 打开HDF5文件
	hid_t file_id;
	herr_t status;
	file_id = H5Fopen("my_file.h5", H5F_ACC_RDWR, H5P_DEFAULT);

	// 创建数据集中的数据本身
	hid_t dataset_id;    // 数据集本身的id
	// dataset_id = H5Dopen(group位置id,
	//                 const char *name, 数据集名
	//                    数据集访问性质)
	dataset_id = H5Dopen(file_id, "/dset", H5P_DEFAULT);

	// 将数据写入数据集
	// herr_t 读取状态 = H5Dread(写入目标数据集id,
	//                              内存数据类型,
	//                       memory_dataspace_id, 定义内存dataspace和其中的选择
	//                          - H5S_ALL: 文件中dataspace用做内存dataspace,file_dataspace_id中的选择作为内存dataspace的选择
	//                         file_dataspace_id, 定义文件中dataspace的选择
	//                          - H5S_ALL: 文件中datasapce的全部,定义为数据集中dataspace定义的全部维度数据
	//                        本次IO操作的转换性质,
	//                          const void * buf, 内存中接受数据的位置
	status = H5Dread(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, matrix[0]);

	// 关闭dataset相关对象
	status = H5Dclose(dataset_id);

	// 关闭文件对象
	status = H5Fclose(file_id);

	// 释放动态分配的内存
	delete[] matrix;
	delete[] data_mem;

	return 0;
}

matlab上使用

没有.h5文件

hdf5write('XXX.h5','/Match_Message',match_message_by_gore);%自动创建'XXX.h5'文件,并写入数组;如果'XXX.h5'文件已经存在,则覆盖
hdf5write('XXX.h5','/Rot_Mat',Rot_by_gore,'WriteMode', 'append');%在'XXX.h5'文件,里面继续写入数组

原有.h5上接着写入数组

之前试过几种写入数组,但是会出现写入数组后,原文件中的数组就被覆盖的情况,当时用了下面的代码,发现还可以用。

dset_details.Location = '/Registration_idx_patch';
dset_details.Name = 'Registration_idx_patch';

% h5create(hdf5_file_name,'/Registration_idx_patch',[size(X,1),2],'WriteMode', 'append')
hdf5write(hdf5_file_name,dset_details,Registration_patch,'WriteMode', 'append');
dset_details.Location = '/Delaunay_face_node_idx';
dset_details.Name = 'Delaunay_face_node_idx';
% h5create(hdf5_file_name,'/Delaunay_face_node_idx',[size(TRI,1),size(TRI,2)])
hdf5write(hdf5_file_name,'/Delaunay_face_node_idx',TRI,'WriteMode', 'append');
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值