[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: load image in different format
From: |
en254 |
Subject: |
Re: load image in different format |
Date: |
Wed, 7 Jun 2000 20:31:26 -0400 (EDT) |
On Tue, 6 Jun 2000, Joao Cardoso wrote:
> Stephen Eglen wrote:
> >
> > Hi, a similar request was made a couple of months ago. I suggested:
> >
> > ----------------------------------------------------------------------
> > > Does it exists m files to read BMP, TIFF or GIF files into Matlab ?
> > > Thanks for help
> >
> > I'm not aware of any octave/matlab implementations at the moment. If
>
> Some year ago (1996!) I have done it, using giftoppm etc to convert the
> images to ppm and scanning the resulting files in octave. Without any
> warranty (as usual) I enclose then.
>
This approach works, but unfortunately is very inefficient for
large size images.
One approach is to avoid converting to temprorary ppm files,
but to use popen to directly suck in the output from the
???top?n tools. This is a little faster and avoids having
to create and delete tmp files.
I'm including a sample imread.m to do this.
The problem with this approach is
1) It's still slow
2) It depends on the pbmtools being installed
The other approach is to write *oct files which directly
link to the appropriate graphics library, ie libjpeg,
lib(un)gif, libtiff. This is a much faster and cleaner
way to do it.
I'll submit something to octave-sources to do this for
*jpeg files. I've been planning to write something
for the other graphics files, but I haven't found the
time.
______________________________________________________________
Andy Adler, address@hidden
------file: imread.m----------
#IMREAD: read images into octave from various file formats
#
# [im]= imread(fname, fmt, imgno); -> im is a greyscale (0-255) of image in
fname
# [r,g,b]= imread(fname, fmt, imgno); -> rgb are red,green,blue (0-255)
components
# [im,map]=imread(fname, fmt, imgno); -> index and colourmap
# filename -> image to read
#
# fmt -> image storage type
# currently the following formats are supported
# if fmt is not supplied, imread will attempt to get it from the filename
#
# fmt == "img" or "octave"
# [im]= imread(fname, "img") -> read 'octave' format images
#
# fmt == "gif"
# [im]= imread(fname, "gif") -> read gif file to im,
# [im]= imread(fname, "gif", imgno ) -> read image # imgno from gif
#
# fmt == "bmp"
# [im]= imread(fname, "bmp") -> read bmp file to im,
#
# fmt == "jpg" or "jpeg"
# [im]= imread(filename, "jpg") -> read jpeg file to im,
# if rgb, compress to greyscale
# [r,g,b]= imread(fname, "jpg") -> read jpeg file to red, green, blue
# components
#
# fmt == "tiff" or "tif"
# [im,map]= imread(fname, "tif" ) -> read the 1st image from the file
#
# fmt == "libtiff"
# [im,map]= imread(fname, "libtif", imagenumber)
# get the 'imagenumber'th image from a tif format file;
# force reading a tif file using the libtiff library (slower,
# but sometimes works better than the libgr-progs version)
#
# fmt == "ppm" or "pgm" or "pnm" or "pbm" (imshow reads the
# file type from the file, so any specification is ok)
# pbm is binary, pgm is 8 bit grey, ppm is colour
# [im]= imread(filename, "pgm") -> read pnm file to im,
# if rgb, compress to greyscale
# [r,g,b]= imread(fname, "ppm") -> read pnm file to red, green, blue
# components
# $Id: imread.m,v 1.7 1999/06/10 19:18:00 aadler Exp aadler $
#TODO:
# support mulitiple image tif files
function [out1,out2,out3]= imread(filename, fmt, imgno);
save_empty_list_elements_ok= empty_list_elements_ok;
unwind_protect
empty_list_elements_ok= 1;
if (nargin == 0)
usage ("[img, map] = imread (filename,[ fmt ,[imgno] ])");
elseif (! isstr (filename))
error ("imread: expecting filename as a string");
endif
fname= file_in_path(IMAGEPATH,filename);
if isempty(fname)
error(['imread: file ' filename ' not found']);
end
if nargin<2 || isempty(fmt)
dot= find(fname=='.'); dot= dot(length(dot));
if isempty(dot) || dot >= length(fname)
error("imread: can't figure out the file type");
end
fmt= fname(dot+1:length(fname));
end
fmt= tolower(fmt);
#
# decode the nargout to output what the user wants
#
if nargout==1; wantgreyscale= 1; wantmap= 0;
elseif nargout==2; wantgreyscale= 0; wantmap= 1;
else wantgreyscale= 0; wantmap= 0;
end
#
# Begin the image processing proper
#
if strcmp( fmt, 'tif') || strcmp( fmt, 'tiff') || ...
strcmp( fmt, 'jpg') || strcmp( fmt, 'jpeg') || ...
strcmp( fmt, 'pnm') || strcmp( fmt, 'pbm') || ...
strcmp( fmt, 'pgm') || strcmp( fmt, 'ppm') || ...
strcmp( fmt, 'gif') || strcmp( fmt, 'bmp')
if fmt(1)=='j'
# jpeg: use djpeg to convert to pnm
if wantgreyscale; pname= ['djpeg -grayscale -pnm ' fname];
else pname= ['djpeg -pnm ' fname ];
end
elseif fmt(1)=='g'
# gif: use giftopnm to convert to pnm
if nargin > 2;
pname= sprintf('giftopnm -image %d %s 2>/dev/null ',imgno,fname);
else
pname= ['giftopnm 2>/dev/null ' fname ];
end
elseif fmt(1)=='b'
# bmp: use bmptoppm to convert to pnm
pname= ['bmptoppm 2>/dev/null ' fname ];
elseif fmt(1)=='t'
# tiff: use tifftopnm to convert to pnm
pname= ['tifftopnm 2>/dev/null ' fname ];
else
# p?m: use cat so that we can open it with a pipe
pname= ['cat ' fname ];
end
fid= popen(pname ,'r');
#
# can we open the pipe?
# if not 1) The file format is wrong and the conver program has bailed out
# 2) The apropriate converter program hasn't been installed
#
if fid<0;
error(['could not popen ' pname '. Are libgr-progs installed?']);
end
# get file type
line= fgetl( fid );
if strcmp(line, 'P1'); bpp=1; spp=1; bindata=0;
elseif strcmp(line, 'P4'); bpp=1; spp=1; bindata=1;
elseif strcmp(line, 'P2'); bpp=8; spp=1; bindata=0;
elseif strcmp(line, 'P5'); bpp=8; spp=1; bindata=1;
elseif strcmp(line, 'P3'); bpp=8; spp=3; bindata=0;
elseif strcmp(line, 'P6'); bpp=8; spp=3; bindata=1;
else error([fname 'does not appear to be a pnm file']);
end
# ignore comments
line= fgetl( fid );
while length(line)==0 || line(1)=='#'
line= fgetl( fid );
end
# get width, height
[wid, hig]= sscanf( line, '%d %d', 'C' );
# get max component value
if bpp==8
max_component= sscanf( fgetl(fid), '%d' );
end
if bindata
data= fread(fid);
numdata= size(data,1);
if bpp==1
data= rem( floor( (data*ones(1,8)) ./ ...
(ones(length(data),1)*[128 64 32 16 8 4 2 1]) ), 2)';
end
else
numdata= wid*hig*spp;
data= zeros( numdata,1 );
dptr= 1;
line= fgetl( fid );
while !feof( fid)
rdata= sscanf( line ,' %d');
nptr= dptr + size(rdata,1);
data( dptr:nptr-1 ) = rdata;
dptr= nptr;
line= fgetl( fid );
end # feof
end #if bindata
fclose( fid );
if spp==1
greyimg= reshape( data(:), wid, hig )';
elseif spp==3
redimg= reshape( data(1:spp:numdata), wid, hig )';
grnimg= reshape( data(2:spp:numdata), wid, hig )';
bluimg= reshape( data(3:spp:numdata), wid, hig )';
else
error(sprintf("imread: don't know how to handle pnm with spp=%d",spp));
end
elseif strcmp(fmt,'img') || strcmp(fmt,'octave')
eval (['load ', fname]);
if exist ("map") && ( exist("img") || exist("X") )
if (exist ("img"))
idximg = img;
elseif (exist ("X"))
idximg = X;
end
else
error ("imread: invalid image file found");
endif
elseif strcmp(fmt,'libtiff')
#
# read a tif file using the libtiff library instead of libgr-progs
# it sometimes works better, which is bizarre because
fid= popen(['tiffinfo -d ' fname],'r');
if fid<0; error(['could not open tiffinfo ' fname ]); end
while !feof( fid)
line= fgetl( fid );
if length(line)<6; continue; end
if strcmp(line(1:6), 'Strip ')
break;
end
# get all the number on the line
nums= toascii(line);
nums( nums<toascii('0') | nums>toascii('9'))= toascii(' ');
nums= sscanf(setstr(nums),'%d');
if strcmp(line(3:12) , 'Image Widt')
wid= nums(1); hig= nums(2);
elseif strcmp(line(3:12) , 'Resolution')
# DPI scanning resolution - not required
elseif strcmp(line(3:12) , 'Bits/Sampl')
bpp = nums(1);
elseif strcmp(line(3:12) , 'Compressio')
if !strcmp( line( length(line)+(-3:0) ),'None' )
error('imread: compressed tiffs not supported. Bummer');
end
elseif strcmp(line(3:12) , 'Photometri')
elseif strcmp(line(3:12) , 'Image Desc')
elseif strcmp(line(3:12) , 'Orientatio')
elseif strcmp(line(3:12) , 'Samples/Pi')
spp= nums(1);
elseif strcmp(line(3:12) , 'Rows/Strip')
elseif strcmp(line(3:12) , 'Planar Con')
end
end
numdata= wid*hig*spp;
data= zeros( numdata,1 );
dptr= 1;
while !feof( fid)
rdata= sscanf( line ,' %x');
nptr= dptr + size(rdata,1);
data( dptr:nptr-1 ) = rdata;
dptr= nptr;
line= fgetl( fid );
end # feof
fclose( fid );
if spp==1
greyimg= reshape( data, wid, hig )';
elseif spp==3
redimg= reshape( data(1:spp:numdata), wid, hig )';
grnimg= reshape( data(2:spp:numdata), wid, hig )';
bluimg= reshape( data(3:spp:numdata), wid, hig )';
else
printf("imread: Warning: don't know how to handle tif with spp=%d\n",spp)
;
# lets wing it and do the best we can
data= mean(reshape( data(1:numdata), spp, wid*hig ));
greyimg= reshape( data, wid, hig )';
end
else
error(['imread: format ' fmt ' is not supported. Bummer!']);
end
# This section outputs the image in the desired output format
# if the user requested the colour map, the we regenerate it from
# the image.
#
# Of course, 1) This may result in huge colourmaps
# 2) The colourmap will not be in the same order as
# in the original file
if wantgreyscale
if exist('greyimg')
out1= greyimg;
elseif exist('idximg')
greymap= mean(map')';
out1= reshape( greymap( idximg ) , size(idximg,1), size(idximg,2) );
else
out1= ( redimg+grnimg+bluimg ) / 3 ;
end
elseif wantmap
if exist('idximg')
out1= idximg;
out2= map;
elseif exist('greyimg')
[simg, sidx] = sort( greyimg(:) );
[jnkval, sidx] = sort( sidx );
dimg= [1; diff(simg)>0 ];
cimg= cumsum( dimg );
out1= reshape( cimg( sidx ) , size(greyimg,1), size(greyimg,2) );
out2= ( simg(find( dimg ))*[1,1,1] - 1)/255;
else
#
# attempt to generate a colourmap for r,g,b images, assume range is 0<v<1000
# for each value ( This will also be inaccurate for noninteger v )
# however, we shouldn't be getting any of that from the pnm converters
#
[simg, sidx] = sort( round(redimg(:)) + ...
1e3*round(grnimg(:)) + ...
1e6*round(bluimg(:)) );
[jnkval, sidx] = sort( sidx );
dimg= [1; diff(simg)>0 ];
cimg= cumsum( dimg );
out1= reshape( cimg( sidx ) , size(redimg,1), size(redimg,2) );
tmpv= simg(find( dimg )) - 1;
out2= [ rem(tmpv,1000), rem(floor(tmpv/1e3), 1000), floor(tmpv/1e6) ]/255;
end
else
if exist('greyimg')
out1= greyimg;
out2= greyimg;
out3= greyimg;
else
out1= redimg;
out2= grnimg;
out3= bluimg;
end
end
unwind_protect_cleanup
empty_list_elements_ok= save_empty_list_elements_ok;
end_unwind_protect
----------endoffile: imread.m-----------
-----------------------------------------------------------------------
Octave is freely available under the terms of the GNU GPL.
Octave's home on the web: http://www.che.wisc.edu/octave/octave.html
How to fund new projects: http://www.che.wisc.edu/octave/funding.html
Subscription information: http://www.che.wisc.edu/octave/archive.html
-----------------------------------------------------------------------