Вопрос

I'm having a problem updating my plot. Basically, I have a function that creates a figure with 3 subplots. Then I have another function that runs the create figure function and then updates the plot. It's important to just update so I don't create a new graph each loop since it's 3d data and takes a while to load.

The problem lies in my second subplot. I load 3 images (3 slices) using slice() and then also want to plot a position vector. I set my position vector to (0,0,0) initially, then I thought I could just update it in my loop by setting the 'XData', 'YData'... to their respective values. For some reason it's not working and is spitting the error "Undefined function 'XData' for input arguments of type 'double'." Please help, below is the code, thanks!!!

NOTE--- The error lies in the update plot function after "%refresh plot"

Initial Plot

function [Fig] = EndoSliceViewer_createFigure(Figindex,DICOMparam)
%This function creates and returns a Figure object to visualizes DICOM data
%in the plane orthogonal to the endoscopic view, the RGB view of the camera
%and the orientation of the navigation

%set resolution for Endo Slice Plot
Fig.resolEndoSlice=300; 
Fig.resolEndoRGB=[720 1280]; 
Fig.resolEndoNavi=[500 500 500]; 

%init figure on screen
Fig.fig=figure(Figindex); gcf;
set(Fig.fig,'Position',[50 500 1500 500],'Name','Endo Slice Viewer');
%set(Fig.fig,'KeyPressFcn','global kpressed; global Fig; kpressed = get(Fig.fig,''CurrentChar'');');

Fig.sub1=subplot(1,3,1);
Fig.sub1im=image(uint8(zeros(Fig.resolEndoRGB(1), Fig.resolEndoRGB(2),3)));
title('Endo Camera View');
daspect([1 1 1]);

Fig.sub2=subplot(1,3,2);
Fig.sub2im=plot3(0,0,0);
h=slice(DICOMparam.Vd,DICOMparam.Cx,DICOMparam.Cy,DICOMparam.Cz);
colormap bone;
set(h,'FaceColor','interp',...
    'EdgeColor','none',...
    'DiffuseStrength',.8)
title('Navigation View');
xlim([-0.2*Fig.resolEndoNavi(1),  1.2*Fig.resolEndoNavi(1)]);
ylim([-0.2*Fig.resolEndoNavi(2),  1.2*Fig.resolEndoNavi(2)]);
zlim([-0.2*Fig.resolEndoNavi(3),  1.2*Fig.resolEndoNavi(3)]);
xlabel('X [vox]');
ylabel('Y [vox]');
zlabel('Z [vox]');
daspect([1 1 1]);

Fig.sub3=subplot(1,3,3);
Fig.sub3im=imagesc(zeros(Fig.resolEndoSlice, Fig.resolEndoSlice));
title('Endo Slice View');
xlim([0 Fig.resolEndoSlice]);
ylim([0 Fig.resolEndoSlice]);
xlabel('Xendo [vox]');
ylabel('Yendo [vox]');
daspect([1 1 1]);
colormap bone
drawnow;

%potentially: add subplot for navigation position display later
end

Update Plot

function [  ] = EndoSliceViewerJP( Naviparam,  DICOMparam)
%RGBparam should be included later - add +1 to nargin values 

%visualizes: 
%1st: RGB camera Live view 
%2nd: Orientation and Position of Navigation System
%3rd: DICOM Slice relative to navigated Endoscope in a and its orientation
%in a Slice perpendicular to the endoscope
%assumes Navigation system running with referenced tool (Naviparam.tool=4 or Naviparam.tool=5)

%currently this plots slices according to Endoscope position, could add
%vector in plot that shows orientation of the scope...
disp('Endo Slice Viewer');
disp('" ": exit on space key');
global kpressed;
kpressed = 0;

global Fig
Fig=EndoSliceViewer_createFigure(1,DICOMparam);
set(Fig.fig,'KeyPressFcn','global kpressed; global Fig; kpressed = get(Fig.fig,''CurrentChar'');');

%create matrices and filter for smoothing of Endo Slice Data
xrel=-(ones(Fig.resolEndoSlice,1)*(1:Fig.resolEndoSlice)-Fig.resolEndoSlice/2)';
yrel=-(ones(Fig.resolEndoSlice,1)*(1:Fig.resolEndoSlice)-Fig.resolEndoSlice/2);
SLimage=zeros(Fig.resolEndoSlice,Fig.resolEndoSlice);
PosVec=zeros(Fig.resolEndoSlice,Fig.resolEndoSlice,3);
gfilt = fspecial('gaussian',5,1.5);
depth = 50;


exitflag = 0;
while (exitflag == 0)
     %check on keyboard input
     if kpressed ~= 0
        switch kpressed
            case 'r'
                depth=depth+2
            case 'f'
                depth=depth-2
            case ' '
                exitflag = 1;
                disp('**** Exit Endo Slice Viewer ****')

        end
        kpressed = 0;
     end

