matlab读.h5文件

之前用 python 给 nuswide 提取了 VGG19 特征,因为文件太大,超过 .mat 限制,存成 .h5,见 [1]。现在一个 matlab 程序要读,可以用 h5disp 查看 .h5 文件内容的结构(各个 datasets),然后用 h5read 读。

注意两点:

  • 文件名、dataset 的类型要是 char 而能是 string,否则报错。可以用 c = char(s) 将 string 转成 char
  • 好像被自动转置了一次?我当初存的时候应该是 n × d n\times d n×d 的,但读出来的时候变成 d × n d\times n d×n 了(不知道是 h5py[1] 在存的时候自己转了,还是 matlab 读的时候自己转的)

Code

% "双"引号 是 string,会报错
% F = "datasets/nuswide-tc10/images.nuswide.vgg19.4096d.h5";
% '单'引号 是 char(数组),可以
F = 'datasets/nuswide-tc10/images.nuswide.vgg19.4096d.h5';

% 打印文件内结构
h5disp(F);

% 读
images = h5read(F, '/images');  % dataset name 也要用****引号 char
fprintf("images:"), disp(size(images));  % (4096, 269648)
  • 输出
HDF5 images.nuswide.vgg19.4096d.h5 
Group '/' 
    Dataset 'images' 
        Size:  4096x269648
        MaxSize:  4096x269648
        Datatype:   H5T_IEEE_F32LE (single)
        ChunkSize:  []
        Filters:  none
        FillValue:  0.000000

images:        4096      269648

References

  1. h5py存取简例
  2. Importing HDF5 Files
  3. 利用matlab读取.h5文件内容
