diff --git a/ChangeLog.m b/ChangeLog.m index c51f90b..6f2b336 100755 --- a/ChangeLog.m +++ b/ChangeLog.m @@ -21,6 +21,12 @@ % % *Change log* % +% _*Version 5.1* created on 2020-09-15 by Luca Della Santina_ +% +% + Optional saving of different cut parts +% + Delete objects from graphical editor +% + Renamed loadImage.m to loadImageStack.m to disambiguate among apps +% % _*Version 5.0* created on 2020-09-14 by Luca Della Santina_ % % + Visual editor for fiducial cut points @@ -164,4 +170,4 @@ % % bug fixed the file selector for reference points % % _*Version 1.0* created on 2017-09-01 by Luca Della Santina_ -% \ No newline at end of file +% diff --git a/VolumeCut.mlapp b/VolumeCut.mlapp index 8e0f6fb..2b318bb 100644 Binary files a/VolumeCut.mlapp and b/VolumeCut.mlapp differ diff --git a/VolumeCut.mlappinstall b/VolumeCut.mlappinstall index 8115adb..86b31bc 100644 Binary files a/VolumeCut.mlappinstall and b/VolumeCut.mlappinstall differ diff --git a/VolumeCut.prj b/VolumeCut.prj index 3568c17..d3da7cb 100644 --- a/VolumeCut.prj +++ b/VolumeCut.prj @@ -1,5 +1,5 @@ - + VolumeCut Luca Della Santina @@ -13,8 +13,8 @@ Cut image volumes along arbitrary surfaces Copyright 2017-2020 Luca Della Santina Licensed under the term of GPL v3 - /tmp/tp6b9c4b36_a13f_45d6_bbd4_45541cf2fa4f.png - 5.0 + /tmp/tp0c8c39bb_7de3_4006_8bf6_fc3f84df506f.png + 5.1 MATLAB Image Processing Toolbox @@ -46,7 +46,7 @@ Licensed under the term of GPL v3 ${PROJECT_ROOT}/cutVolume.m ${PROJECT_ROOT}/editStruct.m ${PROJECT_ROOT}/gridfit.m - ${PROJECT_ROOT}/loadImage.m + ${PROJECT_ROOT}/loadImageStack.m ${PROJECT_ROOT}/markVolume2D.m ${PROJECT_ROOT}/saveastiff.m ${PROJECT_ROOT}/skel2mask.m diff --git a/docs/index.html b/docs/index.html index 68c08b4..48d7ea6 100755 --- a/docs/index.html +++ b/docs/index.html @@ -30,7 +30,7 @@

Cut image volumes along arbitrary surfaces

