我遇到了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
,但没有帮助。
非常感谢。
答案 0 :(得分: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生成的图重新创建示例应该是类似的。 HTH
您将在下面找到GUIDE生成的类似示例。和以前一样,您必须创建GUI并通过拖放添加组件。使用“Property Inspector”根据需要调整其属性。更重要的是,给每个人一个独特的Tag
。我正在使用:
最好不要使用全局变量,而是将数据存储在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
我希望这一切都清楚
答案 1 :(得分:0)
在axes1_ButtonDownFcn
,imshow(image, []);
行显示单击时未旋转的图像。我认为删除该行应该摆脱你的问题。然后,您可以使用gca
代替您的轴。简而言之,试试这个
function axes1_ButtonDownFcn(hObject, eventdata, handles)
global image h
h = imrect(gca);
setColor(h, 'black');