<think>我们需要从文件名中提取时间信息。观察文件名格式:`raw _0. 20250710081107. 340462. h5`,其中时间信息部分为`20250710081107`,这表示2025年07月10日08时11分07秒。但是注意,文件名中还有空格和点,我们需要解析出时间字符串。 我们可以使用正则表达式来提取时间字符串。时间字符串的格式是14位数字(年月日时分秒)。在MATLAB中,我们可以使用正则表达式匹配14位连续数字。 修改步骤1中解析时间戳的部分: 原代码: [~, name] = fileparts(fileList(fidx).name); timeStamps(fidx) = datenum(name, 'yyyymmdd_HHMMSS'); 新文件名格式下,我们需要从文件名中提取14位数字字符串,然后将其转换为datenum。注意,datenum函数支持将字符串转换为日期数字,但需要指定格式。14位数字的格式为'yyyymmddHHMMSS'(注意没有下划线)。 修改为: [~, name] = fileparts(fileList(fidx).name); % 使用正则表达式匹配14位数字 timeStr = regexp(name, '\d{14}', 'match'); if ~isempty(timeStr) timeStamps(fidx) = datenum(timeStr{1}, 'yyyymmddHHMMSS'); else error('在文件名 %s 中未找到时间信息', fileList(fidx).name); end 另外,注意文件名中可能有空格,我们使用fileparts得到的基本文件名是完整的(包括空格),所以正则表达式匹配时要注意。 完整修改后的步骤1代码: ```matlab %% 步骤1: 批量读取H5文件 fileList = dir(fullfile(dataDir, filePattern)); numFiles = numel(fileList); timeStamps = zeros(numFiles, 1); % 存储时间戳 % 预分配空间-时间矩阵 (时间×空间) spatialTemporalMatrix = zeros(numFiles, 1280); % 并行读取处理 (需要Parallel Computing Toolbox) parfor fidx = 1:numFiles % 从文件名解析时间戳 (使用正则表达式提取14位连续数字) [~, name] = fileparts(fileList(fidx).name); % 匹配14位连续数字 timeStr = regexp(name, '\d{14}', 'match'); if ~isempty(timeStr) timeStamps(fidx) = datenum(timeStr{1}, 'yyyymmddHHMMSS'); else error('在文件名 %s 中未找到时间信息', fileList(fidx).name); end % 读取H5数据 filePath = fullfile(dataDir, fileList(fidx).name); data = h5read(filePath, '/measurement'); % 假设数据集路径为/measurement % 计算空间能量特征 (每行RMS) spatialTemporalMatrix(fidx, :) = rms(data, 2)'; end ``` 这样,即使文件名中有其他字符,我们也能正确提取时间信息。 注意:如果文件名中有多个14位数字,我们只取第一个匹配的。根据你的描述,每个文件名中应该只有一个时间字符串。 其他步骤不变。 另外,在结果输出部分,我们使用`datestr`将时间戳转换为字符串时,可以指定格式,例如:`datestr(timeStamps(floor(bb(2))), 'yyyy-mm-dd HH:MM:SS')`,这样输出更易。 如果遇到没有匹配到时间字符串的文件,程序会报错。如果希望跳过错误文件,可以将错误改为警告并跳过,但这样可能会影响时间序列的连续性。因此,建议确保所有文件都包含时间信息。 所以,完整的代码修改点就是步骤1中时间戳的提取方式。 如果实际文件名中的时间格式不是14位数字(比如有小数点或其他),则需要调整正则表达式。但根据你提供的例子,是14位整数。 另外,注意文件名中的时间信息精确到秒,而我们的数据是每秒一个文件,所以每个文件的时间戳是整秒。 现在,代码应该可以处理你提供的文件名格式了。</think>### 解决方案:处理非标准时间格式的文件名 以下是针对非标准文件名格式的完整解决方案,使用正则表达式提取时间信息并处理数据: ```matlab %% 参数设置 dataDir = 'path/to/h5/files'; % H5文件存储目录 filePattern = '*.h5'; % 文件匹配模式 spacing = 0.4; % 空间采样间隔(米) timeResolution = 1/8000; % 时间分辨率(秒) thresholdFactor = 5; % 事件检测阈值因子 %% 步骤1: 批量读取H5文件并解析时间戳 fileList = dir(fullfile(dataDir, filePattern)); numFiles = numel(fileList); timeStamps = NaT(numFiles, 1); % 存储时间戳 (NaT表示未定义时间) % 预分配空间-时间矩阵 spatialTemporalMatrix = zeros(numFiles, 1280); % 定义时间解析函数 parseTime = @(name) datetime(regexp(name, '\d{14}', 'match', 'once'), ... 'InputFormat', 'yyyyMMddHHmmss', 'TimeZone', 'local'); % 并行处理文件 parfor fidx = 1:numFiles % 从文件名解析时间戳 fileName = fileList(fidx).name; try % 提取14位数字时间戳 timeStr = regexp(fileName, '\d{14}', 'match', 'once'); if isempty(timeStr) error('未找到时间戳: %s', fileName); end % 转换为datetime对象 timeStamps(fidx) = datetime(timeStr, 'InputFormat', 'yyyyMMddHHmmss', 'TimeZone', 'local'); % 读取H5数据 filePath = fullfile(dataDir, fileName); data = h5read(filePath, '/measurement'); % 计算空间能量特征 (每行RMS) spatialTemporalMatrix(fidx, :) = rms(data, 2)'; catch ME warning('文件 %s 处理失败: %s', fileName, ME.message); end end % 移除处理失败的文件 validIdx = ~isnat(timeStamps); timeStamps = timeStamps(validIdx); spatialTemporalMatrix = spatialTemporalMatrix(validIdx, :); numFiles = numel(timeStamps); % 按时间排序 [timeStamps, sortIdx] = sort(timeStamps); spatialTemporalMatrix = spatialTemporalMatrix(sortIdx, :); %% 步骤2: 时空矩阵预处理 (同之前代码) % ... [预处理代码保持不变] ... %% 步骤3: 车辆事件检测 (同之前代码) % ... [检测代码保持不变] ... %% 步骤4: 时空事件聚类 (同之前代码) % ... [聚类代码保持不变] ... %% 步骤5: 结果可视化与输出 % 显示检测到的事件 disp('===== 检测到的车辆事件 ====='); for i = 1:numel(validEvents) e = validEvents(i); fprintf('事件 %d:\n', i); fprintf(' 时间范围: %s 到 %s\n', e.StartTime, e.EndTime); fprintf(' 位置范围: %.1f米 到 %.1f米\n', e.StartLocation, e.EndLocation); fprintf(' 中心时间: %s\n', e.CenterTime); fprintf(' 中心位置: %.1f米\n', e.CenterLocation); fprintf(' 持续时间: %.2f秒\n', e.Duration); fprintf(' 空间跨度: %.1f米\n\n', e.SpaceLength); end % 创建时间轴用于绘图 timePoints = timeStamps(1):seconds(1):timeStamps(end); [~, timeIndices] = ismember(timeStamps, timePoints); % 时空矩阵可视化 figure('Position', [100, 100, 1200, 600]) subplot(2,1,1) imagesc(timeIndices, 1:1280, spatialTemporalMatrix') title('原始时空矩阵') xlabel('时间') ylabel('空间位置 (每点=0.4米)') datetick('x', 'HH:MM:SS', 'keeplimits', 'keepticks') colorbar subplot(2,1,2) imagesc(timeIndices, 1:1280, eventMatrix') title('检测到的车辆事件') xlabel('时间') ylabel('空间位置 (每点=0.4米)') hold on for i = 1:numel(validEvents) e = validEvents(i); startIdx = find(timeStamps >= e.StartTime, 1); endIdx = find(timeStamps <= e.EndTime, 1, 'last'); startPos = e.StartLocation / spacing + 0.5; endPos = e.EndLocation / spacing + 0.5; rectangle('Position', [startIdx, startPos, endIdx-startIdx, endPos-startPos],... 'EdgeColor', 'r', 'LineWidth', 1.5) end datetick('x', 'HH:MM:SS', 'keeplimits', 'keepticks') ``` ### 关键修改点详解 #### 1. 时间戳解析函数 ```matlab parseTime = @(name) datetime(regexp(name, '\d{14}', 'match', 'once'), ... 'InputFormat', 'yyyyMMddHHmmss', 'TimeZone', 'local'); ``` - 使用正则表达式 `\d{14}` 匹配14位连续数字(如20250710081107) - 转换为MATLAB的`datetime`类型,保留时区信息 - 示例文件名:`raw _0. 20250710081107. 340462. h5` → 提取`20250710081107` → 解析为`2025-07-10 08:11:07` #### 2. 健壮的错误处理 ```matlab try % 提取和处理代码 catch ME warning('文件 %s 处理失败: %s', fileName, ME.message); end ``` - 捕获可能的错误(如时间戳缺失、文件损坏) - 记录错误但继续处理其他文件 - 使用`warning`而非`error`保证程序继续执行 #### 3. 时间数据处理流程 ```matlab % 移除无效文件 validIdx = ~isnat(timeStamps); timeStamps = timeStamps(validIdx); % 按时间排序 [timeStamps, sortIdx] = sort(timeStamps); spatialTemporalMatrix = spatialTemporalMatrix(sortIdx, :); ``` 1. 使用`NaT`(Not-a-Time)标记无效时间戳 2. 过滤掉无效文件 3. 按时间顺序排序文件,确保时间序列正确 #### 4. 可视化时间轴处理 ```matlab % 创建连续时间轴 timePoints = timeStamps(1):seconds(1):timeStamps(end); [~, timeIndices] = ismember(timeStamps, timePoints); % 绘图时使用实际时间 imagesc(timeIndices, 1:1280, spatialTemporalMatrix') datetick('x', 'HH:MM:SS', 'keeplimits', 'keepticks') ``` - 创建连续的时间轴(每秒一个点) - 使用`datetick`将数值轴转换为易的时间格式 - `keeplimits`和`keepticks`保持坐标轴范围不变 ### 处理流程说明 1. **文件扫描**:获取所有H5文件列表 2. **时间戳提取**: - 使用正则表达式匹配14位数字时间戳 - 转换为`datetime`对象 - 处理可能的格式错误 3. **数据读取**: - 并行读取H5文件 - 计算每行的RMS值作为特征 4. **数据清洗**: - 移除无效时间戳的文件 - 按时间顺序排序 5. **事件检测**: - 时空矩阵预处理(去噪、平滑) - 基于统计阈值检测事件 - 时空聚类识别车辆轨迹 6. **结果输出**: - 文本显示检测到的车辆事件 - 可视化时空矩阵和检测结果 ### 注意事项 1. **时间格式**:代码假设时间戳为14位数字(年月日时分秒) 2. **文件命名**:支持示例中的`raw _0. 20250710081107. 340462. h5`格式 3. **错误处理**:自动跳过格式错误的文件并记录警告 4. **时区处理**:使用`'TimeZone', 'local'`保留本地时区信息 5. **内存优化**:处理前确保有足够内存(7200×1280矩阵约70MB)
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值