Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab:在GUI中同时在两个图像上显示十字光标_Matlab_User Interface_Image Processing_Matlab Guide - Fatal编程技术网

Matlab:在GUI中同时在两个图像上显示十字光标

Matlab:在GUI中同时在两个图像上显示十字光标,matlab,user-interface,image-processing,matlab-guide,Matlab,User Interface,Image Processing,Matlab Guide,我正在使用指南构建一个MatlabGUI,用于处理医学图像(MRI扫描上的脑肿瘤分割)。作为预处理步骤,程序会记录不同的扫描,如下所示: 现在我想在两个图像上显示十字光标,作为对共同注册的视觉检查。十字准线应相互链接,以便它们指向两幅图像中的同一像素。此外,当鼠标悬停(或单击)其中一个图像时,它应该移动。这就是我想要实现的目标: 是否存在可以实现这一点的内置MATLAB函数?或者,如果我必须自己编写,如何解决这个问题?我将使用玩具GUI来展示它的工作原理: 让我们首先尝试使其仅适用于第一个

我正在使用指南构建一个MatlabGUI,用于处理医学图像(MRI扫描上的脑肿瘤分割)。作为预处理步骤,程序会记录不同的扫描,如下所示:

现在我想在两个图像上显示十字光标,作为对共同注册的视觉检查。十字准线应相互链接,以便它们指向两幅图像中的同一像素。此外,当鼠标悬停(或单击)其中一个图像时,它应该移动。这就是我想要实现的目标:


是否存在可以实现这一点的内置MATLAB函数?或者,如果我必须自己编写,如何解决这个问题?

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

让我们首先尝试使其仅适用于第一个图像。您想要实现的是:

  • 当用户单击图形时,我们希望能够访问鼠标单击的位置
  • 然后我们要检查点击是否位于第一个图像内
  • 如果是,我们要更新纵横杆的位置,它将由叠加在图像上的两条线表示,并在选定点交叉
步骤0:初始设置 您首先要确定一些细节:

  • 确保在两次
    imshow
    调用后都添加了对
    hold on
    的调用,否则横杆将删除图像而不是覆盖图像
步骤1:获取鼠标单击的位置 在GUI打开功能中(此处为
SuperDuperGUI\u 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
%获取第一幅图像的位置(我们只对宽度感兴趣)
%axes1对象的大小和高度)
Img1Pos=get(handles.axes1,'Position')
%检查是否在里面
if(光标点(1,1)=0)
%做事
结束
步骤3:如果点击在第一张图像内,则更新纵横杆的位置
%检查是否在内部
if(光标点(1,1)=0)
Lines=findobj('Type','line','Parent',handles.axes1);
如果为空(行)
%如果Lines为空,则需要创建line对象
行([0 Img1Pos(3)],[cursorPoint(1,2)cursorPoint(1,2)],'Color','g','Parent',handles.axes1);
行([cursorPoint(1,1)cursorPoint(1,1)],[0 Img1Pos(4)],'Color','g','Parent',handles.axes1);
其他的
%如果没有,我们只更新两行的XData和YData字段
第(1)行。扩展数据=[0 Img1Pos(3)];%没有必要,但为了清楚起见,我会把它放在那里
第(1)行。YData=[光标点(1,2)光标点(1,2)];
第(2)行。扩展数据=[光标点(1,1)光标点(1,1)];
第(2)行。YData=[0 Img1Pos(4)];%没有必要,但为了清楚起见,我会把它放在那里
结束
结束
结果:

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

Edit 下面的代码灵感来自BillBokeey的答案,对此我非常感谢

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

% 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
函数getMousePositionInImage(src,事件) %获取当前句柄结构 handles=guidata(src); %以AXES1的轴单位获取坐标(这里我选择定义它们) %作为用户单击点的像素) cursorPoint1=get(handles.axes2,'CurrentPoint'); cursorPoint2=get(handles.axes3,“CurrentPoint”); %获取第一张图像的位置(我们只对宽度感兴趣) %axes1对象的大小和高度) 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'); %检查是否在里面 如果(光标点1(1)=YLim1(1)) Lines1=findobj('Type','line','Parent',handles.axes2); Lines2=findobj('Type','line','Parent',handles.axes3); 如果为空(第1行) %如果Lines为空,则需要创建line对象 行(XLim1,[cursorPoint1(1,2)cursorPoint1(1,2)],'Color','g','Parent',handles.axes2); 行([cursorPoint1(1,1)cursorPoint1(1,1)],YLim1,'Color','g','Parent',handles.axes2); 行(XLim2,[cursorPoint1(1,2)cursorPoint1(1,2)],'Color','g','Parent',handles.axes3); 行([cursorPoint1(1,1)cursorPoint1(1,1)],YLim2,'Color','g','Parent',handles.axes3); 其他的 %如果没有,我们只更新两行的XData和YData字段 行1(1).扩展数据=XLim1;%没有必要,但为了清楚起见,我会把它放在那里 第1(1)行。YData=[光标点1(1,2)光标点1(1,2)]; 行1(2).扩展数据=[cursorPoint1(1,1)cursorPoint1(1,1)]; 第1(2)行。YData=YLim1;%没有必要,但为了清楚起见,我会把它放在那里 Lines2(1).扩展数据=XLim2;%没有必要,但为了清楚起见,我会把它放在那里 Lines2(1).YData=[光标点1(1,2)光标点1(1,2)]; 行2(2).扩展数据=[cursorPoint1(1,1)cursorPoint1(1,1)]; Lines2(2).YData=YLim2;%没有必要,但为了清楚起见,我会把它放在那里 结束 elseif(光标点2(1)=YLim2(1)) Lines1=findobj('Type','line','Parent',handles.axes2); Lines2=findobj('Type','line','Parent',handles.axes3); 如果为空(第2行) %如果Lines为空,则需要创建line对象 第(XLi)行
    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