足迹分享 http://blog.sciencenet.cn/u/weiw7 客观,平静。

博文

高速camera数据文件读取

已有 4284 次阅读 2011-6-9 09:19 |系统分类:科研笔记

    最近新买了一台一百万帧每秒(1Mega-FPS)的高速camera。速度的提升就意味着数据量的增加。它现在的工作模式是将采集的数据先存放在自身的16G内存中,然后以1GByte/min的速度将内存的数据作为一个raw文件写入硬盘。默认的后续处理方法是将raw文件转换为单独的图片文件(比如tiff等)。再用matlab读取tiff文件进行数据分析和处理。百万帧级的高采样率导致了图片文件的数目通常高达数十万张,windows操作系统对这样大量文件的读写操作效率都极低,很不方便。如果能够直接将raw文件转换为格式清晰的.mat文件的话,这一切就能方便许多。
    想要进行格式转换,首先需要知道的就是raw文件的数据格式。在联系厂家获得了该文件的数据格式以后,就能比较容易地完成这一raw2mat的格式转换了。在这一过程中有一些细节和体会,记录如下。
1)Signed integer / floating point 数据类型的存储
hex2dec, oct2dec, bin2dec等命令都只适用于unsigned integer的处理。如果数据类型为long/short/float/double的话,就有特殊的处理方法。略举两例,供举一反三。
Value (Dec)        Format         Data(Hex)
-179590            Long           FFFD427A  
计算方法: 从十六进制到十进制  -->  hex2dec('FFFD427A') - 2^32 = -179590
           从十进制到十六进制  -->  dec2hex(2^32 + (-179590)) = 'FFFD427A'
double占用8个字节。前四个字节表示整数部分,按照上述long格式处理;后四个字节表示小数部分,第N位的权重按照(2^-N)处理。计算方法为dec2hex('FFFD427A')/2^32.
 
2)TIME64格式
这是一种表示当前系统时间的方法。通常的时间存储方式为直接记录年月日时分秒星期几等信息。TIME64则是表示UNIX时间,它共有8个字节64位。前32位表示当前时刻与1970年1月1日零时(UTC)的时间间隔(以秒记),后32位则类似于小数部分。计算方法类似于double数据类型。这一表示方法所能处理的时刻范围自1901年12月13日至2038年1月19日。
 
3)逆顺序排列
这一数据文件有一个奇怪的特点,就是在数据范围内逆顺序排列。比如整个文件的第5~8字节表示-179590,已经计算出来对应的十六进制数为FFFD427A。但是文件的第5~8字节却分别是:7A 42 FD FF。目前尚不清楚这一逆序的原因,也不知道是否是普遍的做法,但现象值得注意。
 
4)大体的数据排列方式是:
头文件区:记录着文件的基本信息,比如采样时刻,图片大小及数目,camera设置等等。
索引区:记录着每一帧图片的offset,即其第一个像素点在整个文件中的位置。
数据区:顺序记录着每一帧图片的强度信息。
 
5)注意addpath ('File --> Set path')。如果想让自己的函数成为库函数,需要进行set path操作。注意文件名不要太普通,否则容易重名。
 
========= 以下是源文件,备查=========
% function A = raw2mat()
[fname,fpath] = uigetfile('D:My documentsMATLABasuCamera*.raw','Pick an RAW file.');
fid = fopen([fpath '' fname]);
A = fread(fid);
A = A';

%%Acquire File Information
x = sum(A(49:52).*[1 2^8 2^16 2^24]); %Width of image;
y = sum(A(53:56).*[1 2^8 2^16 2^24]); %Length of image;
z = sum(A(21:24).*[1 2^8 2^16 2^24]); %Number of images.
[lyear,lmonth,lday] = unixsecs2date(sum(A(41:44).*[1 2^8 2^16 2^24]));
fprintf('=========== RAW file information: =========n');
fprintf('====Captured on %d-%d-%d.n====Size: %dx%dx%d.n',lyear,lmonth,lday,x,y,z);
 
%%Acquire Index information for each image
B = zeros(x,y,z,'uint16');
index0 = sum(A(33:36).*[1 2^8 2^16 2^24]); %The offset of a block that stores the offsets of each image.
index_matrix = reshape(A(index0+1:index0+8*z),8,z)';
index1 = index_matrix * [1;2^8;2^16;2^24;0;0;0;0] + 9;
t = cputime;
 
%%Acquire Image data
for i = 1:z
    B(:,:,i) = uint16(flipud(reshape(reshape(A(index1(i):index1(i)+x*y*2-1),2,x*y)'*[1;2^8],x,y)'))';
end
t0 = cputime -t;
imagesc(B(:,:,1))


https://wap.sciencenet.cn/blog-567441-453179.html

上一篇:Patch clamping 读书笔记
下一篇:TTL信号的采集
收藏 IP: 149.169.132.*| 热度|

1 田灿荣

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...
扫一扫,分享此博文

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-5-19 03:10

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部