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

Posted

技术标签:

【中文标题】从时间戳图像对创建 HDF5 数据集的最佳方法是啥?【英文标题】:What is the best way to create a HDF5 dataset from timestamp-image-pairs?从时间戳图像对创建 HDF5 数据集的最佳方法是什么? 【发布时间】:2021-04-20 15:13:50 【问题描述】:

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

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

我可以为此想到 2 种可能的解决方案,但我对这两个都有问题。我会很感激这里的一些指示:

版本 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[];

如何做到这一点?这些类型的数据集应该很常见,但我找不到标准的方法来做到这一点。

谢谢!

【问题讨论】:

我建议您阅读 HDF5 用户指南 属性一章中的“特殊问题”部分。它说:“我们认为属性的最大大小为 64K 字节”。所以,如果你的时间图数组是 64K 字节的属性:1)在密集的属性存储中,或 2)在单独的数据集中。用户指南中有这两种技术的示例。请参阅 1.10 版指南中的第 306-308 页。 【参考方案1】:

解决此用例的最佳方法是使用 HDF5 复合数据集(包含两个成员:timestamppayload),就像上面第 2 版中所述。

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

解决用例的一种方法是在 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;


【讨论】:

以上是关于从时间戳图像对创建 HDF5 数据集的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

计算用于咖啡分类的HDF5数据集的平均值

从时间戳中提取时间分辨率以获取列中特定值的最佳方法是啥?

在android中从网络下载图像数据的最佳方法是啥

用于创建 HDF5 数据集的 4 维 c++ 数组的动态内存分配

从 Amazon Redshift UNLOAD 创建对 RFC-4180 友好的 CSV 文件的最佳方法是啥?

在项目模板中包含对我自己的程序集的引用的最佳方式是啥?