MATLAB set('XData'....)
У меня проблема с обновлением моего сюжета. По сути, у меня есть функция, которая создает фигуру с 3-мя участками. Затем у меня есть другая функция, которая запускает функцию создания фигуры, а затем обновляет график. Важно просто обновить, чтобы я не создавал новый график в каждом цикле, так как это трехмерные данные и для их загрузки требуется некоторое время.
Проблема заключается во втором моем сюжете. Я загружаю 3 изображения (3 среза), используя slice(), а затем хочу построить вектор положения. Сначала я установил вектор положения на (0,0,0), а затем решил, что смогу просто обновить его в своем цикле, установив для "XData", "YData"... их соответствующие значения. По какой-то причине он не работает и выдает ошибку "Неопределенная функция" XData "для входных аргументов типа" double "". Пожалуйста, помогите, ниже код, спасибо!!!
ПРИМЕЧАНИЕ --- Ошибка заключается в функции обновления графика после "%refresh 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
Обновление сюжета
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
3 ответа
Функция set
вызывается следующим образом
set(ObjectHandle, 'PropertyName_1', PropertyValue_1, 'PropertyName_2', PropertyValue_2);
добавляя больше пар имя-значение по мере необходимости. В вашем случае это было бы
set(LineHandle, 'XData', DICOMPos(1), 'YData', DICOMPos(2), 'ZData', DICOMPos(3));
для изменения данных позиции. Обратите внимание, что все эти свойства принадлежат линии, а не осям, поэтому вам нужно получить дескриптор обновляемой линии. Предполагая, что оси содержат только одну строку, это можно сделать произвольно, добавив этот код перед циклом:
LineHandle = findobj(Fig.sub2, 'type', 'line');
Кроме того, вы не можете изменить стиль линии следующим образом: set(LineHandle, 'b*')
, Это является причиной ошибки "Недопустимые аргументы пара параметр / значение".
Во-первых, вам нужно имя свойства перед каждым значением свойства, а во-вторых, на самом деле нет имени свойства для стиля линии. Вы должны изменить цвет и маркер отдельно, например, так:
set(LineHandle, 'Marker', '*', 'Color', 'b');
Ошибка говорит вам, что вы используете XData как функцию где-то, и у вас нет этой функции. Это происходит, когда вы звоните
XData(DICOMPos(1))
Вы делаете то же самое для данных Y и Z. Это не то, как вы используете функцию. Я предполагаю, что вы редактируете чужой код? Какие данные вы пытаетесь заменить на оси? DICOMPos(1)?
Причина, по которой этот код был неправильным, была немного хитрой... или, по крайней мере, не так, как я ожидал. Я пытался получить доступ к фиг.2, которая определяла оси фиг.2им вместо прямого доступа к фиг.2им. Причина, по которой я пытался определить новые "XData" для Fig2, заключается в том, что для Fig2im MATLAB постоянно сообщал мне, что дескриптор был удален или недействителен. Это потому, что мой slice() перезаписывал мой plot3() в моей первоначальной настройке графика, поэтому Fig.sub2im больше не был тем, кем я хотел.
Чтобы это исправить, все, что мне нужно было сделать, это отредактировать Fig2 на Fig2im, а затем удерживать; после моего сюжета3.