花园分享 http://blog.sciencenet.cn/u/zxczxc0417

博文

快速写入多个格式化tiff文件的matlab程序

已有 5464 次阅读 2012-3-20 00:11 |个人分类:天下大事|系统分类:观点评述|关键词:学者| 高考, 中国, 科学发展, 同学会

 最近在工作的时候需要在一个tiff文件中写入10000帧以上的内容,以前都是用了matlab自带的imwrite函数,这个函数的优点是现成又好用,可是问题是这个函数的通用性太强,速度慢的要死,即使是个很小的tiff文件也要写上十几分钟,如果又上百个这样的文件,那真是一种煎熬。这个问题主要出在tiff文件的格式本身,tiff文件中yao找到某个帧就必须要从第一帧开始,它的数据结构就像一个链表。详细信息可以参考我的博文之前两个。
为了解决这个问题,有一下几种方法:
1. 把u盘上的数据拷贝到计算机的硬盘上
2。在内存中虚拟一个硬盘
3。修改matlab的程序
4。自己编写程序加速

第一种方法很好,能加快不少速度,如果文件的个数不是很多,这个方法还是不错的。不过一个文件也要写上十几分钟,文件越长越大,耗时越多。
第二种方法只能提高一点点,基本没用。不知道为什么,即令人惊讶有令人奇怪。虚拟硬盘的读写速度比普通硬盘要快很多,有兴趣的可以去google一下。我感觉可能还是跟tiff文件的格式有关,也就是说虚拟硬盘和普通硬盘在寻地址方面的速度相当。
第三种方法很难做到,我顺着matlab的函数imwrite顺藤摸瓜一直找下去最后找到了c程序及其dll的库文件,c的脚本文件很大,很复杂,要让我修改那些不是不可能,但是我的感觉是代价会很大。
第三种方法应该说是目前为止我所能找到的最好方法。写一个文件差不多30秒吧,比十几分钟的标准时间算是快多了。
用这种方法的基本思想是,我的文件中每个帧的大小个格式完全一样,所以可以用基本的写文件函数fwrite来操作文件,那样的速度会提高很多。借此机会我也好好学习了一下tiff文件的格式,算是基本上搞懂了。于是乎制作了一个最简单的tiff文件写入函数。这个函数实际上由三个子函数构成:
make_tiff_start : 负责tiff文件的开头写入
make_tiff_mid   : 负责中间各帧的接入
make_tiff_end   : 结尾帧的写入
下面是这三个子函数的matlab代码
------------------function make_tiff_start-----------------
% write a head of tiff file
% infile is the input movie file, should be tiff format
% outfile is the output tiff file, should be tiff format
function make_tiff_start( infile,outfile);

fid1 = fopen(infile, 'r');
fid2 = fopen(outfile, 'w');

% write the image file header (IFH)
c = fread(fid1, 1,'short');
fwrite(fid2,c,'short');
fwrite(fid2,42,'short');
fwrite(fid2,8,'long');

fclose(fid1);
fclose(fid2);
------------------function make_tiff_mid-----------------
% x is just read from tiff file
% outfile is the file name for output, should be tiff
% index_frame is the index number for this frame. you must sequencely input the frames.
% That is from 1 to N
function make_tiff_mid( x, outfile, index_frame);

DirE = struct('tag',{},'type',{},'counts',{},'voffset',{});
[ImageLength ImageWidth] = size(x);
% ImageWidth   ; % kuan du
% ImageLength ; % gao du

fid2 = fopen(outfile, 'a');

% build the image file directory for new movie
direc = 11;
DirE(1).tag = 256; DirE(1).type = 3; DirE(1).counts = 1; DirE(1).voffset = ImageWidth;
DirE(2).tag = 257; DirE(2).type = 3; DirE(2).counts = 1; DirE(2).voffset = ImageLength;
DirE(3).tag = 258; DirE(3).type = 3; DirE(3).counts = 1; DirE(3).voffset = 16;
DirE(4).tag = 259; DirE(4).type = 3; DirE(4).counts = 1; DirE(4).voffset = 1;
DirE(5).tag = 262; DirE(5).type = 3; DirE(5).counts = 1; DirE(5).voffset = 1;
DirE(6).tag = 273; DirE(6).type = 4; DirE(6).counts = 1; DirE(6).voffset = 8; % need modify
DirE(7).tag = 277; DirE(7).type = 3; DirE(7).counts = 1; DirE(7).voffset = 1;
DirE(8).tag = 278; DirE(8).type = 3; DirE(8).counts = 1; DirE(8).voffset = ImageLength;
DirE(9).tag = 279; DirE(9).type = 4; DirE(9).counts = 1; DirE(9).voffset = ImageWidth*ImageLength*2;
DirE(10).tag = 284; DirE(10).type = 3; DirE(10).counts = 1; DirE(10).voffset = 1;
DirE(11).tag = 296; DirE(11).type = 3; DirE(11).counts = 1; DirE(11).voffset = 3;

