⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rotatetool.m

📁 Rotation tool, totates a single image contained in HANDLE.HANDLE can be a handle to figure, axes, or
💻 M
📖 第 1 页 / 共 2 页
字号:
function varargout = rotatetool(varargin)% ROTATETOOL is an interface to the IMROTATE function.  %%   ROTATETOOL(HANDLE) rotates a single image contained in HANDLE.%   HANDLE can be a handle to a figure, axes, or image object.%%   To retrieve rotated image use the GETIMAGE function on the appropriate%   figure window.%% USAGE:%   [OUT] = ROTATETOOL(GRD), where GRD is a MxN of any class "above" UINT8 rotates the GRD%   array and returns it in OUT. The GRD image's representation is computed with a linear%   scaling on the [0 255] interval.%       ( img = uint8(round( ((GRD - GRD_z_min) / (GRD_z_max - GRD_z_min))*255 )) )%%   [OUT,HDR_OUT] = ROTATETOOL(GRD,HDR_IN), where HDR_IN is a header row vector with the GRD%   coordinate referencing, outputs also an updated version of the header. This header has the%   the form used by the GMT MEX programs, which is:%       [x_min x_max y_min y_max z_min z_max registratrion x_inc y_inc]%       registratrion is either 0 (for grid registration) or 1 to pixel registration.%       Interested users that want to know more must consult the GMT manual.%   NOTE: This is not the ML way of working with grids, but it's ALOT more efficient than the%   standard use of MESHGRID which implies triplicating the memory use.%%   [OUT] = ROTATETOOL(IMG), IMG is a uint8 indexed or RGB array rotates the IMG%   array and returns it in OUT.%%   [OUT] = ROTATETOOL(IMG,CMAP), uses the colormap CMAP in the preview image. If CMAP is%   not given in input and the image is indexed, a cmap = jet(256) is used.%%   [OUT,HDR_OUT] = ROTATETOOL(IMG,HDR_IN,CMAP), IMG is a uint8 indexed or RGB array. Same as%   above, but with a header info vector like in the GRD case. Use this for example if the%   IMG comes from a georeferenced image.%%   The "Apply n return" button performs the rotation on the input data and returns%   the output if it was requested.%%   The "Cancel" button just closes this figure returns nothing%% EXAMPLES:%   I = checkerboard(50);%   h = imshow(I);%   rotatetool(h)   % When satisfied push 'Apply n return' then call GETIMAGE%   B = getimage(gcf);%%   Operate on a double array, and get it rotated%   Z = peaks(128);%   grd = rotatetool(Z,jet(256));%%   Let us pretend that the Z obove is a referenced grid. So contruct first the HDR_IN vector%   hdr_in = [1 128 1 128 min(Z(:)) max(Z(:)) 0 1 1];%   [grd,hdr] = rotatetool(Z,hdr_in);%%   Demonstration mode%   rotatetool      % displays 'peppers.png' and opens GUI.%%   THIS GUI NEEDS THE IMAGE PROCESSING TOOLBOX TO RUN%%   CREDITS%       This GUI is a pure imitation of ROTATEGUI from Birju Patel and uses some code from%       that function. However, it has extended functionalities and was re-writen using R13%       syntax. Which means that it can be compiled with the V3.x compiler.%%%   AUTHOR hObject = figure('Tag','figure1','Visible','off');handles = guihandles(hObject);guidata(hObject, handles);rotatetool_LayoutFcn(hObject,handles);handles = guihandles(hObject);movegui(hObject,'east')% Some initializationshandles.frame_axesPos = get(handles.frame_axes,'Pos');handles.cancel = 0;             % It will be set to one if the cancel button is hit or the fig is killedhandles.angle = 0;handles.do_flipLR = false;handles.do_flipUD = false;handles.hOrigFigure = [];handles.hOrigImage = [];handles.OrigGrd = [];handles.in_hdr = [];            % To hold an eventual input GMT style row vector headerhandles.out_header = [];        % To hold an eventual output GMT style row vector headercmap = [];n_argout = nargout;     n_argin = numel(varargin);if (n_argin >= 1)    if (ishandle(varargin{1}))              % First argument is an image handle, or ... error        if ( strcmp(get(varargin{1},'type'),'axes') || strcmp(get(varargin{1},'type'),'fig'))            handles.hOrigImage = findobj(varargin{1},'type','image');        elseif ( strcmp(get(varargin{1},'type'),'image') )            handles.hOrigImage = varargin{1};        end        msg = [];        if (isempty(handles.hOrigImage) || numel(handles.hOrigImage) > 1)            msg = 'ERROR: None or more than one image objects found in the figure.';        end        if (n_argout)            msg = 'ERROR: Output arguments are not allowed when the input is a handle.';        end        if (~isempty(msg))            errordlg(msg,'ERROR');      delete(hObject);    return        end        handles.hOrigFigure = get(get(handles.hOrigImage,'Parent'),'Parent');    else        if (isa(varargin{1},'uint8'))           % First argument is an image array            handles.OrigImage = varargin{1};        else                                    % First arg is a "grid"            handles.OrigGrd = varargin{1};            z_min = double(min(min(handles.OrigGrd)));            z_max = double(max(max(handles.OrigGrd)));            handles.OrigImage = uint8(round( ((double(handles.OrigGrd) - z_min) / (z_max - z_min))*255 ));            cmap = jet(256);        end    end        if (n_argin == 2 && size(varargin{2},1) == 1)       % Second argument is a GMT style vector header        handles.in_hdr = varargin{2};    elseif (n_argin == 2 && size(varargin{2},2) == 3)   % Second argument is a colormap        cmap = varargin{2};    end    if (n_argin == 3)                           % There is no choice in args order here        handles.in_hdr = varargin{2};        cmap = varargin{3};    end    % One last test on CMAP & HEADER likelihood    msg = [];    if (~isempty(handles.in_hdr) && size(handles.in_hdr,2) < 4)        msg = 'ERROR: The GMT header vector is invalid';    end    if (~isempty(cmap) && size(cmap,2) ~= 3)        msg = 'ERROR: Invalid colormap in imput';    end    if (~isempty(msg))        errordlg(msg,'ERROR');      delete(hObject);    return    endelse        % Demo mode    h = figure;    handles.hOrigImage = imshow('peppers.png');    %handles.hOrigImage = imshow('pout.tif');    handles.hOrigFigure = h;end% Determine resize needed so that preivew image fits in defined area% ReductionFactor determines how to scale original image so% that it fits in the defined preview area.pImageConstr = min(handles.frame_axesPos(3),handles.frame_axesPos(4));    %Constraining dimension in image panelif (~isempty(handles.hOrigImage))    [oriImageHeight,oriImageWidth,k] = size(get(handles.hOrigImage,'Cdata'));else    [oriImageHeight,oriImageWidth,k] = size(handles.OrigImage);end%Length of Image diagonal in pixels. +5 added to allow for some panel border effectsdImage = ceil(sqrt(oriImageHeight^2 + oriImageWidth^2)) + 5;reductionFactor = (pImageConstr/dImage);if (~isempty(handles.hOrigImage))    handles.previewImage = imresize(get(handles.hOrigImage,'Cdata'),reductionFactor);else    handles.previewImage = imresize(handles.OrigImage,reductionFactor);end[imHeight,imWidth,k] = size(handles.previewImage);% Center axes containing preview image in the "image panel" so rotation will look like a pin-wheel[leftPosition,bottomPosition] = calcPosition(handles,imWidth,imHeight);    % Make the position relative to frame_axes LL cornerleftPosition = leftPosition + handles.frame_axesPos(1);bottomPosition = bottomPosition + handles.frame_axesPos(2);set(handles.axes1,'Pos',[leftPosition bottomPosition imWidth imHeight],...    'DataAspectRatio', [1 1 1], 'PlotBoxAspectRatioMode', 'auto')%display image in axeshandles.himage = displayPreviewImage(handles,handles.previewImage,cmap);%------------ Give a Pro look (3D) to the frame boxes  -------------------------------bgcolor = get(0,'DefaultUicontrolBackgroundColor');framecolor = max(min(0.65*bgcolor,[1 1 1]),[0 0 0]);set(0,'Units','pixels');    set(hObject,'Units','pixels')    % Pixels are easier to reason withh_f = findobj(hObject,'Style','Frame');for i=1:length(h_f)    frame_size = get(h_f(i),'Position');    f_bgc = get(h_f(i),'BackgroundColor');    usr_d = get(h_f(i),'UserData');    if abs(f_bgc(1)-bgcolor(1)) > 0.01           % When the frame's background color is not the default's        frame3D(hObject,frame_size,framecolor,f_bgc,usr_d)    else        frame3D(hObject,frame_size,framecolor,'',usr_d)        delete(h_f(i))    endend%------------- END Pro look (3D) -------------------------------------------------------% Choose default command line output for rotatetoolhandles.output = hObject;if (n_argout == 1 && isempty(handles.OrigGrd))      % This the only case where the Fig handle can go out    varargout{1} = hObject;endif (n_argout == 2)    handles.out_header = 1;    set(handles.popup_bboxmenu,'Enable','off')       % Don't want the head-ache of computing new limitsendhandles.n_argout = n_argout;guidata(hObject, handles);set(hObject,'Visible','on');% Check if we have to do a uiwait and what goes out (if anything)if (n_argout > 0)                       % If called with output, we must wait    uiwait(hObject);    handles = guidata(hObject);    if (handles.cancel)                 % Don't try to output eventual non-existing variables        if (n_argout == 1),     varargout{1} = [];      end        if (n_argout == 2),     varargout{1} = [];      varargout{2} = [];  end        delete(handles.figure1);        % The figure can be deleted now        return    end    varargout{1} = handles.output_grd;    if (n_argout == 2)        varargout{2} = handles.out_header;    end    delete(handles.figure1);        % The figure can be deleted nowend% ----------------------------------------------------------------------------function push_cw90_Callback(hObject, eventdata, handles)    % When the rotation button is pushed repeatedly, the rotation    % applied to the image is cumulative.  Pushing the cw button n    % times will rotate preview image 90*n degrees.    updateAngleInfo(handles,90);    updateImage(handles);% ----------------------------------------------------------------------------function push_ccw90_Callback(hObject, eventdata, handles)    updateAngleInfo(handles,-90);    updateImage(handles);% ----------------------------------------------------------------------------function push_flipLR_Callback(hObject, eventdata, handles)    newCdata = flipdim(get(handles.himage,'CData'),2);    set(handles.himage,'Cdata',newCdata);    handles.do_flipLR = ~handles.do_flipLR;     % For the Apply button    guidata(handles.figure1,handles)% ----------------------------------------------------------------------------function push_flipUD_Callback(hObject, eventdata, handles)    newCdata = flipdim(get(handles.himage,'CData'),1);    set(handles.himage,'Cdata',newCdata);    handles.do_flipUD = ~handles.do_flipUD;    guidata(handles.figure1,handles)% ----------------------------------------------------------------------------function slider_Callback(hObject, eventdata, handles)    % Affordance for manual rotation. User can drag slider to rotate preview    % image in small increments. The slider boundaries are [-180, 180].    % Text box next to slider will show values within this range.    handles.angle = get(hObject,'Value');    guidata(handles.figure1,handles)    updateImage(handles);    set(handles.edit_angRot,'String',num2str(handles.angle));% ----------------------------------------------------------------------------function edit_angRot_Callback(hObject, eventdata, handles)    % User can enter in a single scalar number (rotation angle in degrees) and image    % will be rotated by that amount.  If the input angle is out of the [-180,180]    % range, the value will be wrapped into this range using the checkAngle function.    textvalue = str2double(get(hObject,'String'));    % Expression not allowe in text field.    if (~isempty(textvalue) && ~isnan(textvalue) && isreal(textvalue))        handles.angle = checkAngle(textvalue);        guidata(handles.figure1,handles)        updateImage(handles);        set(handles.slider,'Value',handles.angle);        set(hObject,'String',num2str(handles.angle));    else        errordlg('Text field must contain a single scalar value.')    end% ----------------------------------------------------------------------------function popup_bboxmenu_Callback(hObject, eventdata, handles)    % changes bounding box option for IMROTATE    updateImage(handles);% ----------------------------------------------------------------------------function popup_interpmenu_Callback(hObject, eventdata, handles)    % changes to interp method won't be noticeable in preview image so the preview    % image will always use nearest interp. But we need to record the selected    % option in case the user exits without further rotations to image    val = get(hObject,'Value');    switch val        case 1,     handles.interpmethod = 'nearest';        case 2,     handles.interpmethod = 'bilinear';        case 3,     handles.interpmethod = 'bicubic';    end    guidata(handles.figure1,handles)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -