Matlab:在GUI中的两个图像上同时显示十字准线

时间:2016-06-29 08:20:00

标签: matlab user-interface image-processing matlab-guide

我使用GUIDE构建MATLAB GUI来处理医学图像(MRI扫描时的脑肿瘤分割)。作为预处理步骤,程序会对不同的扫描进行核心处理,如下所示:

enter image description here

我现在想要在两个图像上显示十字准线作为核心注册的目视检查。十字准线应该彼此链接,使得它们指向两个图像中的相同像素。此外,它应该在悬停(或点击)其中一个图像时移动。这就是我想要实现的目标:

enter image description here

是否存在可以实现此目的的内置MATLAB函数?或者,如果我必须自己编写,那么如何处理这个问题呢?

2 个答案:

答案 0 :(得分:1)

我将使用玩具GUI来展示它的工作原理:

enter image description here

让我们首先尝试让它仅适用于第一张图片。你想要达到的目标是:

  • 当用户点击该图时,我们希望能够访问鼠标点击的位置。
  • 然后我们要检查点击是否位于第一张图片
  • 如果是,我们想要更新横杆的位置,横杆的位置将由两条线覆盖在图像上并在选定点交叉。

步骤0:初始设置

您想先确定一些细节:

  • 请确保在hold on个来电之后添加对imshow的来电,否则横线会删除您的图片而不是覆盖在其上。

步骤1:获取鼠标点击位置

在您的GUI开启功能(此处为SuperDuperGUI_OpeningFcn)中,您想要添加一个电话:

set(gcf, 'WindowButtonDownFcn', @getMousePositionOnImage);

每次用户在GUI中单击时,这将触发函数getMousePositionOnImage

然后,您要添加并实现函数getMousePositionOnImage

function getMousePositionOnImage(src, event)

% Fetch the current handles structure
handles = guidata(src);

% Get the coordinate IN THE AXES UNITS OF AXES1 (Here I chose to define them
% as pixels) of the point where the user clicked
cursorPoint = get(handles.axes1, 'CurrentPoint')

步骤2:检查鼠标是否在第一张图像内

仍在getMousePositionOnImage函数中:

% Get the Position of the first image (We're only interested by the width
% and height of the axes1 object)
Img1Pos=get(handles.axes1,'Position')

% Check if inside
if(cursorPoint(1,1)<Img1Pos(3)&&cursorPoint(1,2)<Img1Pos(4)&&cursorPoint(1,1)>=0&&cursorPoint(1,2)>=0)

    % Do stuff

end

步骤3:如果点击位于第一张图片内,请更新横杆的位置

% Check if inside
if(cursorPoint(1,1)<Img1Pos(3)&&cursorPoint(1,2)<Img1Pos(4)&&cursorPoint(1,1)>=0&&cursorPoint(1,2)>=0)


   Lines=findobj('Type','line','Parent',handles.axes1);

   if isempty(Lines)

   % If Lines is empty, we need to create the line objects
   line([0 Img1Pos(3)],[cursorPoint(1,2) cursorPoint(1,2)],'Color','g','Parent',handles.axes1); 
   line([cursorPoint(1,1) cursorPoint(1,1)],[0 Img1Pos(4)],'Color','g','Parent',handles.axes1); 



   else

  % If not, we just update the fields XData and YData of both Lines
  Lines(1).XData=[0 Img1Pos(3)]; % Unnecessary but I'll leave it there for clarity
  Lines(1).YData=[cursorPoint(1,2) cursorPoint(1,2)];


  Lines(2).XData=[cursorPoint(1,1) cursorPoint(1,1)]; 
  Lines(2).YData=[0 Img1Pos(4)]; % Unnecessary but I'll leave it there  for clarity


   end




end

结果:

enter image description here

现在我将让你做最后一部分,其中涉及链接两个横杆。而不是仅检查点击是否在第一张图像上,您将分别检查两者。然后,如果它位于其中一个图像中,您将两个横杆更新到右轴对象中的点击位置

答案 1 :(得分:0)

修改

以下代码的灵感来自BillBokeey的答案,对此我非常感激。

