├── file_proc-toolbox
├── README.md
├── get_predirs.m
├── imfiles2giffile.m
└── get_dirs.m
├── demo
├── count_openset_num.m
├── calculate_area_2022_0725.m
├── calculate_area_2023_2002.m
├── count_cell_num.m
└── bone_shape_reconstruct_from_dcm_220831.m
├── img_proc-toolbox
├── lab2ind.m
├── keep_remove_ranked_vol.m
├── serial_dilate_erode_vol.m
├── vol_rot_gif.m
├── sub2ind_nd.m
├── ind2lab.m
└── sub2lab.m
├── evaluate_metrics-toolbox
├── lap_conv3d.m
├── hausforff_dist.m
├── centroid_dist.m
├── avg_surf_dist.m
├── det_jacob.m
└── get_thickness_map.m
├── README.md
└── LICENSE
/file_proc-toolbox/README.md:
--------------------------------------------------------------------------------
1 | # file_processing
--------------------------------------------------------------------------------
/demo/count_openset_num.m:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jianqingzheng/image_processing/HEAD/demo/count_openset_num.m
--------------------------------------------------------------------------------
/demo/calculate_area_2022_0725.m:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jianqingzheng/image_processing/HEAD/demo/calculate_area_2022_0725.m
--------------------------------------------------------------------------------
/demo/calculate_area_2023_2002.m:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jianqingzheng/image_processing/HEAD/demo/calculate_area_2023_2002.m
--------------------------------------------------------------------------------
/img_proc-toolbox/lab2ind.m:
--------------------------------------------------------------------------------
1 | function [ind,pnd]=lab2ind(lab,thresh)
2 | if nargin<2
3 | thresh=0.1;
4 | end
5 | img_sz=size(lab);
6 | ind=find(lab>thresh);
7 | pnd=[];
8 | id=ind;
9 | for s=img_sz
10 | coord=mod(id,s);
11 | pnd=[pnd,coord];
12 | id=floor(id/s);
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/evaluate_metrics-toolbox/lap_conv3d.m:
--------------------------------------------------------------------------------
1 | function out_vol=lap_conv3d(vol)
2 | % lap_k1=[];
3 | lap_k0=[0,0,0;
4 | 0,-1,0;
5 | 0,0,0];
6 | lap_k2=[0,-1,0;
7 | -1,6,-1;
8 | 0,-1,0];
9 | lap_kernel=cat(3,lap_k0,lap_k2,lap_k0);
10 | out_vol=convn(double(vol),lap_kernel,'same');
11 | end
12 |
--------------------------------------------------------------------------------
/img_proc-toolbox/keep_remove_ranked_vol.m:
--------------------------------------------------------------------------------
1 | function out_vol=keep_remove_ranked_vol(vol,rank_nums)
2 | out_vol=vol>0.5;
3 | if ndims(vol)>2
4 | L = bwconncomp(vol,26);%
5 | else
6 | L = bwconncomp(vol,8);%
7 | end
8 | stats = regionprops(L,'Area');
9 | Ar = cat(1, stats.Area);
10 | [~,ind]=sort(Ar,'descend');
11 | LM = labelmatrix(L);
12 | % out_vol(find(LM==ind(remove_vol_rank)))=0;%
13 | if rank_nums(1)>0
14 | out_vol(~ismember(LM,ind(rank_nums)))=0;%
15 | else
16 | rank_nums=-1.*rank_nums;
17 | out_vol(ismember(LM,ind(rank_nums)))=0;%
18 | end
19 | end
20 |
21 |
--------------------------------------------------------------------------------
/file_proc-toolbox/get_predirs.m:
--------------------------------------------------------------------------------
1 | function [predirs,foldernames]=get_predirs(dirs_in,layernumber)
2 | predirs=dirs_in;
3 | predirs_temp=predirs;
4 | for i=0:layernumber
5 | if i==layernumber
6 | foldernames_temp=cell(size(dirs_in));
7 | end
8 | for j=1:numel(predirs)
9 | [predir,foldername,~]=fileparts(predirs_temp{j});
10 | if i==layernumber
11 | foldernames_temp{j}=foldername;
12 | else
13 | predirs_temp{j}=predir;
14 | end
15 | end
16 | end
17 | if layernumber>0
18 | predirs=predirs_temp;
19 |
20 | end
21 | foldernames=foldernames_temp;
22 | end
--------------------------------------------------------------------------------
/file_proc-toolbox/imfiles2giffile.m:
--------------------------------------------------------------------------------
1 | function []=imfiles2giffile(imdirs,giffile,delay,loopnumb)
2 | if nargin<4
3 | loopnumb=inf;
4 | if nargin<3
5 | delay=0.001;
6 | end
7 | end
8 | % im_dirs_temp=get_dirs(Label_path,'.obj',[Label_path,'/',sprintf('P%02d',p)]);
9 | for i=1:numel(imdirs)
10 | img=imread(imdirs{i});
11 | drawnow
12 | f=getframe;
13 | f=frame2im(f);
14 | [X,map]=rgb2ind(img,256);
15 | if i==1
16 | imwrite(X,map,giffile,'gif','LoopCount',loopnumb,'DelayTime',delay);
17 | else
18 | imwrite(X,map,giffile,'WriteMode','Append','DelayTime',delay);
19 | end
20 | end
21 | end
--------------------------------------------------------------------------------
/img_proc-toolbox/serial_dilate_erode_vol.m:
--------------------------------------------------------------------------------
1 | function out_vol=serial_dilate_erode_vol(vol,dilate_erode_rates,growing_msk,min_area,se_type)
2 | if nargin<5
3 | se_type='sphere';
4 | if nargin<4
5 | min_area=0;
6 | if nargin<3
7 | growing_msk=1;
8 | end
9 | end
10 | end
11 | for r= dilate_erode_rates
12 | se=strel(se_type,abs(r));
13 | % se=strel('cube',abs(r));
14 | if r>0
15 | vol=imdilate(vol,se);
16 | else
17 | vol=imerode(vol,se);
18 | end
19 | vol=vol.*growing_msk;
20 | if min_area>0
21 | vol=bwareaopen(vol,min_area);
22 | end
23 | end
24 | out_vol=vol;
25 | end
--------------------------------------------------------------------------------
/evaluate_metrics-toolbox/hausforff_dist.m:
--------------------------------------------------------------------------------
1 | function hd=hausforff_dist(vol1,vol2,side_idx)
2 | if nargin<3
3 | side_idx=0;
4 | end
5 | v1=lap_conv3d(vol1)>0.5;
6 | v2=lap_conv3d(vol2)>0.5;
7 | [~,coord1]=img2ind(v1);
8 | [~,coord2]=img2ind(v2);
9 | if side_idx==1 || side_idx==2
10 | dist_mat=pdist2(coord1,coord2,"euclidean");
11 | hd=max(min(dist_mat,[],side_idx));
12 | else
13 | [hd]=HausdorffDist(coord1,coord2);
14 | end
15 | end
16 |
17 | function [ind,pnd]=img2ind(img,thresh)
18 | if nargin<2
19 | thresh=0.000000001;
20 | end
21 | img_sz=size(img);
22 | ind=find(img>thresh);
23 | pnd=[];
24 | id=ind;
25 | for s=img_sz
26 | coord=mod(id,s);
27 | pnd=[pnd,coord];
28 | id=floor(id/s);
29 | end
30 | end
--------------------------------------------------------------------------------
/evaluate_metrics-toolbox/centroid_dist.m:
--------------------------------------------------------------------------------
1 | function cd=centroid_dist(vol1,vol2)
2 | s = regionprops3(vol1,"Centroid","PrincipalAxisLength");
3 | coord1 = s.Centroid;
4 | s = regionprops3(vol2,"Centroid","PrincipalAxisLength");
5 | coord2 = s.Centroid;
6 | % v1=lap_conv3d(vol1)>0.5;
7 | % v2=lap_conv3d(vol2)>0.5;
8 | % volshow(v2);
9 | % [~,coord1]=img2ind(v1);
10 | % [~,coord2]=img2ind(v2);
11 | dist_mat=pdist2(coord1,coord2,"euclidean");
12 | cd=mean(min(dist_mat,[],1));
13 |
14 | end
15 |
16 | function [ind,pnd]=img2ind(img,thresh)
17 | if nargin<2
18 | thresh=0.000000001;
19 | end
20 | img_sz=size(img);
21 | ind=find(img>thresh);
22 | pnd=[];
23 | id=ind;
24 | for s=img_sz
25 | coord=mod(id,s);
26 | pnd=[pnd,coord];
27 | id=floor(id/s);
28 | end
29 | end
--------------------------------------------------------------------------------
/evaluate_metrics-toolbox/avg_surf_dist.m:
--------------------------------------------------------------------------------
1 | function asd=avg_surf_dist(vol1,vol2,side_idx,sample_rate)
2 | if nargin<4
3 | sample_rate=1;
4 | if nargin<3
5 | side_idx=1;
6 | end
7 | end
8 | % % lap_k1=[];
9 | % lap_k0=[0,0,0;
10 | % 0,-1,0;
11 | % 0,0,0];
12 | % lap_k2=[0,-1,0;
13 | % -1,6,-1;
14 | % 0,-1,0];
15 | % lap_kernel=cat(3,lap_k0,lap_k2,lap_k0);
16 | % v1=convn(double(vol1),lap_kernel,'same')>0.5;
17 | % v2=convn(double(vol2),lap_kernel,'same')>0.5;
18 | v1=lap_conv3d(vol1)>0.5;
19 | v2=lap_conv3d(vol2)>0.5;
20 | % volshow(v2);
21 | [~,coord1]=img2ind(v1);
22 | [~,coord2]=img2ind(v2);
23 | dist_mat=pdist2(coord1(1:sample_rate:end,:),coord2(1:sample_rate:end,:),"euclidean");
24 | asd=mean(min(dist_mat,[],side_idx));
25 |
26 | end
27 |
28 | function [ind,pnd]=img2ind(img,thresh)
29 | if nargin<2
30 | thresh=0.000000001;
31 | end
32 | img_sz=size(img);
33 | ind=find(img>thresh);
34 | pnd=[];
35 | id=ind;
36 | for s=img_sz
37 | coord=mod(id,s);
38 | pnd=[pnd,coord];
39 | id=floor(id/s);
40 | end
41 | end
--------------------------------------------------------------------------------
/img_proc-toolbox/vol_rot_gif.m:
--------------------------------------------------------------------------------
1 | function []=vol_rot_gif(fig_id,gif_file,cam_angles)
2 | if nargin<3
3 | rot_num=5;
4 | % cam_angles=[[0:rot_num:360]+90;zeros(1,360/rot_num+1)+5];
5 | cam_angles=[zeros(1,360/rot_num+1)+90;[0:rot_num:360]+90];
6 | if nargin<2
7 | gif_file=['vol_rot_gif','.gif'];
8 | end
9 | end
10 | if nargin>=1
11 | fig=figure(fig_id);
12 | end
13 | loopnumb=Inf;
14 | delay=0.1;
15 |
16 | for ang_id=1:size(cam_angles,2)
17 | view(double(cam_angles(:,ang_id))');
18 | camlight;%
19 | ax = gca;
20 | % ax.Units = 'pixels';
21 | % ti = ax.TightInset;
22 | % pos=ax.Position;
23 | % rect = [0, 0, floor(pos(3)), floor(pos(4))];
24 | axis vis3d
25 | drawnow
26 | f=getframe(ax.Parent);
27 | img=frame2im(f);
28 | delete(findall(gcf,'Type','light'));%
29 | [X,map]=rgb2ind(img,256);
30 | if ang_id==1
31 | imwrite(X,map,gif_file,'gif','LoopCount',loopnumb,'DelayTime',delay);
32 | else
33 | imwrite(X,map,gif_file,'WriteMode','Append','DelayTime',delay);
34 | end
35 | end
36 | end
37 |
38 |
--------------------------------------------------------------------------------
/img_proc-toolbox/sub2ind_nd.m:
--------------------------------------------------------------------------------
1 | function ind = sub2ind_nd( tensor_sz, subs )
2 | % sub2ind_nd - Get the index number using the given subscript coordinates
3 | % and the tensor size
4 | %--------------------------------------------------------------------------
5 | % [ind] = sub2ind_nd( tensor_sz, subs )
6 | % 'ind' - the output index numbers
7 | % 'tensor_sz' - the size of the required tensor
8 | % 'sub' - the given subscript corrdinates
9 | %--------------------------------------------------------------------------
10 | % Examples:
11 | % >> ind = sub2ind_nd([5,5],[3,5;2,3])
12 | %
13 | % ind =
14 | % 23
15 | % 12
16 | %
17 | % >> ind = sub2ind_nd([3,3,3],[1,3,1;1,2,2])
18 | %
19 | % ind =
20 | % 7
21 | % 13
22 | %--------------------------------------------------------------------------
23 | % MATLAB Ver R2019a
24 | %--------------------------------------------------------------------------
25 | % $ Author: Jachin (Jianqing Zheng) $
26 | % $ Revision: 1.0 $ $ Date: 2023/04/05$
27 | %--------------------------------------------------------------------------
28 | % See also: 'sub2lab', 'ind2sub'
29 |
30 | %--------------------------------------------------------------------------
31 | subs=round(subs);
32 | ndims=size(subs,2);
33 | ind=1;
34 | tensor_sz=[1,tensor_sz];
35 | for i=1:ndims
36 | ind=ind+(subs(:,i)-1).*prod(tensor_sz(1:i));
37 | end
38 | end
--------------------------------------------------------------------------------
/img_proc-toolbox/ind2lab.m:
--------------------------------------------------------------------------------
1 | function lab=ind2lab(ind,lab_sz)
2 | % ind2lab - Get a binary volume (label) with one values at the indexed
3 | % position and zero at the others
4 | %--------------------------------------------------------------------------
5 | % [lab] = ind2lab(ind,lab_sz)
6 | % 'lab' - output binary volume with one values at the required locations
7 | % 'ind' - the given indexed location
8 | % 'lab_sz'- the size of the required volume
9 | %--------------------------------------------------------------------------
10 | % Examples:
11 | % >> lab = ind2lab([2,6],[3,3])
12 | %
13 | % lab =
14 | % 0 0 0
15 | % 1 0 0
16 | % 0 1 0
17 | %--------------------------------------------------------------------------
18 | % MATLAB Ver R2019a
19 | %--------------------------------------------------------------------------
20 | % $ Author: Jachin (Jianqing Zheng) $
21 | % $ Revision: 1.0 $ $ Date: 2023/04/05$
22 | %--------------------------------------------------------------------------
23 | % See also: 'sub2lab', 'lab2ind', 'sub2ind_nd'
24 |
25 | %--------------------------------------------------------------------------
26 | ind_tmp=round(ind);
27 | ind_tmp(any(ind_tmp<1,2),:)=[];
28 | ind_tmp(ind_tmp>prod(lab_sz))=[];
29 | lab=zeros(lab_sz);%
30 | if isempty(ind_tmp)
31 | disp('is empty');
32 | else
33 | lab(ind_tmp)=1;
34 | end
35 | end
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/demo/count_cell_num.m:
--------------------------------------------------------------------------------
1 | close all
2 | clear
3 | %% Directory
4 |
5 | subfolder_names=["20220831 irradiation BM chimera C57 HTP"];
6 |
7 | folder_path=fullfile('data');
8 | paths={'D:\Users\JachinZ\Documents\MATLAB\bio_image_process\data\cells\123.jpg'};
9 | % path={'/Users/LengHoufu/Desktop/baf 1_T001 copy.tif'};
10 | % '/Users/LengHoufu/Desktop/baf 1_T001 copy.tif',
11 | % '/Users/LengHoufu/Desktop/baf 1_T001 copy.tif'
12 | % };
13 |
14 | % paths=get_dirs(folder_path,'.jpg');
15 |
16 | %% Parameter setting
17 | thresh0=0.08; %
18 | thresh1=0.4; %
19 | erode_rate=6; %
20 | sigma0=0.4; %
21 | sigma1=1.2; %
22 | min_area0=50; %
23 | min_area1=400; %
24 |
25 | k_size=701;
26 |
27 |
28 | %% For loop calculation
29 | k=-ones(k_size,k_size);
30 | m=-sum(sum(k))-1;
31 | k((k_size-1)/2,(k_size-1)/2)=m;
32 | kernel=k./m;
33 | areas=cell(numel(paths),3);
34 | for i=1:numel(paths)
35 | img=imread(paths{i});
36 | % figure(1);
37 | % imshow(img,[]);
38 | R=img(:,:,1);
39 | B=img(:,:,3);
40 | Z=zeros(size(R));
41 | % imshow(cat(3,Z,Z,B),[]);
42 | B=double(B)./256;
43 |
44 | figure(i)
45 | BM=imgaussfilt(B,sigma0);
46 | BM=conv2(BM,kernel,'same');
47 | % B=reshape(normalize(reshape(B,[1024*1024,1]),'scale','std'),[1024,1024]);
48 | BM=double(BM>thresh0);
49 | % se = strel('ball',dilation_rate,dilation_rate);
50 | % B=imdilate(double(B>thresh),se);
51 | BM=imgaussfilt(BM,sigma1)>thresh1;
52 | BM=double(BM);
53 | % BM=conv2(BM,kernel,'same');
54 | BM=bwareaopen(BM,min_area0);
55 | se = strel('cube',erode_rate);
56 | BM=imerode(BM,se);
57 |
58 | BM=bwareaopen(BM,min_area1);
59 | imshow(cat(3,BM./4,Z,B),[]);
60 |
61 | lb_bw=bwlabel(BM,8);
62 | num=max(max(max(lb_bw)))
63 |
64 | end
65 |
--------------------------------------------------------------------------------
/img_proc-toolbox/sub2lab.m:
--------------------------------------------------------------------------------
1 | function lab=sub2lab(sub,lab_sz)
2 | % sub2lab - Get a binary volume (label) with one values at the subcript
3 | % position and zero at the others
4 | %--------------------------------------------------------------------------
5 | % [lab] = sub2lab(sub,lab_sz)
6 | % 'lab' - output binary volume with one values at the required locations
7 | % 'sub' - the given subscript corrdinates
8 | % 'lab_sz'- the size of the required volume
9 | %--------------------------------------------------------------------------
10 | % Examples:
11 | % >> lab = sub2lab([1,1;2,2],[3,3])
12 | %
13 | % lab =
14 | % 1 0 0
15 | % 0 1 0
16 | % 0 0 0
17 | %
18 | % >> lab = sub2lab([1,1,1;2,2,2],[3,3,3])
19 | %
20 | % lab(:,:,1) =
21 | % 1 0 0
22 | % 0 0 0
23 | % 0 0 0
24 | %
25 | % lab(:,:,2) =
26 | % 0 0 0
27 | % 0 1 0
28 | % 0 0 0
29 | %
30 | % lab(:,:,3) =
31 | % 0 0 0
32 | % 0 0 0
33 | % 0 0 0
34 | %--------------------------------------------------------------------------
35 | % MATLAB Ver R2019a
36 | %--------------------------------------------------------------------------
37 | % $ Author: Jachin (Jianqing Zheng) $
38 | % $ Revision: 1.0 $ $ Date: 2023/04/05$
39 | %--------------------------------------------------------------------------
40 | % See also: 'ind2lab', 'lab2ind', 'sub2ind_nd', 'ind2sub'
41 |
42 | %--------------------------------------------------------------------------
43 | sub_tmp=round(sub);
44 | for d=1:numel(lab_sz)
45 | sub_tmp(any(sub_tmp(d)<1,2),:)=[];
46 | sub_tmp(any(sub_tmp>lab_sz(d),2),:)=[];
47 | end
48 | lab=zeros(lab_sz);%
49 | if isempty(sub_tmp)
50 | disp('is empty');
51 | else
52 | lab(sub2ind_nd(lab_sz,sub_tmp))=1;
53 | end
54 | end
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Image_processing toolbox
2 | This repo provides the implementation of several image processing techniques implemented via matlab.
3 |
4 | Relative Paper list:
5 |
6 |
7 | | Technique name |
8 | Script(s) |
9 | Paper id |
10 |
11 |
12 | | Bone shape reconstruction |
13 | image_processing/demo/bone_shape_reconstruct_from_dcm.m |
14 | Leng2025.05.02.651799 |
15 |
16 |
17 |
18 | # Demos
19 |
20 | # Usage
21 | ## Setup
22 | ```
23 | [$DOWNLOAD_DIR]/image_processing/
24 | ├── data/[$task_name]/
25 |
26 | ├── image_proc-toolbox/
27 | ├── ind2lab.m
28 | ├── keep_remove_ranked_vol.m
29 | ├── lab2ind.m
30 | ├── serial_dilate_erode_vol.m
31 | ├── sub2ind_nd.m
32 | ├── vol_rot_gif.m
33 |
34 | ├── file_proc-toolbox/
35 | ├── get_dirs.m
36 | ├── get_predirs.m
37 | ├── imfiles2giffiles.m
38 |
39 | ```
40 |
41 | # For the citation
42 | The usage of the bone reconstruction script should cite:
43 | ```bibtex
44 | @article {Leng2025.05.02.651799,
45 | author = {Leng, Houfu and jiang, jiahao and Gassner, Katja and Midha, Swati and Justo-Mendez, Raquel and Zheng, Jianqing and Hall, Timothy and Luo, Lin and West, Suzanne D and Vincent, Tonia L. and Wann, Angus and Patel, Kashyap A and Poulton, Joanna and O{\textquoteright}Callaghan, Chris A. and Lechuga-Vieco, Ana Victoria and Simon, Anna Katharina},
46 | title = {Mitochondrial heterogeneity disrupts osteoclast differentiation and bone resorption by impairing respiratory complex I},
47 | elocation-id = {2025.05.02.651799},
48 | year = {2025},
49 | doi = {10.1101/2025.05.02.651799},
50 | publisher = {Cold Spring Harbor Laboratory},
51 | URL = {https://www.biorxiv.org/content/early/2025/05/02/2025.05.02.651799},
52 | eprint = {https://www.biorxiv.org/content/early/2025/05/02/2025.05.02.651799.full.pdf},
53 | journal = {bioRxiv}
54 | }
55 | ```
56 |
--------------------------------------------------------------------------------
/evaluate_metrics-toolbox/det_jacob.m:
--------------------------------------------------------------------------------
1 | function D=det_jacob(ddf,lab)
2 | % DETJAC Calculates the determinants of the Jacobian matrices of a
3 | % deformation field.
4 | % D = DETJAC(J) calculates the determinants of the Jacobian matrices of
5 | % the deformation field J, where J is a matrix with size M-by-N-by-2-by-2.
6 | % The output D is a matrix with size M-by-N.
7 | % lab_sz=size(lab,4);
8 | D=zeros(size(lab));
9 | for lab_id=1:size(lab,4)
10 | J=cal_jac_vol(ddf.*lab(:,:,:,lab_id));
11 | % Calculate the determinants of the Jacobian matrices
12 | a = J(:,:,:,1,1);
13 | b = J(:,:,:,1,2);
14 | c = J(:,:,:,1,3);
15 | d = J(:,:,:,2,1);
16 | e = J(:,:,:,2,2);
17 | f = J(:,:,:,2,3);
18 | g = J(:,:,:,3,1);
19 | h = J(:,:,:,3,2);
20 | i = J(:,:,:,3,3);
21 | D(:,:,:,lab_id) = (a.*e.*i)+(b.*f.*g)+(c.*d.*h)-(g.*e.*c)-(h.*f.*a)-(i.*d.*b);
22 | end
23 |
24 | end
25 |
26 |
27 |
28 | function [ind,pnd]=img2ind(img,thresh)
29 | if nargin<2
30 | thresh=0.000000001;
31 | end
32 | img_sz=size(img);
33 | ind=find(img>thresh);
34 | pnd=[];
35 | id=ind;
36 | for s=img_sz
37 | coord=mod(id,s);
38 | pnd=[pnd,coord];
39 | id=floor(id/s);
40 | end
41 | end
42 |
43 |
44 | function jacob=cal_jac_vol(vol)
45 | vol_sz=size(vol);
46 | % jacob=zeros([vol_sz,vol_sz(end)])
47 | jacob=[];
48 | for v=1:vol_sz(end)
49 | [Gx, Gy, Gz] = imgradientxyz(vol(:,:,:,v));
50 | G=cat(4,Gx,Gy,Gz);
51 | jacob=cat(5,jacob,G);
52 | end
53 | % jacob=cat(5,Gx,Gy,Gz);
54 | for i = 1:vol_sz(end)
55 | jacob(:,:,:,i,i)=jacob(:,:,:,i,i)+1;
56 | end
57 | end
58 |
59 | %
60 | % def eval_detJ_lab(vol1=None,vol2=None,disp=None,thresh=0.5):
61 | % ndims=3
62 | % label=vol1>thresh
63 | % label=label*(ndimage.laplace(label) < 0.1)
64 | % # label=vol2[...,0]>thresh
65 | % # label=np.ones_like(vol2[...,0])
66 | % # a=np.stack(np.gradient(disp,axis=[-2,-3,-4]),-1)
67 | % # b=np.sum(label)
68 | % # rescale_factor=2
69 | % rescale_factor=1
70 | % # label=zoom(label, [1./rescale_factor]*ndims+[1], mode='nearest')
71 | % label=label[...,::rescale_factor,::rescale_factor,::rescale_factor]
72 | % # disp=zoom(disp, [rescale_factor]*ndims+[1], mode='nearest')
73 | % # label=zoom(label, rescale_factor, mode='nearest')
74 | % # a=np.stack(np.gradient(disp,axis=[-2,-3,-4]),-1)
75 | % # b = np.linalg.det(a)
76 | % Jacob=np.stack(np.gradient(disp,axis=[-4,-3,-2]),-1)
77 | % Jacob[..., 0, 0] = Jacob[..., 0, 0] + 1
78 | % Jacob[..., 1, 1] = Jacob[..., 1, 1] + 1
79 | % Jacob[..., 2, 2] = Jacob[..., 2, 2] + 1
80 | % return np.sum((np.linalg.det(Jacob)<0)*label)
--------------------------------------------------------------------------------
/file_proc-toolbox/get_dirs.m:
--------------------------------------------------------------------------------
1 | function [dirs_out]=get_dirs(folder,dirPattern,commonstr,dirs_in)
2 | % get_dirs - Get the directories for required files in one folder and its subfolders
3 | %--------------------------------------------------------------------------
4 | % get_dirs(folder,dirPattern,commonstr,dirs_in) is a recursive function,
5 | % which returns a cell including the directories of all the required
6 | % files.
7 | %--------------------------------------------------------------------------
8 | % [dirs_out] = get_dirs(folder,dirPattern,commonstr,dirs_in)
9 | % 'dirs_out' - output cell of the directories of all the required files.
10 | % 'folder' - a dir string of the folder to search.
11 | % 'dirPattern'- a string of required files' pattern.
12 | % 'commonstr' - a string required in the dirs of those selected files.
13 | % 'dirs_in' - a cell of dirs for recursion
14 | %--------------------------------------------------------------------------
15 | % Examples:
16 | % % Before starting recursion:
17 | % >> folder='/data/someone/Aneurysm_Seg'
18 | % >> dirPat='.jpg'
19 | % >> commonstr={'epoch_1','_2'}
20 | % >> dirs_out=get_dirs(folder,dirPat,commonstr)
21 | %
22 | % % after completing recursion
23 | % dirs_out =
24 | %
25 | % 12×1 cell array
26 | %
27 | % '/data/someone/Aneurysm_Seg//Trained_1/prediction/epoch_10_2.jpg'
28 | % '/data/someone/Aneurysm_Seg//Trained_1/prediction/epoch_11_2.jpg'
29 | % '/data/someone/Aneurysm_Seg//Trained_1/prediction/epoch_12_1.jpg'
30 | % '/data/someone/Aneurysm_Seg//Trained_1/prediction/epoch_12_2.jpg'
31 | % '/data/someone/Aneurysm_Seg//Trained_1/prediction/epoch_13_2.jpg'
32 | % '/data/someone/Aneurysm_Seg//Trained_1/prediction/epoch_14_2.jpg'
33 | % '/data/someone/Aneurysm_Seg//Trained_1/prediction/epoch_15_2.jpg'
34 | % '/data/someone/Aneurysm_Seg//Trained_1/prediction/epoch_16_2.jpg'
35 | % '/data/someone/Aneurysm_Seg//Trained_1/prediction/epoch_17_2.jpg'
36 | % '/data/someone/Aneurysm_Seg//Trained_1/prediction/epoch_18_2.jpg'
37 | % '/data/someone/Aneurysm_Seg//Trained_1/prediction/epoch_19_2.jpg'
38 | % '/data/someone/Aneurysm_Seg//Trained_1/prediction/epoch_1_2.jpg'
39 | %--------------------------------------------------------------------------
40 | % MATLAB Ver >= R2016b
41 | %--------------------------------------------------------------------------
42 | % $ Author: Jachin $
43 | % $ Revision: 2.1 $ $ Date: 2018/03/13 22:24 $
44 | %--------------------------------------------------------------------------
45 | % See also: 'fileparts', 'contains'
46 |
47 | %--------------------------------------------------------------------------
48 |
49 | %% parameter transfer
50 | if nargin<4
51 | dirs_in={};
52 | if nargin<3
53 | commonstr='';
54 | if nargin<2
55 | dirPattern='';
56 | end
57 | end
58 | end
59 | %% verify and append
60 | [~,~,pattern]=fileparts(folder);
61 | if (strcmp(pattern,dirPattern)||isempty(dirPattern))
62 | if ~isempty(commonstr)
63 | if iscell(commonstr)
64 | result=0;
65 | for i=1:size(commonstr,1)
66 | temp=1;
67 | for j=1:size(commonstr,2)
68 | temp=temp&contains(folder,commonstr{i,j});
69 | end
70 | result=result|temp;
71 | end
72 | else
73 | result=contains(folder,commonstr);
74 | end
75 | else
76 | result=1;
77 | end
78 | if result
79 | dirs_out=[dirs_in;folder];
80 | else
81 | dirs_out=dirs_in;
82 | end
83 | else
84 | dirs_out=dirs_in;
85 | end
86 | %% recursion
87 | dirs_recur=dirs_out;
88 | files=dir(folder);
89 | % if contains(folder,'/')
90 | % slash='/';
91 | % else
92 | slash='\';
93 | % end
94 | for i=3:size(files,1)
95 | fn=files(i).name;
96 | folder_recur=sprintf('%s%s%s', folder,slash, fn);
97 | dirs_out=get_dirs(folder_recur,dirPattern,commonstr,dirs_recur);
98 | dirs_recur=dirs_out;
99 | end
100 |
101 | end
102 |
--------------------------------------------------------------------------------
/demo/bone_shape_reconstruct_from_dcm_220831.m:
--------------------------------------------------------------------------------
1 | close all
2 | clear
3 | % set directory
4 | vox_folder=fullfile('data');
5 | subfolder_names=["20220831 irradiation BM chimera C57 HTP"];
6 |
7 | %% set parameters
8 | % rot_axis = [1,0,0; ];
9 | rotx_axis = [1,0,0 ];
10 | roty_axis = [0,1,0 ];
11 |
12 | angs= [0,0;
13 | 0,0;
14 | ];
15 | sec_locs= [0,350;];
16 |
17 | vol_id=1;
18 | subfolder_id=1;
19 | filter_flag=1;
20 | intensity_bias=[0,0,-100,0,400,100,0,0];
21 | thresh_bone0=800+4000+intensity_bias(subfolder_id);
22 | thresh_bone1=1900+4000+intensity_bias(subfolder_id);
23 | thresh_bone2=800+4000+intensity_bias(subfolder_id);
24 | sec_bias=180;
25 | min_area1=100;
26 | remove_small_vol=1;
27 | remove_vol_rank=2;
28 |
29 | sigma=4;
30 | sigma_vol=6;
31 | erode_iter=2;
32 | erode_sz=1;
33 | dilate_iter=12;
34 | % dilate_iter=20;
35 | dilate_sz=4;
36 | % dilate_sz=3;
37 | ang=[0,0];
38 |
39 | %% for loop
40 | dirinfo = dir(fullfile(vox_folder,subfolder_names(subfolder_id)));
41 | dirinfo= dirinfo(3:end);
42 | % dcmfiles = cell(length(dirinfo),1);
43 | dcmfiles = cell(0);
44 | for K = 1 : length(dirinfo)
45 | thisdir = dirinfo(K).name;
46 | if ~all(ismember('.png',char(thisdir)))
47 | dcmfiles =[dcmfiles;fullfile(vox_folder,subfolder_names(subfolder_id),thisdir)];
48 | end
49 | end
50 |
51 | for pth_id =1:1:numel(dcmfiles)
52 | pth_id
53 | close all;
54 | [img,spatial,dim] = dicomreadVolume(dcmfiles{pth_id});
55 | img=img(:,:,:);
56 | % if pth_id>size(sec_locs,1)
57 | % ang=angs(end,:);
58 | % sec_loc=sec_locs(end,:);
59 | % else
60 | % sec_loc=sec_locs(pth_id,:);
61 | % ang=angs(pth_id,:);
62 | % end
63 |
64 | img=imrotate3(img,ang(1),rotx_axis);
65 | img=imrotate3(img,ang(2),roty_axis);
66 | %% section
67 | [~,~,z_coord]=ind2sub(size(img),find(img>thresh_bone1));
68 | sec_loc(2)=max(z_coord)-sec_bias;
69 | sec_loc(1)=sec_loc(2)-100;
70 | % sec_loc(1)=0;
71 |
72 | img(:,:,sec_loc(2):size(img,1))=[];
73 | img(:,:,1:sec_loc(1))=[];
74 |
75 | %% thresholding
76 | vol_shape0=(img>thresh_bone0);
77 | vol_shape0=bwareaopen(vol_shape0,min_area1./10);
78 | if filter_flag
79 | vol_shape1=(imgaussfilt3(img,sigma)>thresh_bone1);
80 | vol_shape1=bwareaopen(vol_shape1,min_area1);
81 | vol_shape2=(img>thresh_bone2);
82 | vol_shape2=bwareaopen(vol_shape2,min_area1./5);
83 | end
84 |
85 | %% filter0
86 | if remove_small_vol
87 | vol_shape0=keep_remove_ranked_vol(vol_shape0,[-remove_vol_rank]);
88 | end
89 |
90 | if filter_flag %%%%%%
91 | if remove_small_vol
92 | vol_shape2=keep_remove_ranked_vol(vol_shape2,[-remove_vol_rank]);
93 | end
94 |
95 | %% filter1
96 | vol_shape1 = serial_dilate_erode_vol(vol_shape1,kron([-erode_sz,erode_sz],ones(1,erode_iter)),vol_shape0,min_area1);
97 | vol_shape1=imgaussfilt3(double(vol_shape1),sigma_vol)>0.3;
98 | vol_shape1 = serial_dilate_erode_vol(vol_shape1,kron([erode_sz],ones(1,7)),vol_shape0,min_area1);
99 | vol_shape2=fill_slide_centroid(vol_shape2);
100 | vol_shape2 = serial_dilate_erode_vol(vol_shape2,kron([dilate_sz],ones(1,dilate_iter)),1,0,'cube');
101 | vol_shape2=imgaussfilt3(double(vol_shape2),sigma_vol)>0.1;
102 | vol_shape2 = serial_dilate_erode_vol(vol_shape2,kron([-dilate_sz],ones(1,dilate_iter)),1,min_area1*200,'cube');
103 | end
104 |
105 | %% select volume
106 | % calculate the ratio of cancellous bone divided by the volume inside the
107 | % cortical bone.
108 | vol_shape=vol_shape0;
109 | if filter_flag
110 | vol_shape=vol_shape.*(vol_shape2);
111 | vol_low_density=sum(sum(sum(vol_shape0.*vol_shape2)));
112 | vol_total=sum(sum(sum(vol_shape2)));
113 | ratio=vol_low_density./vol_total
114 | end
115 |
116 | %% plot
117 | figure(pth_id);
118 | vol_shape(:,:,1)=0;
119 | % vol_shape(:,:,end)=0;
120 | vs=volshow(double(vol_shape));
121 | set(vs,'Renderer', 'Isosurface');
122 | vs.BackgroundColor='w';
123 | vs.IsosurfaceColor=[1.,1.,1.];
124 | vs.Isovalue=.5;
125 | vs.CameraTarget=[-0.1,-0.1,0];
126 | vs.CameraViewAngle=10;
127 | vs.CameraPosition = [-1.5098 0.4677 3.5471];
128 | vs.CameraUpVector= [-0.1328 -0.0914 0.9869];
129 |
130 | print(dcmfiles(pth_id)+'_view0'+'.png', '-dpng', '-r900');
131 | end
132 |
133 | %% function
134 | function [out_vol]=fill_slide_centroid(in_vol)
135 | vol_sum3=sum(sum(in_vol,2),1);
136 | [Y,X,Z]=meshgrid(1:size(in_vol,2),1:size(in_vol,1),1:size(in_vol,3));
137 | cX=sum(sum(X.*in_vol,1),2)./vol_sum3;
138 | cY=sum(sum(Y.*in_vol,1),2)./vol_sum3;
139 | cZ=sum(sum(Z.*in_vol,1),2)./vol_sum3;
140 | out_vol=in_vol;
141 | idx=round(permute(sub2ind(size(out_vol),cX,cY,cZ),[3,1,2]));
142 | out_vol(idx)=1;
143 | end
144 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/evaluate_metrics-toolbox/get_thickness_map.m:
--------------------------------------------------------------------------------
1 | function D = get_thickness_map(matrix)
2 | % matrix is a 3D matrix representing the volume
3 | % with the thin plate defined by a boundary value of 1
4 |
5 | % Calculate the distance transform of the boundary points
6 | bvol=matrix>0.5;
7 | bvol_lap=lap_conv3d(bvol)>0.5;
8 |
9 | D = (2 *bwdist(bvol_lap)).*bvol;
10 | map_msk=lap_conv3d(D)>2.0;
11 | D = D.*map_msk.*(D>1.0) ;
12 | % D = bwdist(bvol).*bvol;
13 | % Find the maximum distance along each axis
14 | % p1=find_max_coordinate(D);
15 | % p2=find_closest_point_to_volume(p1, bvol_lap);
16 | %
17 | % % D=find_max_projection_and_set_to_zero(D,p1-p2);
18 | % d=max_intensity_projection(D, p1-p2);
19 |
20 | max_dist = max(max(max(D)));
21 |
22 | % Calculate the thickness of the plate
23 | thickness = max_dist;
24 | end
25 |
26 | %%
27 |
28 | function [proj, proj_coords] = max_intensity_projection(volume, normal)
29 | % Find the two axes that lie in the plane
30 | [~, axis1] = max(abs(normal));
31 | axis2 = mod(axis1, 3) + 1;
32 |
33 | % Get the dimensions of the projection
34 | proj_dims = size(volume);
35 | proj_dims(axis1) = [];
36 | proj_dims(axis2) = [];
37 |
38 | % Project the volume onto the plane
39 | proj = zeros(proj_dims);
40 | [proj_coords1, proj_coords2] = ndgrid(1:proj_dims(1), 1:proj_dims(2));
41 | proj_coords = zeros([numel(proj_coords1), 3]);
42 | proj_coords(:, axis1) = proj_coords1(:);
43 | proj_coords(:, axis2) = proj_coords2(:);
44 | proj_coords(:, 3) = dot(normal, bsxfun(@minus, proj_coords, [1, 1, 1]), 2) ./ dot(normal, [0,0,1]');
45 |
46 | % Find the maximum intensity projection
47 | proj_coords = round(proj_coords);
48 | for i = 1:proj_dims(1)
49 | for j = 1:proj_dims(2)
50 | proj(i,j) = max(volume(proj_coords(i,j,1),:,proj_coords(i,j,3)));
51 | end
52 | end
53 | end
54 |
55 |
56 |
57 |
58 | % function [MIP, MIP_coords] = max_intensity_projection(volume, normal)
59 | % % volume: 3D volume
60 | % % normal: normal vector of the 2D plane
61 | % normal=normal./norm(normal);
62 | % % Find the two axes that lie in the plane
63 | % [~, axis1] = max(abs(normal));
64 | % axis2 = mod(axis1, 3) + 1;
65 | %
66 | % % Calculate the coordinates of the projection
67 | % [x, y] = meshgrid(1:size(volume, axis2), 1:size(volume, axis1));
68 | % proj_coords = zeros([numel(x), 3]);
69 | % proj_coords(:, axis1) = reshape(y, [], 1);
70 | % proj_coords(:, axis2) = reshape(x, [], 1);
71 | % proj_coords(:, 3) = round((normal* proj_coords' - dot(normal, [1,1,1]')) ./ dot(normal, [0,0,1]'));
72 | %
73 | % % Clip coordinates outside the volume
74 | % valid_indices = all(proj_coords > 0, 2) & all(proj_coords <= repmat(size(volume), [numel(x), 1]), 2);
75 | % proj_coords = proj_coords(valid_indices, :);
76 | %
77 | % % Compute the maximum intensity projection
78 | % MIP = zeros(size(volume, axis1), size(volume, axis2));
79 | % MIP_coords = zeros(size(MIP, 1), size(MIP, 2), 3);
80 | % for i = 1:size(proj_coords, 1)
81 | % x = proj_coords(i, axis2);
82 | % y = proj_coords(i, axis1);
83 | % z = proj_coords(i, 3);
84 | % intensity = volume(y, x, z);
85 | % if intensity > MIP(y, x)
86 | % MIP(y, x) = intensity;
87 | % MIP_coords(y, x, :) = [y, x, z];
88 | % end
89 | % end
90 | % end
91 |
92 |
93 | function coords = get_voxel_coords(size)
94 | % Helper function to compute the coordinates of all voxels in a volume
95 | [x, y, z] = ndgrid(1:size(1), 1:size(2), 1:size(3));
96 | coords = [x(:), y(:), z(:)];
97 | end
98 |
99 | function R = get_rot(u, v)
100 | % Calculate the cross product of u and v
101 | w = cross(u, v);
102 |
103 | % Calculate the angle between u and v
104 | theta = acos(dot(u, v));
105 |
106 | % Check if the vectors are parallel and handle the special case
107 | if theta < eps
108 | R = eye(3);
109 | else
110 | % Calculate the rotation matrix using the axis-angle representation
111 | w_skew = [0, -w(3), w(2); w(3), 0, -w(1); -w(2), w(1), 0];
112 | R = eye(3) + w_skew*sin(theta) + w_skew^2*(1-cos(theta));
113 | end
114 | end
115 |
116 | function max_proj_volume = find_max_projection_and_set_to_zero(volume, direction)
117 |
118 | direction = direction / norm(direction);
119 |
120 | % Compute the maximum intensity projection of the volume in the direction vector
121 | projection = sum(volume .* repmat(direction', size(volume)), 4);
122 | [max_projection, idx] = max(projection, [], 'all', 'linear');
123 |
124 | % Set all voxels in the volume that are not in the projection plane to 0
125 | [xx, yy, zz] = ind2sub(size(volume), idx);
126 | [~, ~, V] = svd(normal);
127 | x_range = 1:size(volume, 1);
128 | y_range = 1:size(volume, 2);
129 | z_range = 1:size(volume, 3);
130 | x_range(xx) = [];
131 | y_range(yy) = [];
132 | z_range(zz) = [];
133 | [X, Y, Z] = ndgrid(x_range, y_range, z_range);
134 | coords = [X(:), Y(:), Z(:)];
135 | projection_plane = [xx*ones(size(coords, 1), 1), yy*ones(size(coords, 1), 1), zz*ones(size(coords, 1), 1)];
136 | coords_on_plane = coords - projection_plane;
137 | coords_on_plane_rot = (V' * coords_on_plane')';
138 | max_dist = max(abs(coords_on_plane_rot), [], 2);
139 | mask = max_dist < 1e-3; % tolerance for numerical errors
140 | volume(~mask) = 0;
141 |
142 | % Display the maximum intensity projection
143 | figure;
144 | imshow(max_projection, []);
145 |
146 |
147 |
148 |
149 |
150 | % volume is the 3D matrix representing the volume
151 | % direction is a 3-element vector specifying the direction
152 | direction = direction./sqrt(sum((direction.^2)));
153 | std_vec=[1,0,0];
154 | R=get_rot(std_vec,direction);
155 |
156 | % % Determine the direction of the parallel view
157 | % view_direction = [1, 0, 0]; % for example, this is the x-axis direction
158 |
159 | % Calculate the maximum 2D projection in the specified direction
160 | max_proj = max(volume, [], find(direction));
161 |
162 | % Create a binary mask of the max projection
163 | max_proj_mask = max_proj > 0;
164 |
165 | % Set all voxels in the volume that are not in the max projection to 0
166 | volume(~max_proj_mask) = 0;
167 |
168 | % Display the max projection
169 | imshow(max_proj);
170 |
171 |
172 |
173 | % Compute the dot product between each coordinate and the direction vector
174 | [X, Y, Z] = ndgrid(1:size(volume,1), 1:size(volume,2), 1:size(volume,3));
175 | coords = [X(:) Y(:) Z(:)];
176 | proj_coords = coords * direction(:);
177 |
178 | % Reshape the projection coordinates into a 3D matrix
179 | proj_coords = reshape(proj_coords, size(volume));
180 |
181 | % Compute the maximum value projection along the appropriate dimension
182 | [max_proj, idx] = max(proj_coords, [], 'all', 'linear');
183 | [max_proj_i, max_proj_j, max_proj_k] = ind2sub(size(volume), idx);
184 |
185 | % Create a binary mask of voxels that are part of the maximum projection
186 | max_proj_mask = zeros(size(volume));
187 | max_proj_mask(max_proj_i, max_proj_j, max_proj_k) = 1;
188 | % max_proj_mask(max_proj_j, max_proj_i, max_proj_k) = 1;
189 |
190 | % Set all voxels that are not part of the maximum projection to zero
191 | max_proj_volume = volume .* max_proj_mask;
192 |
193 | end
194 |
195 | % % Create a random 3D matrix of size 10x10x10
196 | % volume = rand(10, 10, 10);
197 | %
198 | % % Specify the direction as a unit vector
199 | % direction = [1, 1, 1] / sqrt(3);
200 | %
201 | % % Find the maximum value projection along the direction vector and set all other voxels to zero
202 | % max_proj_volume = find_max_projection_and_set_to_zero(volume, direction);
203 | %
204 | % % Display the resulting volume using the maximum value as the colormap limit
205 | % max_val = max(max_proj_volume(:));
206 | % figure;
207 | % sliceViewer(max_proj_volume, [], [], [], [], [], [], max_val);
208 | % This code creates a random 3D matrix of size 10x10x10, specifies the direction as a unit vector, and computes the maximum value projection in the volume along that direction using the find_max_projection_and_set_to_zero function. The resulting volume is then displayed using the sliceViewer function from the Image Processing Toolbox, with the maximum value as the colormap limit.
209 |
210 |
211 |
212 |
213 |
214 |
215 | function max_coord = find_max_coordinate(volume)
216 | % volume is the 3D matrix representing the volume
217 |
218 | % Find the maximum value and its index in the volume
219 | [max_value, max_idx] = max(volume(:));
220 |
221 | % Convert the 1D index to 3D coordinates
222 | [x, y, z] = ind2sub(size(volume), max_idx);
223 | max_coord = [x, y, z];
224 | end
225 |
226 | function [closest_point, distance] = find_closest_point_to_volume(point, volume, voxel_size)
227 | if nargin<3
228 | voxel_size=[1,1,1];
229 | end
230 | % point is a 3-element vector representing the query point
231 | % volume is a 3D matrix representing the volume
232 | % voxel_size is a 3-element vector representing the size of a voxel in each dimension
233 |
234 | % Compute the coordinates of all voxels in the volume
235 | [x, y, z] = ndgrid(1:size(volume, 1), 1:size(volume, 2), 1:size(volume, 3));
236 | voxel_coords = [x(:), y(:), z(:)];
237 |
238 | % Compute the physical coordinates of each voxel
239 | phys_coords = bsxfun(@times, voxel_coords - 1, voxel_size(:)') + voxel_size(:)'/2;
240 |
241 | % Compute the distances between the query point and each voxel
242 | distances = sqrt(sum((phys_coords - point(:)').^2, 2));
243 |
244 | % Find the index of the closest voxel
245 | [~, idx] = min(distances);
246 |
247 | % Convert the index to voxel coordinates
248 | [x, y, z] = ind2sub(size(volume), idx);
249 |
250 | % Compute the physical coordinates of the closest voxel
251 | closest_voxel = bsxfun(@times, [x, y, z] - 1, voxel_size(:)') + voxel_size(:)'/2;
252 |
253 | % Compute the distance between the query point and the closest voxel
254 | distance = sqrt(sum((closest_voxel - point(:)').^2));
255 |
256 | % Return the physical coordinates of the closest point
257 | closest_point = closest_voxel;
258 |
259 | end
260 |
261 |
262 | % function closest_point = find_closest_point_to_volume(point, volume)
263 | % % point is the 3D coordinate of the specific point
264 | % % volume is a 3D matrix representing the volume
265 | %
266 | % % Compute the distance from the point to each point in the volume
267 | % distances = sqrt(sum((volume - repmat(point, size(volume(:), 1), 1)).^2, 2));
268 | %
269 | % % Find the point with the smallest distance to the point
270 | % [~, idx] = min(distances);
271 | %
272 | % % Convert the 1D index to 3D coordinates
273 | % [x, y, z] = ind2sub(size(volume), idx);
274 | % closest_point = [x, y, z];
275 | %
276 | % % Check if the closest point is inside the volume
277 | % if volume(closest_point(1), closest_point(2), closest_point(3)) == 1
278 | % % The point is inside the volume, return the point
279 | % return
280 | % end
281 | %
282 | % % Find the boundary of the volume
283 | % boundary = zeros(size(volume));
284 | % boundary(1,:,:) = 1;
285 | % boundary(end,:,:) = 1;
286 | % boundary(:,1,:) = 1;
287 | % boundary(:,end,:) = 1;
288 | % boundary(:,:,1) = 1;
289 | % boundary(:,:,end) = 1;
290 | %
291 | % % Project the closest point onto the boundary
292 | % distances = sqrt(sum((boundary - repmat(closest_point, size(boundary(:), 1), 1)).^2, 2));
293 | % [~, idx] = min(distances);
294 | % [x, y, z] = ind2sub(size(volume), idx);
295 | % closest_point = [x, y, z];
296 | % end
297 |
298 |
299 |
300 | % % Create a 3D matrix with a thin plate of arbitrary orientation
301 | % matrix = zeros(10, 10, 10);
302 | % [x,y,z] = meshgrid(1:10);
303 | % matrix(sqrt((x-5).^2 + (y-5).^2 + (z-5).^2) <= 3) = 1;
304 | %
305 | % % Calculate the thickness of the plate
306 | % thickness = plate_thickness(matrix);
307 | % disp(thickness);
308 |
309 |
310 |
311 |
312 | %
313 | %
314 | %
315 | % function asd=avg_surf_dist(vol1,vol2,side_idx,sample_rate)
316 | % if nargin<4
317 | % sample_rate=1;
318 | % if nargin<3
319 | % side_idx=1;
320 | % end
321 | % end
322 | % % % lap_k1=[];
323 | % % lap_k0=[0,0,0;
324 | % % 0,-1,0;
325 | % % 0,0,0];
326 | % % lap_k2=[0,-1,0;
327 | % % -1,6,-1;
328 | % % 0,-1,0];
329 | % % lap_kernel=cat(3,lap_k0,lap_k2,lap_k0);
330 | % % v1=convn(double(vol1),lap_kernel,'same')>0.5;
331 | % % v2=convn(double(vol2),lap_kernel,'same')>0.5;
332 | % v1=lap_conv3d(vol1)>0.5;
333 | % v2=lap_conv3d(vol2)>0.5;
334 | % % volshow(v2);
335 | % [~,coord1]=img2ind(v1);
336 | % [~,coord2]=img2ind(v2);
337 | % dist_mat=pdist2(coord1(1:sample_rate:end,:),coord2(1:sample_rate:end,:),"euclidean");
338 | % asd=mean(min(dist_mat,[],side_idx));
339 | %
340 | % end
341 | %
342 | % function [ind,pnd]=img2ind(img,thresh)
343 | % if nargin<2
344 | % thresh=0.000000001;
345 | % end
346 | % img_sz=size(img);
347 | % ind=find(img>thresh);
348 | % pnd=[];
349 | % id=ind;
350 | % for s=img_sz
351 | % coord=mod(id,s);
352 | % pnd=[pnd,coord];
353 | % id=floor(id/s);
354 | % end
355 | % end
--------------------------------------------------------------------------------