diff --git a/ShoulderCase/@Muscle/Muscle.m b/ShoulderCase/@Muscle/Muscle.m index 0f95078..a523724 100644 --- a/ShoulderCase/@Muscle/Muscle.m +++ b/ShoulderCase/@Muscle/Muscle.m @@ -1,85 +1,85 @@ classdef Muscle < handle % The Muscle class is linked to a segmented muscle file (a mask) % and to the slice it has been segmented out of. % % Then, this class can measured values linked to the PCSA and the % muscle's degeneration. properties name = ""; segmentationSet = ""; sliceName = ""; PCSA = nan; atrophy = nan; fat = nan; osteochondroma = nan; degeneration = nan; container = []; end methods function obj = Muscle(musclesContainer,muscleName) obj.container = musclesContainer; obj.name = muscleName; [~, ~] = mkdir(obj.dataPath); [~, ~] = mkdir(obj.dataMaskPath); [~, ~] = mkdir(obj.dataContourPath); end function output = dataPath(obj) output = fullfile(obj.container.dataPath, obj.name); end function output = dataMaskPath(obj) output = fullfile(obj.dataPath, "mask"); end function output = dataContourPath(obj) output = fullfile(obj.dataPath, "contour"); end function output = getValues(obj) output = cellfun(@(property) obj.(property), properties(obj),... 'UniformOutput',false); end function output = summary(obj) summary.name = string(obj.name); summary.segmentationSet = string(obj.segmentationSet); summary.sliceName = string(obj.sliceName); summary.PCSA = obj.PCSA; summary.atrophy = obj.atrophy; summary.fat = obj.fat; summary.osteochondroma = obj.osteochondroma; summary.degeneration = obj.degeneration; output = struct2table(summary); end function measure(obj,sliceName, segmentationSet) obj.sliceName = sliceName; obj.segmentationSet = segmentationSet; try measurer = MuscleMeasurer(obj); obj.PCSA = measurer.getPCSA; obj.atrophy = measurer.getRatioAtrophy; obj.fat = measurer.getRatioFat; obj.osteochondroma = measurer.getRatioOsteochondroma; obj.degeneration = measurer.getRatioDegeneration; end end function output = loadMask(obj) output = imread(fullfile(obj.dataMaskPath,obj.segmentationSet + "_Mask.png")) > 0; end function output = loadPixelCoordinates(obj) - output = load(fullfile(obj.container.slicesDataPath,... + output = load(fullfile(obj.container.dataSlicesPath,... obj.sliceName + "_PixelCoordinates.mat")).imagesPixelCoordinates; end end end diff --git a/ShoulderCase/@RotatorCuff/plot.m b/ShoulderCase/@RotatorCuff/plot.m new file mode 100644 index 0000000..057e30e --- /dev/null +++ b/ShoulderCase/@RotatorCuff/plot.m @@ -0,0 +1,40 @@ +function output = plot(obj,varargin) + % For now this function is specific to plotting the rotator cuff segmentation + % results + + if nargin == 2 + error('Provide the slice name and the mask name or provide nothing (auto slice and segmentations will be plotted).') + elseif nargin == 3 + sliceName = varargin{1} + "_ForSegmentation.png"; + maskName = varargin{2} + "_Mask.png"; + else + sliceName = "rotatorCuffMatthieu_ForSegmentation.png"; + maskName = "autoMatthieu_Mask.png"; + end + + rotatorCuffCrossSection = imread(fullfile(obj.dataSlicesPath,sliceName)); + + leg = {}; + plotHandle(1) = imshow(rotatorCuffCrossSection); + hold on + muscleColor = containers.Map; + muscleColor("SC") = "b"; + muscleColor("SS") = "r"; + muscleColor("IS") = "g"; + muscleColor("TM") = "y"; + + for muscleName = ["SC", "SS", "IS", "TM"] + try + segmentedImage = imread(fullfile(obj.(muscleName).dataMaskPath,maskName)); + catch + continue + end + + if (max(segmentedImage,[],'all') > 0) % if segmentation result is not empty + leg{end+1} = muscleName; + [~,plotHandle(end+1)] = contour(segmentedImage,'color',muscleColor(muscleName)); + end + end + plotHandle(end+1) = legend(leg); + output = plotHandle; +end diff --git a/ShoulderCase/@RotatorCuff/plot3.m b/ShoulderCase/@RotatorCuff/plot3.m new file mode 100644 index 0000000..64528ec --- /dev/null +++ b/ShoulderCase/@RotatorCuff/plot3.m @@ -0,0 +1,23 @@ +function output = plot3(obj) + muscleColor = containers.Map; + muscleColor("SC") = "b"; + muscleColor("SS") = "r"; + muscleColor("IS") = "g"; + muscleColor("TM") = "y"; + plotHandle = []; + + for muscleName = ["SC", "SS", "IS", "TM"] + try + centroidPoint = obj.(muscleName).getCentroid().coordinates; + contourPoints = obj.(muscleName).getContour().coordinates; + plotHandle(end+1) = scatter3(centroidPoint(:,1), centroidPoint(:,2), centroidPoint(:,3),... + "MarkerEdgeColor", muscleColor(muscleName),... + "MarkerFaceColor", muscleColor(muscleName)); + hold on + plotHandle(end+1) = scatter3(contourPoints(:,1), contourPoints(:,2), contourPoints(:,3),... + "MarkerEdgeColor", muscleColor(muscleName)); + end + end + + output = plotHandle; +end \ No newline at end of file diff --git a/ShoulderCase/@ShoulderCasePlotter/plot.m b/ShoulderCase/@ShoulderCasePlotter/plot.m index fb26f4e..ed4fd78 100644 --- a/ShoulderCase/@ShoulderCasePlotter/plot.m +++ b/ShoulderCase/@ShoulderCasePlotter/plot.m @@ -1,94 +1,94 @@ function plot(obj) % set method colors autoColors = {'b','cyan'}; manualColors = {'#D95319','#ffcc00'}; % plot scapula data axes(obj.axesHandle('scapula')); hold on; grid on axis vis3d auto = containers.Map; try auto('landmarks') = obj.SCase.shoulderAuto.scapula.plotLandmarks(autoColors{2},autoColors{2}); end try auto('scapula surface') = obj.SCase.shoulderAuto.scapula.plotSurface(autoColors{1},autoColors{1}); end try auto('glenoid surface') = obj.SCase.shoulderAuto.scapula.glenoid.plot(); end try auto('coordinate system') = obj.SCase.shoulderAuto.scapula.coordSys.plot(autoColors{1},false); end manual = containers.Map; try manual('landmarks') = obj.SCase.shoulderManual.scapula.plotLandmarks(manualColors{2},manualColors{2}); end try manual('scapula surface') = obj.SCase.shoulderManual.scapula.plotSurface(manualColors{1},manualColors{1}); end try manual('glenoid surface') = obj.SCase.shoulderManual.scapula.glenoid.plot(); end try manual('coordinate system') = obj.SCase.shoulderManual.scapula.coordSys.plot(manualColors{1},false); end outliersNormLimit = 10; difference = containers.Map; try difference('difference') = obj.SCase.plotManualAutoDifferences(outliersNormLimit); end % plot centered coordinate system axes(obj.axesHandle('centered coordinate system')); hold on; grid on axis vis3d try auto('centered coordinate system') = obj.SCase.shoulderAuto.scapula.coordSys.plot(autoColors{1},true); end try manual('centered coordinate system') = obj.SCase.shoulderManual.scapula.coordSys.plot(manualColors{1},true); end % plot muscles segmentation axes(obj.axesHandle('auto muscles')); title('Auto segmentation with auto landmarks'); hold on; try - auto('rotator cuff') = obj.SCase.shoulderAuto.muscles.plot(); + auto('rotator cuff') = obj.SCase.shoulderAuto.rotatorCuff.plot(); end axes(obj.axesHandle('scapula')) try - auto("rotator cuff") = [auto("rotator cuff") obj.SCase.shoulderAuto.muscles.plot3()]; + auto("rotator cuff") = [auto("rotator cuff") obj.SCase.shoulderAuto.rotatorCuff.plot3()]; end axes(obj.axesHandle('manual muscles')); title('Auto segmentation with manual landmarks'); hold on; try - manual('rotator cuff') = obj.SCase.shoulderManual.muscles.plot(); + manual('rotator cuff') = obj.SCase.shoulderManual.rotatorCuff.plot(); end axes(obj.axesHandle('scapula')) try - manual("rotator cuff") = [manual("rotator cuff") obj.SCase.shoulderManual.muscles.plot3()]; + manual("rotator cuff") = [manual("rotator cuff") obj.SCase.shoulderManual.rotatorCuff.plot3()]; end % store the data handles obj.plotHandle.auto = auto; obj.plotHandle.manual = manual; obj.plotHandle.difference = difference; end \ No newline at end of file