Skip to content
Snippets Groups Projects
porosity_analysis_bone.m 6.51 KiB
Newer Older
  • Learn to ignore specific revisions
  • BehnazP's avatar
    BehnazP committed
    %   Copyright 2018 Vedrana Andersen Dahl, vand@dtu.dk 
    clear
    close all
    addpath functions
    
    load bonesub
    gray_th = 3*10^4;
    div = [0.5 30.5,70.5,100.5,130.5,170.5 size(V,3)+0.5]; % layer divisions
    midlayer = floor(0.5*(div(1:end-1) + div(2:end))); % middle slice of a layer
    
    %% volume inspection -- use arrows
    show_matvol(permute(V,[3,2,1]))
    hold on, plot([1;size(V,2)]*ones(1,5),[1;1]*div(2:end-1),'r','LineWidth',2)
    text(size(V,2)/2*ones(1,6),midlayer,num2cell(1:6),'Color','r','FontSize',20)
    show_matvol(V)
    
    %% still figures
    x = 100;
    figure, imagesc(squeeze(V(x,:,:))'); axis image, colormap gray
    hold on, plot([1;size(V,2)]*ones(1,5),[1;1]*div(2:end-1),'r','LineWidth',2)
    text(size(V,2)/2*ones(1,6),midlayer,num2cell(1:6),'Color','r','FontSize',20)
    title(['Longitudinal slice, x=',num2str(x)]), xlabel('y'), ylabel('z')
    
    figure
    for i=1:numel(midlayer)
        subplot(2,3,i), imagesc(V(:,:,midlayer(i))), axis image, colormap gray
        title(['Region ' num2str(i), ', z=',num2str(midlayer(i))])
        xlabel('y'), ylabel('x')
    end
    
    %% binarization
    B = medfilt3(medfilt3(V,[3,3,3])>gray_th,[3,3,3]);
    show_matvol(B)
    
    %% still figures
    figure, imagesc(squeeze(B(x,:,:))'); axis image, colormap gray
    hold on, plot([1;size(B,2)]*ones(1,5),[1;1]*div(2:end-1),'r','LineWidth',2)
    text(size(V,2)/2*ones(1,6),midlayer,num2cell(1:6),'Color','r','FontSize',20)
    title(['Longitudinal slice, x=',num2str(x)]), xlabel('y'), ylabel('z')
    
    figure
    for i=1:numel(midlayer)
        subplot(2,3,i), imagesc(B(:,:,midlayer(i))), axis image, colormap gray
        title(['Region ' num2str(i), ', z=',num2str(midlayer(i))])
        xlabel('y'), ylabel('x')
    end
    
    %% distance transform
    distances = bwdist(~B) - bwdist(B) - B + 0.5; % distance from voxel center to interface
    show_matvol(distances)
    
    %% skeletonization of fibres and air 
    % criterium: local maxima in any of the 3 planes for larger number of sceleton points)
    conn = cat(3,zeros(3,3),[0 1 0; 1 1 1; 0 1 0],zeros(3,3));
    skeleton = ((imregionalmax(distances,conn) | imregionalmax(distances,permute(conn,[2 3 1]))...
        | imregionalmax(distances,permute(conn,[3 1 2]))) & B)...
        |  (imregionalmin(distances,conn) | imregionalmin(distances,permute(conn,[2 3 1]))...
        | imregionalmin(distances,permute(conn,[3 1 2]))) & ~B;
    
    % alternative with 3D local maxima, which yields less points
    % conn = cat(3,[0 0 0; 0 1 0; 0 0 0],[0 1 0; 1 1 1; 0 1 0],[0 0 0; 0 1 0; 0 0 0]);
    % skeleton = (imregionalmax(distances,conn) & B) | (imregionalmax(distances,conn) & ~B);
    
    % cleaning
    % skeleton = skeleton & abs(distances)>1;
    skeleton([1,end],:,:) = false; skeleton(:,[1,end],:) = false; skeleton(:,:,[1,end]) = false;
    
    %% visualizing single slice with a special colormap
    z = 100; % and only a slice
    [U,cmap,cbar] = color_skeleton(B(:,:,z),skeleton(:,:,z),distances(:,:,z));
    figure, imagesc(U), colormap(cmap), axis image, title(['Slice z=',num2str(z)])
    colorbar(cbar{:})
    
    [U,cmap,cbar] = color_skeleton(squeeze(B(x,:,:))',squeeze(skeleton(x,:,:))',squeeze(distances(x,:,:))');
    figure, imagesc(U), colormap(cmap), axis image, 
    title(['Longitudinal slice, x=',num2str(x)]), xlabel('y'), ylabel('z')
    colorbar(cbar{:})
    
    %% visualizing multiple slices using special colormap
    [U,cmap,cbar] = color_skeleton(B,skeleton,distances);
    figure
    for i=1:numel(midlayer)
        subplot(2,3,i), imagesc(U(:,:,midlayer(i)),[0,255]), axis image, colormap(cmap)
        title(['region ' num2str(i), ', z=',num2str(midlayer(i))])
        xlabel('y'), ylabel('x')
    end
    
    %% volume slicing using special colormap
    show_matvol(U,[0,255]), colormap(cmap); % full volume
    colorbar(cbar{:})
    
    %% measuring porosity for a whole volume
    volume_all = sum(B(:))/numel(B); % phase volume per block volume
    area_all = compute_area(B)/numel(B); % phase surface per block volume
    
    % measures from distance fields
    figure
    inside_all = fit_distribution(distances(skeleton & B),true);
    a = gca; title([{'Thickness for a whole sample'};a.Title.String])
    xlim([0 30]), xlabel('Radius (pixels)'), ylabel('Count')
    
    figure
    outside_all = fit_distribution(-distances(skeleton & ~B),true);
    a = gca; title([{'Spacing for a whole sample'};a.Title.String])
    xlim([0 30]), xlabel('Radius (pixels)'), ylabel('Count')
    
    %% performing layered collection of measures
    
    volume_layer = zeros(numel(midlayer),1);
    area_layer = zeros(numel(midlayer),1);
    inside_layer = zeros(numel(midlayer),5);
    outside_layer = zeros(numel(midlayer),5);
    
    fig_in = figure;
    fig_out = figure;
    for i = 1:numel(midlayer)
        range = ceil(div(i)):floor(div(i+1));
        B_layer = B(:,:,range);
        distances_layer = distances(:,:,range);
        skeleton_layer = skeleton(:,:,range);
        
        volume_layer(i) = sum(B_layer(:))/numel(B_layer);
        area_layer(i) = compute_area(B_layer)/numel(B_layer);
        
        % measures from distance fields
        figure(fig_in), subplot(2,3,i)
        inside_layer(i,:) = fit_distribution(distances_layer(skeleton_layer & B_layer),true);
        legend off, xlim([0 25])
        title(['Thickness for region ' num2str(i)])
        
        figure(fig_out), subplot(2,3,i)
        outside_layer(i,:) = fit_distribution(-distances_layer(skeleton_layer & ~B_layer),true);
        legend off, xlim([0 25])
        title(['Separation for region ' num2str(i)])
    end
    
    %% saving results
    % fid = fopen('results.tex','w');
    % fprintf(fid, 'Measure & Sample & Region 1 & Region 2 & Region 3 & Region 4 & Region 5 & Region 6 \\\\\\hline\n');
    % fprintf(fid, 'Bone volume & %.2f & %.2f & %.2f & %.2f & %.2f & %.2f & %.2f \\\\\n',[volume_all; volume_layer]);
    % fprintf(fid, 'Area & %.2f & %.2f & %.2f & %.2f & %.2f & %.2f & %.2f \\\\\n',[area_all; area_layer]);
    % fprintf(fid, 'Area per bone volume & %.2f & %.2f & %.2f & %.2f & %.2f & %.2f & %.2f \\\\\n',[area_all; area_layer]./[volume_all; volume_layer]);
    % fprintf(fid, 'Thickness, mode & %.2f & %.2f & %.2f & %.2f & %.2f & %.2f & %.2f \\\\\n',[inside_all(5); inside_layer(:,5)]);
    % fprintf(fid, 'Thickness, median & %.2f & %.2f & %.2f & %.2f & %.2f & %.2f & %.2f \\\\\n',[inside_all(1); inside_layer(:,1)]);
    % fprintf(fid, 'Thickness, mean & %.2f & %.2f & %.2f & %.2f & %.2f & %.2f & %.2f \\\\\n',[inside_all(3); inside_layer(:,3)]);
    % fprintf(fid, 'Separation, mode & %.2f & %.2f & %.2f & %.2f & %.2f & %.2f & %.2f \\\\\n',[outside_all(5); outside_layer(:,5)]);
    % fprintf(fid, 'Separation, median & %.2f & %.2f & %.2f & %.2f & %.2f & %.2f & %.2f \\\\\n',[outside_all(1); outside_layer(:,1)]);
    % fprintf(fid, 'Separation, mean & %.2f & %.2f & %.2f & %.2f & %.2f & %.2f & %.2f \\\\\n',[outside_all(3); outside_layer(:,3)]);
    % fclose(fid);
    % 
    % for savefig = [3,4,6,7,9,10,11,13,14,15,16]
    %     set(savefig,'Units','Normalized','Position',[0.1 0.1 0.6 0.8])
    %     saveas(savefig,['Figure_',num2str(savefig),'.eps'],'epsc');    
    % end