image thumbnail

uiselectim

by

 

12 Nov 2006 (Updated )

Visually select a single image from an array of images in a directory.

uiselectim(varargin)
function [img, map, alpha, filename, pathname, allFileNames] = uiselectim(varargin)
% Syntax:
% [img, map, alpha, filename, pathname, allFileNames] = uiselectim('start_path');
%
%
% Provides functionality for visually selecting a single image from an array
% of images. All images must be in a common directory. Calls uigetfile with
% the multi-select option enabled, allowing the user to select any number
% of images. The layout tool will automatically display images in a subplot 
% array. If you single-click an image, a background patch is highlighted to
% show the selection. Double-clicking (or selecting the "Okay" button)
% finalizes the selection, and returns the selected image (and map and
% alpha value, where appropriate), the filename, and the pathname. 
%
% INPUT:
%    start_path (optional): start_path specifies the directory to display
%    when the dialog is first opened. If start_path is a string
%    representing a valid directory path, the dialog box opens in the
%    specified directory. If start_path is an empty string ('') or is not
%    provided, the dialog box opens in the current working directory.
%
% OUTPUTS:
%    Output arguments 1--3 map to the output arguments of IMREAD. Note that
%    MAP and ALPHA may be empty. FILENAME and PATHNAME, not surprisingly,
%    return the filename and pathname of the selected image. ALLFILENAMES
%    returns a (sorted) list of the names of all images selected for
%    display in UISELECTIM. (See help for IMREAD for additional information
%    about the first three output arguments.) 
%
% EXAMPLES:
% [img, map, alpha, filename, pathname, allFileNames] = uiselectim('C:\mfiles'); 
% img = uiselectim; 


% Written 05/2006 by Brett Shoelson, PhD
% brett.shoelson@mathworks.com
% Ver 1.0

% Parse formats from IMFORMATS
formats = imformats;
nformats = length(formats);
desc = cell(nformats+1,1);
[desc{2:end}] = deal(formats.description);
ext = cell(nformats+1,1);
[ext{2:end}] = deal(formats.ext);
% Add other formats that are not part of IMFORMATS
desc{end+1} = 'Dicom (DCM)';
ext{end+1} = {'dcm'};
nformats = size(desc,1);
allext=[formats.ext,'dcm'];
ext{1} = sprintf('*.%s;',allext{:});
desc{1} = 'All Image Formats';

filterspec = cell(nformats,2);
filterspec{1,1} = ext{1};
filterspec{1,2} = desc{1};
for ii = 2:nformats
	filterspec{ii,1} = sprintf('*.%s;',ext{ii}{:});
	filterspec{ii,2} = sprintf('%s',desc{ii});
end


if nargin == 1 && ~isempty(varargin{1})
	currPath = pwd;
	tmp = pwd;
	try
		cd(varargin{1});
	catch
		error('If you provide an input argument, it must be a string representation of a valid search path.');
	end
end
[f,pathname] = uigetfile(filterspec,'MultiSelect', 'on');
if nargin == 1 && ~isempty(varargin{1})
	cd(currPath);
end

if ischar(f) %Single file selected
	filename = f;
	[img,map,alpha] = imread([pathname f]);
	allFileNames = f;
	return
end

if ~iscell(f) && f==0
	filename = []; pathname = []; img = [];map = [];alpha = [];allFileNames = [];
	return
end


nFrames = numel(f);
subim = zeros(nFrames,1);

if nargout > 5
	allFileNames=sort(f);
end

ptch=zeros(1,nFrames); %Preallocate patch variable
for ii = 1:nFrames
	[k,map,alpha] = imread([pathname f{ii}]);
	[nRows,nCols,nBands] = size(k);
	if ii == 1
		% Estimate nSubColumns and nSubRows given the desired ratio of
		% Columns to Rows to be one (square montage).
		aspectRatio = 1;
		nSubCols = sqrt(aspectRatio * nRows * nFrames / nCols);
		% Make sure Subplot rows and columns are integers. The order in the adjustment
		% matters because the Subplot image is created horizontally across columns.
		nSubCols = ceil(nSubCols);
		nSubRows = ceil(nFrames / nSubCols);
		tmpfig = figure('numbertitle','off','units','normalized',...
			'pos',[0.05 0.1 0.9 0.8],'name','Select Image','closerequestfcn',@mycloserequestfcn);
		okaybutton = uicontrol('style','pushbutton','string','Okay','units','normalized','position',[0.2 0.025 0.275 0.05],...
			'callback',@okay,'enable','off');
		uicontrol('style','pushbutton','string','Cancel','units','normalized','position',[0.525 0.025 0.275 0.05],...
			'callback',@mycloserequestfcn);
	end

	subplot(nSubCols,nSubRows,ii);
	subim(ii) = imshow(k,map);
	hold on
	% Pad x- and y-lim of current axis to include patch; create patch, and
	% send it behind the image
	x_aug = 0.05*diff(get(gca,'xlim'));
	y_aug = 0.05*diff(get(gca,'ylim'));
	ptch(ii) = patch([-x_aug nCols+x_aug nCols+x_aug -x_aug],[-y_aug -y_aug nRows+y_aug nRows+y_aug],...
		[1 0 0],'visible','off','edgecolor','none');
	set(gca,'children',flipud(get(gca,'children')),...
		'xlim',get(gca,'xlim')+[-x_aug x_aug],...
		'ylim',get(gca,'ylim')+[-y_aug y_aug]);
	set(subim(ii),'userdata',ii);
	title(f{ii});
end
set(subim,'buttondownfcn',@imsel);
uiwait(tmpfig);

%NESTED FUNCTIONS
	function selected = imsel(varargin)
		% SelectionType
		% normal: Click left mouse button
		% extend: Shift - click left mouse button or click both left and right mouse buttons
		% alt: Control - click left mouse button or click right mouse button
		% open: Double click any mouse button
		seltype = get(gcf,'SelectionType');
		selected = get(varargin{1},'userdata');
		switch seltype
			case {'normal','extend'}
				set(ptch,'visible','off');
				set(ptch(selected),'visible','on');
				set(okaybutton,'enable','on');
			case 'open'
				% Finalize selection; delete figure, store selection number
				% in main figure
				finalizeSelection(selected);
			case 'alt'
				tmp = get(gcbo,'cdata');
				tmppos = get(gcf,'pos');
				tmpunits = get(gcf,'units');
				tmpfig = figure('units',tmpunits);
				imshow(tmp);
				set(tmpfig,'pos',tmppos);
				uiwait(tmpfig);
		end
	end

	function okay(varargin)
		tmp = get(ptch,'visible');
		selected = find(strcmp(tmp,'on'));
		finalizeSelection(selected);
	end

	function finalizeSelection(varargin)
		selected = varargin{1};
		filename = f{selected};
		img = imread([pathname filename]);
		delete(gcf);
		drawnow;
	end

	function mycloserequestfcn(varargin)
		img=[];
		filename = [];
		pathname = [];
		closereq;
	end

end

Contact us