【问题标题】:problem with Slider and ButtonDownFcn in MatlabMatlab中Slider和ButtonDownFcn的问题
【发布时间】:2011-09-29 11:04:37
【问题描述】:

Slider 和 ButtonDownFcn 有问题。

目前我在 GUI 中向用户显示图像(使用 GUIDE),然后我让他们通过在车牌周围绘制一个矩形来选择车牌。

我添加了滑块来以度为单位转动图像。

当我转动图像然后点击它时,图像会返回到它的初始状态(角度)。

如何确保图像保持在其位置,然后在其上绘制矩形?

这是我的 ButtonDownFcn 函数:

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

这是我的滑块功能:

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());

编辑:现在一切正常,更重要的是它很清楚。 最后一件事你知道我如何从 X 和 Y 轴上删除数字。 我尝试使用axes off,但没有帮助。

非常感谢。

【问题讨论】:

    标签: user-interface matlab button slider


    【解决方案1】:

    我相信通过例子来学习更容易。所以,我将继续我在您的previous question 中开始的示例。

    当 GUI 启动时,会显示一个图像,您可以使用滑块旋转该图像。点击图片时,选择一个矩形的ROI(可以继续旋转下方的图片)。满意后,双击矩形,裁剪后的图像显示在其他轴上(一个从旋转图像裁剪,另一个从原始图像裁剪),然后删除矩形。

    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
    

    同样,使用 GUIDE 生成的图形重新创建示例应该是类似的。高温


    编辑

    您将在下面找到由 GUIDE 生成的类似示例。和以前一样,您必须创建 GUI 并通过拖放添加组件。使用“Property Inspector”根据需要调整它们的属性。更重要的是,给每个人一个独特的Tag。我正在使用:

    • imgAxis、cropAxis、processAxis
    • 加载按钮,进程按钮
    • 角度滑块,角度文本

    最好不要使用全局变量,而是将数据存储在handles 结构中,该结构会传递给回调函数。只要记住在任何更改其数据的方法结束时调用guidata 函数,以提交更改。

    对于手动将处理程序附加到图像ButtonDownFcn 事件的部分,您还应该将handles 结构传递给参数列表。

    也就是说,这里是 GUI 背后的代码(相关部分):

    %# --- 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
    

    我希望这一切都清楚

    【讨论】:

    • 这是一个很好的答案,但我很难用 GUIDE 实现它。在您的示例中,它工作得很好,我不知道出了什么问题。
    • 通过拖放创建组件,然后设置它们的属性。 “读取/显示图像”部分应放置在图形的OpeningFcn。请注意,我没有像您那样定义全局变量,而是使用可以访问封闭函数中的任何变量的嵌套函数。在您的情况下,您应该使用传递给所有回调函数的handles 结构(只需记住在更改其数据的任何方法的末尾调用guidata 函数)。在handles 结构中,存储图像I、图像句柄(由IMSHOW 返回)和三个轴句柄。
    • 正如我所说,您应该将hImage 与其他结构一起存储在handles 结构中,然后调用GUIDATA 函数来提交更改。此外,当您注册回调时,请确保传递所有必需的参数,如:set(handles.hImage, 'ButtonDownFcn',@(o,e) axes1_ButtonDownFcn(o,e,handles));
    • @Michael:如果您阅读文档可能会有所帮助:mathworks.com/help/techdoc/creating_guis/bqz79mu.html,也许阅读一些教程:blinkdagger.com/matlab/…
    • 我又来了。对不起,如果我没有明白这个想法,但是你知道为什么不管我在图片中标记什么,盘子都不会改变它总是保持不变吗?
    【解决方案2】:

    在您的axes1_ButtonDownFcn 中,imshow(image, []); 行是当您单击它时显示未旋转图像的内容。我认为删除该行应该可以解决您的问题。然后,您可以使用 gca 来获取您的轴手柄。总之,试试这个

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

    【讨论】:

    • 感谢您的回答,但问题没有解决。现在当我转动图像并单击它时,我无法绘制矩形。你有什么新想法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-12
    相关资源
    最近更新 更多