% read the movie and write to my movie
i = index_frame;
fwrite(fid2,direc,'short');
DirE(6).voffset = 8 + (i-1) *( 2 + direc*12 + 4 + ImageWidth*ImageLength*2 ) + 2+direc*12+4;
for j = 1:direc
    fwrite(fid2,DirE(j).tag,'short');
    fwrite(fid2,DirE(j).type,'short');
    fwrite(fid2,DirE(j).counts,'long');
    fwrite(fid2,DirE(j).voffset,'long');
end
offset_next_IFD = 8+i*( 2 + direc*12 + 4 + ImageWidth*ImageLength*2 );
fwrite(fid2,offset_next_IFD,'long');   

% write the data of image
fwrite(fid2,x','short');   
fclose(fid2);

------------------function make_tiff_end-----------------
% input the last frame for tiff file
% x, outfile, index_frame have the same meaning in make_tiff_mid
function make_tiff_end( x, outfile, index_frame);

DirE = struct('tag',{},'type',{},'counts',{},'voffset',{});

[ImageLength ImageWidth] = size(x);
% ImageWidth   ; % kuan du
% ImageLength ; % gao du

fid2 = fopen(outfile, 'a');

% build the image file directory for new movie
direc = 11;
DirE(1).tag = 256; DirE(1).type = 3; DirE(1).counts = 1; DirE(1).voffset = ImageWidth;
DirE(2).tag = 257; DirE(2).type = 3; DirE(2).counts = 1; DirE(2).voffset = ImageLength;
DirE(3).tag = 258; DirE(3).type = 3; DirE(3).counts = 1; DirE(3).voffset = 16;
DirE(4).tag = 259; DirE(4).type = 3; DirE(4).counts = 1; DirE(4).voffset = 1;
DirE(5).tag = 262; DirE(5).type = 3; DirE(5).counts = 1; DirE(5).voffset = 1;
DirE(6).tag = 273; DirE(6).type = 4; DirE(6).counts = 1; DirE(6).voffset = 8; % need modify
DirE(7).tag = 277; DirE(7).type = 3; DirE(7).counts = 1; DirE(7).voffset = 1;
DirE(8).tag = 278; DirE(8).type = 3; DirE(8).counts = 1; DirE(8).voffset = ImageLength;
DirE(9).tag = 279; DirE(9).type = 4; DirE(9).counts = 1; DirE(9).voffset = ImageWidth*ImageLength*2;
DirE(10).tag = 284; DirE(10).type = 3; DirE(10).counts = 1; DirE(10).voffset = 1;
DirE(11).tag = 296; DirE(11).type = 3; DirE(11).counts = 1; DirE(11).voffset = 3;

% read the movie and write to my movie
i = index_frame;
% write the last one
fwrite(fid2,direc,'short');
DirE(6).voffset = 8 + (i-1) *( 2+direc*12+4 + ImageWidth*ImageLength*2 ) + 2+direc*12+4;
for j = 1:direc
    fwrite(fid2,DirE(j).tag,'short');
    fwrite(fid2,DirE(j).type,'short');
    fwrite(fid2,DirE(j).counts,'long');
    fwrite(fid2,DirE(j).voffset,'long');
end
offset_next_IFD = 0;
fwrite(fid2,offset_next_IFD,'long');

fwrite(fid2,x','short');   

fclose(fid2);

 


 



https://m.sciencenet.cn/blog-236430-549565.html

上一篇:新科CBHD高清播放机体验(图)
下一篇:TIF格式图像文件初探

2 吕喆 张骥

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

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

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

GMT+8, 2024-5-16 02:51

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部