source: prextra/impaint.m @ 62

Last change on this file since 62 was 5, checked in by bduin, 14 years ago
File size: 5.7 KB
Line 
1function out = impaint(fig,varargin)
2% out = impaint(fig)
3%
4% Create an overlay on the current active image and allow for painting the
5% overlay.
6% Possible calls:
7%   impaint(h,'on');               start the overlay
8%   impaint(h,'off');              remove the whole overlay
9%   impaint(h,classnr,[r g b]);    define a new class with colour [r g b]
10% out = impaint(h,'get');          get the label image out
11%
12% You can leave out h, then the current active figure is used.
13%
14% There are also some interactive changes that you can make:
15%   t    toggles impaint on and off
16%  Nc    selects another class label (prefix this command with the
17%         class number N)
18%  Nb    sets the brush size to N (prefix this command with the brush
19%         size N)
20%   s    save the current labels in Matlab variable 'lab'
21%
22% See also  im_update
23
24
25% When nothing is defined:
26if nargin<2
27        varargin = {'on'};
28end
29% Special case, because an integer can be interpreted as a handle, we
30% assume that when a single input is given, it is actually a label
31if nargin==1
32        if isnumeric(fig)
33                varargin{1} = fig;
34                fig = gcf;
35        end
36end
37if nargin<1
38        fig = gcf;
39end
40% make sure that the first input is the figure handle:
41if ~ishandle(fig)
42        varargin = {fig varargin{:}};
43        fig = gcf;
44end
45
46% Check if we want to get/set the active class, or (re)define a class:
47if isnumeric(varargin{1})
48        allUD = get(fig,'userdata');
49        if ~isfield(allUD,'impaint')
50                error('This image does not have an overlay defined.');
51        end
52        UD=allUD.impaint; % our part of UD
53        if length(varargin)==1  % we want to set/get the active class
54                if varargin{1}>size(UD.msk_fg,1)
55                        error('This class is not defined in the overlay.');
56                else
57                        UD.currlab = varargin{1};
58                end
59                % and (maybe more important) get the labels to the output
60                if nargout>0
61                        out = UD.labels;
62                end
63        else                    % we want to set the colours
64                % We can process a whole list of colours...
65                for i=1:2:(length(varargin)-1)
66                        [nr,clr] = checkimpaintcolor(varargin{i},varargin{i+1});
67                        UD.msk_fg(nr,:) = clr;
68                        % Definition of the active label
69                        UD.currlab = nr;
70                end
71        end
72        % store everthing in the figure:
73        set(fig,'UserData',[]);
74        allUD.impaint=UD;
75        set(fig,'UserData',allUD);
76        return;
77end
78
79
80% Now check all the 'string' possibilities:
81switch lower(varargin{1})
82case 'on'
83
84        % Set up variables:
85        allUD=get(fig,'UserData'); % existing user data
86        UD = [];   % Here I store the UserData
87
88        % Put the image on screen
89        UD.im_ax = findobj(get(fig,'children'),'type','axes');
90        UD.im_im = findobj(get(UD.im_ax,'children'),'type','image');
91        % get the size of the image
92        sz = size(get(UD.im_im,'cdata'));
93
94        %set(fig,'busyaction','cancel','DoubleBuffer','on');
95
96        % Label storage:
97        UD.labels = zeros(sz);  % background has label=0
98        UD.labsize=size(UD.labels);
99       
100        % Mask image
101        if length(sz)==2
102                mskim = zeros([sz 3]);
103        elseif length(sz)==3
104                mskim = zeros(sz);
105        else
106                error('I cannot make a mask image for this image data.');
107        end
108        %mskim(1:50, 1:140, 1) = 1; % just to show something...
109        % Definitions of the fore- and background colour
110        if length(varargin)==3
111                [nr,clr] = checkimpaintcolor(varargin{2},varargin{3});
112                UD.msk_fg(nr,:) = clr;
113                % Definition of the active label
114                UD.currlab = nr;
115        else
116                UD.msk_fg = [1 0 0; 0 1 0; 0 0 1];   % standard: the first class is red.
117                % Definition of the active label
118                UD.currlab = 1;
119        end
120        UD.msk_bg = [0 0 0];
121        % Definition of the brush-size
122        UD.brushsz = 4;
123        % define character command buffer:
124        UD.charbuffer='';
125        UD.state='on'; % impaint is toggled on
126
127        % make a second axis for the overlay:
128        UD.pos = get(UD.im_ax,'position');
129        UD.msk_ax = axes('position', UD.pos);
130        set(fig,'currentaxes',UD.msk_ax);
131        UD.msk_im = imagesc(mskim);
132        set(UD.msk_ax,'visible','off');
133        msk2 = findobj(get(UD.msk_ax,'children'),'type','image');
134        set(msk2,'alphadata',0.5);
135
136        % set the window title:
137        set(fig,'Name',sprintf('imprint on, brush: %d, class: %d',UD.brushsz,UD.currlab));
138       
139        % to speedup coordinate transformations later:
140        UD.sz = sz;
141        UD.W = sz(2)./UD.pos(3);
142        UD.H = sz(1)./UD.pos(4);
143        UD.pos(3) = UD.pos(3)+UD.pos(1);
144        UD.pos(4) = UD.pos(4)+UD.pos(2);
145
146        % now we have to define a callback
147        oldh.btndown=get(fig,'WindowButtonDownFcn');
148        set(fig,'WindowButtonDownFcn','im_update(''fill'')');
149        oldh.btnup=get(fig,'WindowButtonUpFcn');
150        set(fig,'WindowButtonUpFcn','im_update(''stopfill'')');
151        oldh.keypress=get(fig,'KeyPressFcn');
152        set(fig,'KeyPressFcn','im_update(''keypress'')');       
153
154        % preserve previously set handlers
155        UD.oldhandlers=oldh;
156       
157        % store everthing in the figure:
158        set(fig,'UserData',[]);
159        allUD.impaint=UD; % set our substructure in UD
160        set(fig,'UserData',allUD);
161       
162        out=fig;
163        return
164       
165case 'get'
166        allUD = get(fig,'userdata');
167        if ~isfield(allUD,'impaint')
168                error('This image does not have an overlay defined.');
169        end
170        out = allUD.impaint.labels;
171       
172        return
173
174case 'off'
175        % Remove all the traces from the image:
176        allUD = get(fig,'userdata');
177        if ~isfield(allUD,'impaint')
178                error('This image does not have an overlay defined.');
179        end
180        UD=allUD.impaint;
181        delete(UD.msk_ax);
182
183        % restore old handlers
184        set(fig,'WindowButtonDownFcn',UD.oldhandlers.btndown);
185        set(fig,'WindowButtonUpFcn',UD.oldhandlers.btnup);
186        set(fig,'KeyPressFcn',UD.oldhandlers.keypress);
187       
188        rmfield(allUD,'impaint');
189        set(fig,'userdata',allUD);
190
191        return
192
193end
194
195return
196
197function [nr,clr] = checkimpaintcolor(nr,clr)
198if ~isnumeric(nr)
199        error('The class number should be a scalar.');
200end
201if (length(nr)~=1)
202        error('The class number should be a scalar.');
203end
204if ~isnumeric(clr)
205        error('The color definition should be 1x3 matrix.');
206end
207if (length(clr)~=3)
208        error('The color definition should be 1x3 matrix.');
209end
210if any(clr<0)
211        error('Colour values should be larger than 0.');
212end
213if any(clr>1)
214        error('Colour values should be smaller than 1.');
215end
216% make it a nice row vector:
217clr = clr(:)';
218return
Note: See TracBrowser for help on using the repository browser.