when i give a fluke ti400 is2 image as input i am getting maximum variable size exceeded error in matlab? how to overcome the problem?

function [X,d] = readis2(f,map,param,cal)
%READIS2 Import data files from Fluke infrared thermal camera (IS2 format).
% X=READIS2(FILENAME) reads IS2 radiometric file FILENAME and
% returns a structure X containing fields with data and headers:
% IR: infrared sensor values (240x320 uint16 matrix)
% TB: brillancy temperatures, in C (240x320 double matrix)
% T: body temperatures, in C (240x320 double matrix)
% VI: visible image (480x640x3 uint8 RGB)
% VI2: cropped and interpolated visible image adjusted on IR
% image pixels (240x320x3 uint8 RGB)
% Emissivity: emissivity value (0 to 1.00)
% Transmission: transmission value (0 to 1.00)
% BackgroundTemp: background temperature (C)
% Date: [YEAR MONTH DAY HOUR MINUTE SECOND]
%
% X=READIS2(FILENAME,MAP) plots temperature image using MAP color scale
% over visible image. MAP is a valid [n x 3] RGB colormap, for instance
% JET or GRAY. Use MAP=[] to specify other parameters without plot.
%
% X=READIS2(FILENAME,MAP,PARAM) applies given parameters to overwrite values
% from camera. PARAM = [DT,EM,TR,BT] (use NaN to keep original values):
% DT = time difference (in days) applied to image timestamp
% EM = emissivity
% TR = transmission
% BT = background temperature (C)
%
% X=READIS2(FILENAME,MAP,PARAM,CAL) applies a polynomial function to calibrate
% brillancy temperatures, as follow: TB_cal = polyval(CAL,TB_raw). This will
% affect also body temperatures. Example: CAL = [1.08,-2.72] is for my own
% Ti32 camera calibration result for 0-100C range laboratory experiment.
%
% Notes:
% - the function has been tested only with original IS2 files from a
% Fluke TI32 camera.
% - to produce temperatures from IR sensor values, the function needs a
% calibration file 'readis2_ti32.dat' located in current directory or
% Matlab path (see corresponding header info).
% - body temperatures Tr (output X.T) and brillancy temperatures Tb
% (output X.IR) are related with the formula:
% Tb = e*t*Tr + (2-e-t)*Te
% where e is emissivity, t is transmission, and Te is background
% (reflected) temperature. So Tb and Tr are equal for e = t = 1.
%
% Author: Franois Beauducel <beauducel@ipgp.fr>
% Institut de Physique du Globe de Paris
%
% Created: 2011-07-24
% Updated: 2012-04-01
%
% Acknowledgments:
% Magnus Andersen (read_is2.m), Pierre Agrinier, Valrie Clouard,
% Damien Gaudin, David Krammer.
% History:
% [2012-04-01]
% - body temperature now OK when emissivity or transmission < 1
% [2012-03-26]
% - adds possibility to calibrate brillancy temperature using polynomial
% - extends comments on calibration file
% [2012-02-06]
% - Improve plot output (log-scale histogram)
%
%
% Copyright (c) 2012, Franois Beauducel, covered by BSD License.
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are
% met:
%
% * Redistributions of source code must retain the above copyright
% notice, this list of conditions and the following disclaimer.
% * Redistributions in binary form must reproduce the above copyright
% notice, this list of conditions and the following disclaimer in
% the documentation and/or other materials provided with the distribution
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
% POSSIBILITY OF SUCH DAMAGE.
error(nargchk(0,4,nargin))
unit = 'count';
makeplot = 0;
cmap = jet(2^16);
if nargin < 1
[filename,pathname] = uigetfile('*.IS2','Please select a file...');
f = fullfile(pathname,filename);
end
if ~ischar(f) | ~exist(f,'file')
error('File %s does not exist.',f);
end
if nargin >= 2
if ~isempty(map)
if ~isnumeric(map) | size(map,2) ~= 3
error('MAP must be a colormap Mx3 matrix');
else
cmap = map;
makeplot = 1;
end
end
end
if nargin >= 3
if ~isnumeric(param)
error('PARAM must be numeric');
end
else
param = 0;
end
if nargin >= 4
if ~isnumeric(cal)
error('CAL must be numeric');
end
end
% Temperature calibration file
fcal = 'readis2_ti32.dat';
% ATTENTION: this file must exist in the Matlab path to produce temperature
% values in C (otherwise temperatures are given in counts).
% The data come from interpolation of sample images exported using the
% Fluke SmartView software
if exist(fcal,'file')
tcal = load(fcal);
unit = 'C';
else
warning('Calibration file "%s" not found.\nOutput IR temperatures will be uncalibrated (uint16).',fcal);
end
% data offsets
offset_ir = 7989;
offset_vi = 84817;
% --- reads the whole file in uint16
fid = fopen(f);
d = fread(fid,'*uint16');
fclose(fid);
% --- gets some header informations
% header index = d(1:7989) and d(84790:84817)
header{1} = char(d(88:105))'; % CameraManufacturer
header{2} = char(d(120:130))'; % CameraModel
header{3} = char(d(152:170))'; % CameraSerial
header{4} = char(d(184:198))'; % EngineSerial
header{5} = fliplr(typecast(d(64:65),'uint8')'); % FirmwareVersion
% get the date and time
daymonth = double(typecast(d(2936)','uint8')); % day and month
year = double(d(2937)); % year
msec = double(typecast(d(2934:2935),'uint32')); % number of milliseconds in the day
if isnan(param(1))
dt = 0;
else
dt = param(1);
end
dte = datenum(year,daymonth(2),daymonth(1),0,0,msec/1000) + dt;
% get IR parameters
emissivity = double(typecast(d(2940:2941),'single'));
transmission = double(typecast(d(2942:2943),'single'));
backgroundtemp = double(typecast(d(2944:2945),'single'));
% IR image size
irsz(1) = double(typecast(d(7984:7985),'uint32')); % 320
irsz(2) = double(typecast(d(7986:7987),'uint32')); % 240
% visible image size
visz(1) = double(typecast(d(2930:2931),'uint32')); % 640
visz(2) = double(typecast(d(2932:2933),'uint32')); % 480
vsz = [visz(2),visz(1),3]; % [480,640,3]
% --- reads IR image (320x240 16-bit)
*
ir = reshape(d(offset_ir+(1:prod(irsz))),irsz)';*//getting error here
if exist('tcal','var')
tb = interp1(tcal(:,1),tcal(:,2),double(ir),'linear','extrap');
else
tb = double(ir);
end
% --- calibrates brillancy temperature using CAL (if specified)
if exist('cal','var')
tb = polyval(cal,tb);
end
% --- computes body temperature from brillancy temperature and parameters
if length(param) >= 2 & ~isnan(param(2))
emissivity = param(2);
end
if length(param) >= 3 & ~isnan(param(3))
transmission = param(3);
end
if length(param) >= 4 & ~isnan(param(4))
backgroundtemp = param(4);
end
t = tb/(emissivity*transmission) - (2-emissivity-transmission)*backgroundtemp;
tlim = minmax(t);
tavr = mean(mean(t));
% --- reads visible image (640x480 16-bit RGB coded 5:6:5)
*v = reshape(d(offset_vi+(1:prod(vsz(1:2)))),vsz(2),vsz(1))';*//getting error here
vi = zeros(vsz,'uint8');
vi(:,:,3) = bitshift(bitand(v,31),3); % 5 less significant bits = blue
vi(:,:,2) = bitshift(bitand(bitshift(v,-5),63),2); % 6 middle bits = green
vi(:,:,1) = bitshift(bitshift(v,-11),3); % 5 most significant bits = red
% incrustes IR image into visible one (IR-Fusion simulation)
x0 = 1:irsz(1);
y0 = 1:irsz(2);
r = 1.25;
[xx,yy] = meshgrid(linspace(x0(1),x0(end),length(x0)*r),linspace(y0(1),y0(end),length(y0)*r));
ti = interp2(x0,y0,double(t),xx,yy,'*linear');
s2 = size(ti);
ti = ind2rgb(floor((size(cmap,1)-1)*(ti-min(min(ti)))/diff(minmax(ti))+1),cmap);
ii = (vsz(1)-s2(1))/2 + (1:s2(1));
jj = (vsz(2)-s2(2))/2 + (1:s2(2));
blend = vi;
blend(ii,jj,:) = uint8(256*ti);
% crops and interpolates visible image to fit IR image
x1 = 1:length(jj);
y1 = 1:length(ii);
[xx,yy] = meshgrid(linspace(1,length(jj),irsz(1)),linspace(1,length(ii),irsz(2)));
vi2(:,:,1) = uint8(interp2(x1,y1,double(vi(ii,jj,1)),xx,yy,'*linear'));
vi2(:,:,2) = uint8(interp2(x1,y1,double(vi(ii,jj,2)),xx,yy,'*linear'));
vi2(:,:,3) = uint8(interp2(x1,y1,double(vi(ii,jj,3)),xx,yy,'*linear'));
if nargout
X.Filename = f;
X.VI = vi;
X.VI2 = vi2;
X.IR = ir;
X.TB = tb;
X.T = t;
X.Unit = unit;
X.Range = tlim;
X.IRBlend = blend;
X.Date = datevec(dte);
X.Emissivity = emissivity;
X.Transmission = transmission;
X.BackgroundTemp = backgroundtemp;
X.CameraManufacturer = header{1};
X.CameraModel = header{2};
X.CameraSerial = header{3};
X.EngineSerial = header{4};
X.IRSensorSize = irsz;
X.Firmware = sprintf('%d.%d.%d.%d',header{5});
else
makeplot = 1;
end
% plots images and statistics
if makeplot
scrsz = get(0,'ScreenSize');
figure('Position',[1,1,scrsz(4)*2/3,scrsz(4)],'PaperType','usletter')
orient tall
% plots blend image
subplot(8,1,1:5)
imagesc(blend)
title({sprintf('%s %s',header{1},header{3}), ...
sprintf('"%s" [%s]',f,datestr(dte))}, ...
'FontSize',10,'FontWeight','bold','Interpreter','none')
axis image, axis off
% text legends
xt = size(blend,2)*2/8;
yt = size(blend,1);
text(xt,yt,{'','Emissivity ','Transmission ','Background Temp. '}, ...
'FontSize',10,'HorizontalAlignment','right','VerticalAlignment','top')
text(xt,yt,{'', ...
sprintf('= {\\bf%1.2f}',emissivity), ...
sprintf('= {\\bf%1.2f}',transmission), ...
sprintf('= {\\bf%g C}',backgroundtemp)}, ...
'FontSize',10,'HorizontalAlignment','left','VerticalAlignment','top')
xt = size(blend,2)*6/8;
text(xt,yt,{'','Temperature Max. ','Min. ','Avr. '}, ...
'FontSize',10,'HorizontalAlignment','right','VerticalAlignment','top')
text(xt,yt,{'', ...
sprintf('= {\\bf%+7.2f %s}',tlim(2),unit), ...
sprintf('= {\\bf%+7.2f %s}',tlim(1),unit), ...
sprintf('= {\\bf%+7.2f %s}',tavr,unit)}, ...
'FontSize',10,'HorizontalAlignment','left','VerticalAlignment','top')
h = colorbar;
title(h,unit)
colormap(cmap)
caxis(tlim)
% plots histogram of pixels
n = 50; % number of bins
bins = linspace(tlim(1),tlim(2),n);
ht = hist(t(:),bins); % computes histogram
htl = log10(ht) + 1; % computes log and adds +1 because bar graph refers to 0
xlim = tlim + diff(tlim)*(1/n)*[-1,1]; % extends both X-limits of 1/n
ylim = [0,max(htl)];
subplot(8,1,6)
htn = 100*ht/sum(ht); % normalized histogram
plot(bins,htn,'-k','LineWidth',2);
set(gca,'XLim',xlim,'XTickLabel',[])
grid on
ylabel('# Pixels (%)')
subplot(8,1,7:8)
h = bar(bins,htl); % initial histogram [0,1,10,100] become [-Inf,1,2,3]
set(get(h,'Children'),'CData',bins,'LineWidth',.2); % makes indexed color bars
set(gca,'XLim',xlim,'YLimMode','manual','YLim',ylim);
ytick = (0:6)'; % blind ticks are 0,1,2, ... 6
yticklabel = num2str([0,10.^(0:5)]'); % tick labels are '0','1','10', ... '100000'
set(gca,'YTick',ytick,'YTickLabel',yticklabel)
grid on
ylabel('Number of pixels')
xlabel(sprintf('IR Temperature (%s)',unit))
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function y = minmax(x)
% minmax(X) returns [MIN,MAX] vector with min and max values of matrix X
y = [min(min(x)),max(max(x))];

3 Comments

We can deduce that d is uint16 or int16. The size is not important at the moment: if it were too small then we would not have reached the line with the problem.

Sign in to comment.

Answers (3)

I suspect that you need to swapbtyes() those uint32. On all MATLAB versions for a number of years, the values have been little-endian and I suspect that your byte stream is big-endian
You're using the code for images created by the Fluke Ti32. I know that Fluke did change it's file format, it's now a zip-file. Maybe you do have something on this project: https://gitlab.com/roelofy/read_is2_new (I know it's Python... And the script is not ready yet.)

Asked:

on 26 Dec 2017

Answered:

on 6 Jul 2021

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!