首先,执行BillBokeey解决方案的第0步和第1步。然后我把这个函数放在我的代码中:

    function getMousePositionOnImage(src, event)
    % Fetch the current handles structure
    handles = guidata(src);

    % Get the coordinate IN THE AXES UNITS OF AXES1 (Here I chose to define them
    % as pixels) of the point where the user clicked
    cursorPoint1 = get(handles.axes2, 'CurrentPoint');
    cursorPoint2 = get(handles.axes3, 'CurrentPoint');

    % Get the Position of the first image (We're only interested by the width
    % and height of the axes1 object)
    Img1Pos = getpixelposition(handles.axes2);
    Img2Pos = getpixelposition(handles.axes3);

    XLim1 = get(handles.axes2, 'XLim');
    YLim1 = get(handles.axes2, 'YLim');

    XLim2 = get(handles.axes3, 'XLim');
    YLim2 = get(handles.axes3, 'YLim');

    % Check if inside
    if (cursorPoint1(1)<XLim1(2) && cursorPoint1(2)<YLim1(2) && cursorPoint1(1)>=XLim1(1) && cursorPoint1(1)>=YLim1(1)) 
        Lines1=findobj('Type','line','Parent',handles.axes2);
        Lines2=findobj('Type','line','Parent',handles.axes3);

        if isempty(Lines1)
            % If Lines is empty, we need to create the line objects
            line(XLim1,[cursorPoint1(1,2) cursorPoint1(1,2)],'Color','g','Parent',handles.axes2); 
            line([cursorPoint1(1,1) cursorPoint1(1,1)],YLim1,'Color','g','Parent',handles.axes2); 

            line(XLim2,[cursorPoint1(1,2) cursorPoint1(1,2)],'Color','g','Parent',handles.axes3); 
            line([cursorPoint1(1,1) cursorPoint1(1,1)],YLim2,'Color','g','Parent',handles.axes3); 
        else
            % If not, we just update the fields XData and YData of both Lines
            Lines1(1).XData=XLim1; % Unnecessary but I'll leave it there for clarity
            Lines1(1).YData=[cursorPoint1(1,2) cursorPoint1(1,2)];

            Lines1(2).XData=[cursorPoint1(1,1) cursorPoint1(1,1)]; 
            Lines1(2).YData=YLim1; % Unnecessary but I'll leave it there  for clarity

            Lines2(1).XData=XLim2; % Unnecessary but I'll leave it there for clarity
            Lines2(1).YData=[cursorPoint1(1,2) cursorPoint1(1,2)];

            Lines2(2).XData=[cursorPoint1(1,1) cursorPoint1(1,1)]; 
            Lines2(2).YData=YLim2; % Unnecessary but I'll leave it there  for clarity
        end

    elseif (cursorPoint2(1)<XLim2(2) && cursorPoint2(2)<YLim2(2) && cursorPoint2(1)>=XLim2(1) && cursorPoint2(1)>=YLim2(1))
        Lines1=findobj('Type','line','Parent',handles.axes2);
        Lines2=findobj('Type','line','Parent',handles.axes3);

        if isempty(Lines2)
            % If Lines is empty, we need to create the line objects
            line(XLim1,[cursorPoint2(1,2) cursorPoint2(1,2)],'Color','g','Parent',handles.axes2); 
            line([cursorPoint2(1,1) cursorPoint2(1,1)],YLim1,'Color','g','Parent',handles.axes2); 

            line(XLim2,[cursorPoint2(1,2) cursorPoint2(1,2)],'Color','g','Parent',handles.axes3); 
            line([cursorPoint2(1,1) cursorPoint2(1,1)],YLim2,'Color','g','Parent',handles.axes3); 
        else
            % If not, we just update the fields XData and YData of both Lines
            Lines1(1).XData=XLim1; % Unnecessary but I'll leave it there for clarity
            Lines1(1).YData=[cursorPoint2(1,2) cursorPoint2(1,2)];

            Lines1(2).XData=[cursorPoint2(1,1) cursorPoint2(1,1)]; 
            Lines1(2).YData=YLim1; % Unnecessary but I'll leave it there  for clarity

            Lines2(1).XData=XLim2; % Unnecessary but I'll leave it there for clarity
            Lines2(1).YData=[cursorPoint2(1,2) cursorPoint2(1,2)];

            Lines2(2).XData=[cursorPoint2(1,1) cursorPoint2(1,1)]; 
            Lines2(2).YData=YLim2; % Unnecessary but I'll leave it there  for clarity
        end

    end