开发者

problem with Slider and ButtonDownFcn in Matlab

I have a problem with Slider and ButtonDownFcn.

Currently I display to the user an image in the GUI (using GUIDE), then I let them select a license plate by drawing a rectangle around it.

I have added slider to turn the image in degrees.

When I turn the image and then click on it, the image returns to its initial state (angle).

What can do to make sure that the image stays in its location and then draw the rectangle on it?

This is my ButtonDownFcn function:

function axes1_ButtonDownFcn(hObject, eventdata, handles)
global image  h 
imshow(image, []);
h = imrect;
setColor(h, 'black');

This is my slider function:

function slider2_Callback(hObject, eventdata, handles)
global image hImage
slider_value = get(handles.slider2,'Value');
axes(handles.axes1);
hImage = imshow(imrotate(image,slider_value,'bilinear'), 开发者_运维技巧'Parent', handles.axes1);
set(hImage, 'ButtonDownFcn', @(s,e) axes1_ButtonDownFcn());

EDIT: now it's all working just fine, and more importantly it is clear. one last thing do you know how I can remove the numbers from X and Y axes. I tried with axes off but it didn't help.

problem with Slider and ButtonDownFcn in Matlab

thanks a lot.


I believe it's easier to learn by example. So, I will continue the example I started in your previous question.

When the GUI is started, an image is shown, which you can rotate using the slider. When the image is clicked, select a rectangular ROI (you can continue to rotate the image underneath). Once satisfied, double click the rectangle, and the cropped image is shown on the other axes (one cropped from the rotated image, the other from the original image), then the rectangle is removed.

function rotationGUI2()
    %# setup GUI
    hFig = figure('menu','none', 'Position',[100 100 750 420]);
    hAx = axes('Parent',hFig, 'Units','pixels', 'Position',[50 70 350 300]);
    hAx1 = axes('Parent',hFig, 'Units','pixels', 'Position',[450 230 250 140]);
    hAx2 = axes('Parent',hFig, 'Units','pixels', 'Position',[450 70 250 140]);
    uicontrol('Parent',hFig, 'Style','slider', 'Value',0, 'Min',0,...
        'Max',360, 'SliderStep',[1 10]./360, ...
        'Position',[100 20 300 30], 'Callback',@slider_callback) 
    hTxt = uicontrol('Style','text', 'String','0', ...
        'Units','pixels', 'Position',[240 25 20 15]);

    %# read and show image
    I = imread('cameraman.tif');
    hImg = imshow(I, 'Parent',hAx);
    set(hImg, 'ButtonDownFcn',@image_ButtonDownFcn);  %# attach event listener

    %# Callback functions
    function slider_callback(hObj, eventdata)
        angle = round( get(hObj,'Value') );             %# rotation angle
        I_rot = imrotate(I, angle, 'bilinear', 'crop'); %# rotate image
        set(hImg, 'CData',I_rot)                        %# update image
        set(hTxt, 'String',num2str(angle))              %# update text
    end
    function image_ButtonDownFcn(hObj,eventdata)
        hRect = imrect(hAx);
        setColor(hRect, 'black');
        rectPos = wait(hRect);
        delete(hRect)

        I1 = imcrop(I, rectPos);                  %# crop from original image
        I2 = imcrop(get(hImg,'CData'), rectPos);  %# crop from rotated image
        imshow(I1, 'Parent',hAx1)
        imshow(I2, 'Parent',hAx2)
    end
end

problem with Slider and ButtonDownFcn in Matlab

Again, recreating the example using a GUIDE-generated figure should be similar. HTH


EDIT

Below you will find a similar example generated by GUIDE. As before, you will have to create the GUI and add the components by drag-drop. Use the "Property Inspector" to adjust their properties as required. More importantly, give each a unique Tag. I'm using:

  • imgAxis, cropAxis, processAxis
  • loadButton, processButton
  • angleSlider, angleText

problem with Slider and ButtonDownFcn in Matlab

It is good practice not to use global variables, instead store your data in the handles structure which gets passed around to the callback functions. Just remember to call the guidata function at the end of any method that changes its data, to commit the changes.

