Last time I showed off custom data cursors with a little utility function that displays object labels as data cursors:
My code used label2rgb to display a "colorized" label matrix. The custom data cursor callback, though, needed the original label matrix, so I used setappdata to save the label matrix in a place where the callback routine could retrieve it.
Within a few hours of posting that code, I had a "Doh!" moment. I haven't used that kind of setappdata trick since nested function handles appeared in MATLAB 7.0. I have no idea why I suddenly reverted to my previous coding patterns. Old habits die hard, as the cliche says.
Anyway, nested function handles in MATLAB 7 can be used to create callback functions that carry around their own state. I thought I would show you how my display_label_matrix function looks using this technique.
function display_label_matrix(L) % display_label_matrix Display label matrix with custom data cursors % display_label_matrix(L) displays the label matrix L as colored objects on % a gray background. It also installs a custom data cursor handler in the % figure. In data cursor mode, clicking on an object displays a data % cursor containing the object's number. % Steve Eddins % Copyright 2006 The MathWorks, Inc. % $Revision: 1.2 $ $Date: 2006/11/21 02:41:00 $ rgb = label2rgb(L, 'jet', [.7 .7 .7], 'shuffle'); h = imshow(rgb); % Enable the figure data cursor mode, and use our own custom data cursor % strings. dcm = datacursormode(ancestor(h, 'figure')); set(dcm,'Enable','on', ... 'Updatefcn', @dataCursorText); %====================================================================== function output_text = dataCursorText(obj, event_obj) % Respond to a user click in data cursor mode by displaying the label % number of the pixel that was clicked on. h_image = get(event_obj, 'Target'); pos = get(event_obj, 'Position'); clicked_label = L(round(pos(2)), round(pos(1))); output_text = sprintf('%d', clicked_label); end %---------------------------------------------------------------------- end
In the new version, the callback function, dataCursorText, is nested within the outer function, display_label_matrix. Notice how dataCursorText uses a variable, L, that is created in the scope of the outer function, display_label_matrix. When the outer function creates a function handle to dataCursorText, the value of L at that moment is captured into a kind of private workspace that goes along with the function handle. No auxiliary information or state needs to be stored anywhere else; the function handle has inside of it all the information it needs to perform its computation.
If you are interested in learning more about nested functions in MATLAB, you might want to look at Loren Shure's News & Notes article on the topic.
Get the MATLAB code
Published with MATLAB® 7.3