从时间戳图像对创建 HDF5 数据集的最佳方法是什么?

问题描述 投票:0回答:1

我必须从带有 C 语言时间戳的图像创建 HDF5 文件。我事先不知道我将获得多少对,因此固定大小的数据集不是一个选项。

我的数据样本是一个大型 (~ 12 x 10^6) uint8_t 数组,除了 uint64_t 时间戳之外,还包含图像的扁平版本。为了更好地理解,我添加了我的解决方案的 C 等效项。

我可以想到两种可能的解决方案,但我对这两种方案都有问题。我希望在这里得到一些指示:

版本1

我创建了一个初始大小为 0 的二维 uint8_t 数据集。我在每次迭代期间扩展数据集并将图像数据写入 HDF5 文件。在这里,我计划将时间戳放入数据集属性中相应的 uint64_t 数组中。问题是我发现无法随时随地扩展属性数组,因此我必须将所有时间戳保存在临时数组中,然后将其添加到属性中。这不仅消耗内存,而且在崩溃的情况下,我只剩下图像但没有时间戳。

uint8_t images[][IMG_BUF_SIZE];

(as attribute:)
uint64_t timestamps[];

版本2

我尝试使用复合数据类型,以便获得复合类型样本的一维数组。每个样本都包含 uint64_t 时间戳和大型 uint8_t 数组。我遇到的问题是,我在 HDF5 的文档中读到,在复合数据类型中,不建议使用“大数组”。

typedef struct 
{
    uint64_t timestamp;
    uint8_t payload[IMG_BUF_SIZE];
} time_image_t;

time_image_t array[];

如何做到这一点?这些类型的数据集应该很常见,但我无法找到执行此操作的标准方法。

谢谢!

arrays c file append hdf5
1个回答
0
投票

解决此用例的最佳方法是使用 HDF5 复合数据集(包含两个成员:

timestamp
payload
),就像上面版本 2 中所述。

此外,数据集必须是可扩展的,以便它可以根据您将获得的数据大小(事先未知)进行增长。为了避免覆盖数据集中已存储的数据,在将数据写入其中时,您需要使用选择(超板或点)。

解决您的用例的一种方法可以是通过在 C 中使用HDFql,如下所示(请注意,在本例中,我只是向数据集添加了两个“行” - 您可以有一个循环添加尽可能多的“行” “根据需要解决您的想法):

#include <stdio.h>
#include <stddef.h>
#include "HDFql.h"

#define IMG_BUF_SIZE 3

typedef struct
{
    uint64_t timestamp;
    uint8_t payload[IMG_BUF_SIZE];
}time_image_t;

int main(int argc, char *argv[])
{

    // declare variables
    char script[1024];
    time_image_t data;

    // create HDF5 file named 'data.h5' and use (i.e. open) it
    hdfql_execute("create and use file data.h5");

    // prepare script to create an extendable dataset named 'dset' of data type compound (containing two members named 'timestamp' and 'payload')
    sprintf(script, "create dataset dset as compound(timestamp as unsigned bigint offset %d, payload as unsigned tinyint(%d) offset %d)(unlimited) size %d", offsetof(time_image_t, timestamp), IMG_BUF_SIZE, offsetof(time_image_t, payload), sizeof(time_image_t));

    // execute script
    hdfql_execute(script);

    // register variable 'data' for subsequent usage (by HDFql)
    hdfql_variable_register(&data);

    // populate variable 'data' with some values
    data.timestamp = 123;
    data.payload[0] = 10;
    data.payload[1] = 20;
    data.payload[2] = 30;

    // insert data into last row of dataset 'dset' thanks to a point selection
    hdfql_execute("insert into dset[-1] values from memory 0");

    // populate variable 'data' with more values
    data.timestamp = 456;
    data.payload[0] = 75;
    data.payload[1] = 85;
    data.payload[2] = 95;

    // alter (i.e. change) dimension of dataset 'dset' to +1
    hdfql_execute("alter dimension dset to +1");

    // insert data into last row of dataset 'dset' thanks to a point selection
    hdfql_execute("insert into dset[-1] values from memory 0");

    // unregister variable 'data' as it is no longer used (by HDFql)
    hdfql_variable_unregister(&data);

    // close HDF5 file 'data.h5'
    hdfql_execute("close file");

    return 0;

}
© www.soinside.com 2019 - 2024. All rights reserved.