For the part where you manually attach a handler to the image ButtonDownFcn event, you should also pass the handles structure to the arguments list.

That said, here the code behind the GUI (relevant parts):

%# --- Executes just before untitled is made visible.
function untitled_OpeningFcn(hObject, eventdata, handles, varargin)
    %# store handles to figure, axes, and others
    handles.fig = hObject;
    handles.hAx = findobj(hObject, 'Tag','imgAxis');
    handles.hAxCrop = findobj(hObject, 'Tag','cropAxis');
    handles.hAxProcess = findobj(hObject, 'Tag','processAxis');
    handles.img = [];
    handles.hImg = [];
    handles.hImgCrop = [];

    %# disable interaction of some components until image is loaded
    set(findobj(hObject, 'Tag','angleSlider'), 'Enable','off')
    set(findobj(hObject, 'Tag','processButton'), 'Enable','off')

    %# Update handles structure
    guidata(hObject, handles);
end

%# --- Outputs from this function are returned to the command line.
function varargout = untitled_OutputFcn(hObject, eventdata, handles)
    varargout{1} = handles.fig;
end

%# --- Executes on slider movement.
function angleSlider_Callback(hObject, eventdata, handles)
    angle = round( get(hObject,'Value') );                    %# rotation angle
    I_rot = imrotate(handles.img, angle, 'bilinear', 'crop'); %# rotate image
    set(handles.hImg, 'CData',I_rot)                          %# update image
    set(findobj(handles.fig,'Tag','angleText'), 'String',num2str(angle))
end

%# --- Executes on button press in processButton.
function processButton_Callback(hObject, eventdata, handles)
    %# get cropped image
    I = get(handles.hImgCrop, 'CData');

    %# do some processing: here i'm simply detecting the edges
    if isrgb(I), I = rgb2gray(I); end
    %#BW = im2bw(I, graythresh(I));
    BW = edge(I, 'canny');

    %# show processed image
    imshow(BW, 'Parent',handles.hAxProcess)

    %# Update handles structure
    guidata(hObject, handles);
end

%# --- Executes on button press in loadButton.
function loadButton_Callback(hObject, eventdata, handles)
    %# get image file location
    [fName, fPath] = uigetfile(...
        {'*.psd;*.bmp;*.jpg;*.tif;*.png;*.gif','All Image Files'; ...
        '*.*','All Files' }, 'File Selector', ...
        fullfile(matlabroot,'toolbox','images','imdemos'));
    if fPath==0
        msgbox('No file selected', 'File Selector', 'error');
        return
    end

    %# read and show image
    handles.img = imread( fullfile(fPath,fName) );
    handles.hImg = imshow(handles.img, 'Parent',handles.hAx);

    %# attach handler
    set(handles.hImg, 'ButtonDownFcn',{@imgAxis_ButtonDownFcn,handles});

    %# reenable disabled components
    set(findobj(handles.fig, 'Tag','angleSlider'), 'Enable','on')

    %# Update handles structure
    guidata(hObject, handles);
end

%# --- Executes on mouse press over axes background.
function imgAxis_ButtonDownFcn(hObject, eventdata, handles)
    %# check if some image is shown
    if isempty(handles.hImg) || ~ishandle(handles.hImg)
        return
    end

    %# select ROI using a rectangle
    hRect = imrect(handles.hAx);
    setColor(hRect, 'black');
    rectPos = wait(hRect);
    delete(hRect)

    %# crop image from rotated image, and show it
    I = imcrop(get(handles.hImg,'CData'), rectPos);
    handles.hImgCrop = imshow(I, 'Parent',handles.hAxCrop);

    %# reenable disabled components
    set(findobj(handles.fig, 'Tag','processButton'), 'Enable','on')

    %# Update handles structure
    guidata(hObject, handles);
end

problem with Slider and ButtonDownFcn in Matlab

I hope this makes it all clear


In your axes1_ButtonDownFcn, the line imshow(image, []); is what shows you the non-rotated image when you click on it. I think removing that line should get rid of your problem. You can then use gca to get your axes handle instead. In short, try this

function axes1_ButtonDownFcn(hObject, eventdata, handles)
global image  h 
h = imrect(gca);
setColor(h, 'black');
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