- Download VolumeCut + Download VolumeCut Release notes User manual Report an issue diff --git a/loadImageStack.m b/loadImageStack.m new file mode 100644 index 0000000..5a8dea3 --- /dev/null +++ b/loadImageStack.m @@ -0,0 +1,51 @@ +%% VolumeCut: Cut images along custom surfaces +% Copyright (C) 2017,2018 Luca Della Santina +% +% This file is part of VolumeCut +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . +% This software is released under the terms of the GPL v3 software license +% +function [I, Isize, Ires] = loadImageStack(PathName, FileName) + % Read the image size and resolution from file + tmpImInfo = imfinfo([PathName FileName]); + tmpImSizeZ = numel(tmpImInfo); + tmpImSizeX = tmpImInfo.Width; + tmpImSizeY = tmpImInfo.Height; + Isize = [tmpImSizeX, tmpImSizeY, tmpImSizeZ]; + + % Read image resolution data + try + tmpXYres = 1/tmpImInfo(1).XResolution; + if contains(tmpImInfo(1).ImageDescription, 'spacing=') + tmpPos = strfind(tmpImInfo(1).ImageDescription,'spacing='); + tmpZres = tmpImInfo(1).ImageDescription(tmpPos+8:end); + tmpZres = regexp(tmpZres,'\n','split'); + tmpZres = str2double(tmpZres{1}); + else + tmpZres = 0.3; % otherwise use default value + end + Ires = [tmpXYres, tmpXYres, tmpZres]; + catch + Ires = [1,1,1]; + end + + % Load the image data into matlab + fprintf('Loading image stack... '); + I = uint8(ones(tmpImSizeX, tmpImSizeY, tmpImSizeZ)); + for j = 1:tmpImSizeZ + I(:,:,j)=imread([PathName FileName], j); + end + fprintf('DONE\n'); +end \ No newline at end of file diff --git a/markVolume2D.m b/markVolume2D.m index 181c661..d615876 100644 --- a/markVolume2D.m +++ b/markVolume2D.m @@ -51,16 +51,17 @@ chkShowObjects = uicontrol('Style','checkbox' ,'Units','normalized','position',[.912,.830,.085,.02],'String','Show (spacebar)', 'Value',1,'Callback',@chkShowObjects_changed); chkShowAllZ = uicontrol('Style','checkbox' ,'Units','normalized','position',[.912,.790,.085,.02],'String','Ignore Z (Z)', 'Value',1,'Callback',@chkShowAllZ_changed); lstDots = uicontrol('Style','listbox' ,'Units','normalized','position',[.907,.530,.085,.25],'String',[],'Callback',@lstDots_valueChanged); + btnDelete = uicontrol('Style','Pushbutton','Units','normalized','position',[.907,.480,.088,.04],'String','Delete Item (d)','Callback',@btnDelete_clicked); %#ok, unused variable - txtValidObjs = uicontrol('Style','text' ,'Units','normalized','position',[.907,.490,.085,.02],'String',['Total: ' num2str(size(Dots,3))]); - txtSelObj = uicontrol('Style','text' ,'Units','normalized','position',[.907,.460,.085,.02],'String','Selected Object info'); %#ok, unused variable - txtSelObjID = uicontrol('Style','text' ,'Units','normalized','position',[.907,.430,.085,.02],'String','ID# :'); - txtSelObjPos = uicontrol('Style','text' ,'Units','normalized','position',[.907,.400,.085,.02],'String','Pos : '); - txtSelObjPix = uicontrol('Style','text' ,'Units','normalized','position',[.907,.370,.085,.02],'String','Voxels : '); + txtValidObjs = uicontrol('Style','text' ,'Units','normalized','position',[.907,.440,.085,.02],'String',['Total: ' num2str(size(Dots,3))]); + txtSelObj = uicontrol('Style','text' ,'Units','normalized','position',[.907,.410,.085,.02],'String','Selected Object info'); %#ok, unused variable + txtSelObjID = uicontrol('Style','text' ,'Units','normalized','position',[.907,.380,.085,.02],'String','ID# :'); + txtSelObjPos = uicontrol('Style','text' ,'Units','normalized','position',[.907,.350,.085,.02],'String','Pos : '); + txtSelObjPix = uicontrol('Style','text' ,'Units','normalized','position',[.907,.320,.085,.02],'String','Voxels : '); - txtZoom = uicontrol('Style','text' ,'Units','normalized','position',[.925,.310,.050,.02],'String','Zoom level:'); %#ok, unused variable - btnZoomOut = uicontrol('Style','Pushbutton','Units','normalized','position',[.920,.250,.030,.05],'String','-' ,'Callback',@btnZoomOut_clicked); %#ok, unused variable - btnZoomIn = uicontrol('Style','Pushbutton','Units','normalized','position',[.950,.250,.030,.05],'String','+' ,'Callback',@btnZoomIn_clicked); %#ok, unused variable + txtZoom = uicontrol('Style','text' ,'Units','normalized','position',[.925,.290,.050,.02],'String','Zoom level:'); %#ok, unused variable + btnZoomOut = uicontrol('Style','Pushbutton','Units','normalized','position',[.920,.230,.030,.05],'String','-' ,'Callback',@btnZoomOut_clicked); %#ok, unused variable + btnZoomIn = uicontrol('Style','Pushbutton','Units','normalized','position',[.950,.230,.030,.05],'String','+' ,'Callback',@btnZoomIn_clicked); %#ok, unused variable btnSave = uicontrol('Style','Pushbutton','Units','normalized','position',[.907,.050,.088,.05],'String','Save objects','Callback',@btnSave_clicked); %#ok, unused variable @@ -131,7 +132,24 @@ function lstDots_valueChanged(src,event) %#ok, unused arguments scroll(frame, 'right'); end end - + + function btnDelete_clicked(src,event) %#ok, unused arguments + % Remove selected object from the list + if SelObjID > 0 + Dots.Pos(SelObjID, :) = []; + Dots.Vox(SelObjID) = []; + Dots.Filter(SelObjID) = []; + + if SelObjID > numel(Dots.Filter) + SelObjID = numel(Dots.Filter); + set(lstDots, 'Value', 1); + end + PosZoom = [-1, -1]; + lstDotsRefresh; + scroll(frame, 'right'); + end + end + function ID = addDot(X, Y, D) % Creates a new object #ID from pixels within R radius % X,Y: center coordinates, R: radius in zoomed region pixels