function imqc(in,out)
%IMQC runs quality control checks on TIFF images
%
% IMQC(DRIVER,REPORT_FILE)
%
% DRIVER is a file listing the TIFF images to be quality controlled (full
% path and filename should be supplied)
% REPORT_FILE is the full path and name of a file to which the IMQC report
% will be written. You should have permission to write to the specified
% directory. If the filename specified already exists, it will be
% overwritten.
%
% This function is not designed to replace visualising the data, but to
% provide a warning of which files may not be suitable for continued
% processing.
%
% Version 1.0
%
% Adam Leadbetter (alead@bodc.ac.uk) - 2006Nov24
%
% Try to open the in and out files - if we fail on either it is an error
%
fid = fopen(in);
if(fid == -1)
error('ImageQualityControl:CannotOpenDriver',...
'Error: Cannot open the driver file %s',in);
end
fir = fopen(out,'w');
if(fir == -1)
error('ImageQualityControl:CannotOpenReport',...
'Error: Cannot open the report file %s',out);
end
clear in out;
%
% Process the images
%
report = struct('FileName','',...
'Error','',...
'Warning','');
ImgNam = fgetl(fid);
kk = 0;
Counter = struct('Processed',0,'Warnings',0,'Errors',0);
while(ImgNam ~= -1)
kk = kk + 1;
fprintf(1,'\n\tProcessing %s\n',ImgNam);
report(kk).FileName = ImgNam;
%
% Check that the image exists
%
fie = fopen(ImgNam);
if(fie == -1)
fprintf(fir,'\n\tWarning: %s - Could not open image\n',report(kk).FileName);
fprintf(1,'\n\t\tWarning: Could not open image\n');
report(kk).Error = 'CouldNotOpenImageFile';
Counter.Errors = Counter.Errors + 1;
ImgNam = fgetl(fid);
continue
end
fclose(fie);
%
% Check we're dealing with a genuine TIFF file
%
allowed_fmts = {'TIF','TIFF','tif','tiff'};
ImgInfo = imfinfo(ImgNam);
if(~ismember(allowed_fmts,ImgInfo.Format))
fprintf(fir,'\n\tWarning: %s - Not a TIFF image\n',report(kk).FileName);
fprintf(1,'\n\t\tWarning: Not a TIFF image\n');
report(kk).Error = 'NotTIFF';
Counter.Errors = Counter.Errors + 1;
ImgNam = fgetl(fid);
continue
end
clear allowed_fmts;
%
% Load the image & generate the histogram
%
AA = imread(report(kk).FileName);
if(length(size(AA)) == 3)
nn = 2;
aq = size(AA);
AB = AA(:,:,1);
while(nn <= aq(3))
AB = AB + AA(:,:,aq(3));
nn = nn + 1;
end
AA = AB;
clear aq nn AB;
end
try
[Counts,X] = imhist(AA);
catch
Counter.Errors = Counter.Errors + 1;
fprintf(1,'\n\t\tWarning: Could not generate an image histogram\n');
fprintf(fir,'\n\tWarning: %s - Could not generate an image histogram\n',...
report(kk).FileName);
report(kk).Error = 'UnrecognisedImageTypeHistogram';
ImgNam = fgetl(fid);
continue
end
%
% Check for black-out, white-out & one-frequency dominance
%
if((sum(Counts) * 0.90) < (sum(Counts(1:ceil(0.05*length(X))))))
report(kk).Warning = 'BlackOut';
Counter.Warnings = Counter.Warnings + 1;
fprintf(1,'\n\t\tWarning: May be a black-out\n');
fprintf(fir,'\n\tWarning: %s May be a black-out\n',report(kk).FileName);
elseif((sum(Counts) * 0.90) < (sum(Counts(floor(0.95*length(X)):end))))
report(kk).Warning = 'WhiteOut';
Counter.Warnings = Counter.Warnings + 1;
fprintf(1,'\n\t\tWarning: May be a white-out\n');
fprintf(fir,'\n\tWarning: %s may be a white-out\n',report(kk).FileName);
elseif(max(Counts) > (4*std(Counts)) + median(Counts)) % May need twaeking
report(kk).Warning = 'SingleFreqDominant';
fprintf(1,'\n\tWarning: A single frequency may be dominant\n');
fprintf(fir,'\n\tWarning: %s - a single frequency may be dominant\n',...
report(kk).FileName);
else
report(kk).Warning = [];
end
%
% If there's a warning - do a plot
%
if(~isempty(report(kk).Warning))
local_imqcplot(AA,ImgNam);
end
%
% Get the next image filename
%
ImgNam = fgetl(fid);
Counter.Processed = Counter.Processed + 1;
end
clear fie;
%
% Tidy up - close the files
%
fprintf(1,'\n\tFinishing up\n');
fclose(fid);
fprintf(fir,'\n\tFiles processed:\t\t%g',Counter.Processed);
fprintf(fir,'\n\tWarnings found:\t\t%g',Counter.Warnings);
fprintf(fir,'\n\tImages skipped:\t\t%g\n',Counter.Errors);
fprintf(fir,'\n\tNormal termination\n');
fclose(fir);
fprintf(1,'\n\tReport file written\n');
fprintf(1,'\n\tFiles processed:\t%g',Counter.Processed);
fprintf(1,'\n\tWarnings found:\t\t%g',Counter.Warnings);
fprintf(1,'\n\tImages skipped:\t\t%g\n',Counter.Errors);
clear fid fir;
fprintf(1,'\n\tJob done\n');
function local_imqcplot(AA,ImgNam)
%LOCAL_IMQCPLOT plots the image quality control window
%
% AA is the image data acquired by IMREAD
%
% Version 1.0
% Adam Leadbetter (alead@bodc.ac.uk) - 2006Nov24
figure;
if(find(ImgNam == '\'))
ImgNam(ImgNam == '\') = '/';
end
subplot(3,4,[1:3 5:7 9:11]);
imshow(AA);
title(ImgNam,'FontWeight','bold','FontSize',14);
subplot(3,4,8);
imhist(AA);
grid on;