if (nargin>=1) %Naviparam is passed - update Navigation View
     %capture new navigation data
     Naviparam=Navi_acquire(Naviparam);
     Naviparam=Navi_calc_data(Naviparam);

     %refreshN avigation View
     %NOT YET IMPLEMENTED: UPDATE NAVIGATION PLOT 

     if (nargin==2) %DICOMparam is also passed - update EndoSlice View
         EndoVecX=inv(DICOMparam.calib.navi2dicom(1:3,1:3))*inv(Naviparam.data.Endo_RefHomMat(1:3,1:3))*[1;0;0];
         EndoVecY=inv(DICOMparam.calib.navi2dicom(1:3,1:3))*inv(Naviparam.data.Endo_RefHomMat(1:3,1:3))*[0;1;0];
         EndoVecZ=inv(DICOMparam.calib.navi2dicom(1:3,1:3))*inv(Naviparam.data.Endo_RefHomMat(1:3,1:3))*[0;0;-1];
         disp(Naviparam.data.Endo_RefHomMat(1:3,1:3));
         EndoVecX=EndoVecX/norm(EndoVecX);
         EndoVecY=EndoVecY/norm(EndoVecY);
         EndoVecZ=EndoVecZ/norm(EndoVecZ);
         mask=ones(Fig.resolEndoSlice,Fig.resolEndoSlice);
         S=[DICOMparam.Sx; DICOMparam.Sy; DICOMparam.Sz];

         DICOMPos = DICOMparam.calib.navi2dicom*[Naviparam.data.Endo_RefOffsetPosVec;1];

         for i=1:3
             %Point on Plane defined by Endo Position plus distance*Viewing direction vector
             PosVec(:,:,i)=(DICOMPos(i)+depth*EndoVecZ(i))+xrel*EndoVecX(i)+yrel*EndoVecY(i);
             %limit positions to integer values inside DICOM data cube
             PosVec(:,:,i)=round(PosVec(:,:,i));
             PosVec(:,:,i)=min(max(PosVec(:,:,i),1),S(i));
             %create mask to set Points outside the data cube to 0
             mask=double(PosVec(:,:,i)>1).*double(PosVec(:,:,i)<S(i).*mask(:,:));
         end
         %access data cube via indexed labelling
         XposTemp=PosVec(:,:,1); YposTemp=PosVec(:,:,2); ZposTemp=PosVec(:,:,3);
         indexTemp=sub2ind(size(DICOMparam.Vd), XposTemp(:), YposTemp(:),ZposTemp(:));
         SLimage(:)=DICOMparam.Vd(indexTemp(:));

         SLimage=SLimage.*mask;
         SLimage=imfilter(SLimage,gfilt);

         %refresh plot
         set(Fig.sub3im, 'cdata', SLimage);
     axes(Fig.sub2);
     set(lineseries, 'XData', DICOMPos(1), 'YData', DICOMPos(2), 'ZData', DICOMPos(3));
     set(lineseries, 'Marker', '*', 'Color', 'b');
     disp(DICOMPos);
     end
end

%RGBparam is always passed - update RGB camera View
%capture new RGB data
%handles.RGBparam=RGB_acquire(handles.RGBparam);
%refresh RGB camera View
%set(Fig.sub1im, 'CData', imresize(handles.RGBparam.image,[Fig.resolEndoRGB(1) Fig.resolEndoRGB(2)]));  


drawnow;
end

close(Fig.fig);
clear global;


end
Это было полезно?

Решение

The function set is called in the following manner

set(ObjectHandle, 'PropertyName_1', PropertyValue_1, 'PropertyName_2', PropertyValue_2);

adding more name-value pairs as fit. In your case that would be

set(LineHandle, 'XData', DICOMPos(1), 'YData', DICOMPos(2), 'ZData', DICOMPos(3));

for changing the position data. Note that all of these properties belong to the line, not the axes, so you need to get a handle for the line you are updating. Assuming the axes contains only one line this can be done ad-hoc by adding this code before the loop:

LineHandle = findobj(Fig.sub2, 'type', 'line');

Also, you can't change the linestyle in this manner: set(LineHandle, 'b*'). This is the reason for the error "Invalid parameter/value pair arguments."

First off, you need a property name before each property value, and second, there is actually no property name for the linestyle. You have to change the color and the marker separately, for example like this:

set(LineHandle, 'Marker', '*', 'Color', 'b');

Другие советы

The error is telling you that you are using XData like a function somewhere and you don't have that function. This happens when you call

XData(DICOMPos(1))

You are doing the same thing for the Y and Z data. This is not how you use the function. I'm guessing you are editing someone else's code? What is the data you are trying to replace into the axes? DICOMPos(1)?

The reason this code was wrong was a little tricky...or at least not in the way I expected. I was trying to access Fig.sub2 which defined the axes of Fig.sub2im instead of directly accessing Fig.sub2im. The reason I was trying to define new 'XData' for Fig.sub2 is because for Fig.sub2im MATLAB kept telling me the handle was deleted or invalid. This is because my slice() was overwriting my plot3() in my initial plot setup, therefore Fig.sub2im was no longer what I wanted it to be.

To fix this, all I had to do was edit Fig.sub2 to Fig.sub2im and then put hold on; after my plot3.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top