Switch to unified view

a b/whole_mount_tiles_stitching.m
1
function msg = whole_mount_tiles_stitching
2
%% Whole Mount Tile Stitching
3
4
%% Purpose:  
5
% This function creates a whole-mount image from individual tiles and implements
6
% black_border_removal to remove border around image in the case of old
7
% images that were scanned with a border.
8
9
%% ------------------------------------------------------------------------
10
11
% directory = ''; name the needed directory that contains tiled images to
12
% be re-stitched together
13
% subj = XX; % patient number
14
% slice = "XX"; % slide name
15
% scanner = "Olympus"; % scanner name indictate tile sizes
16
% anot_micro = "Nikon"; % scanner used if originally annotated on a
17
% previous scanner
18
19
for d = 1:numel(directory)
20
    tic;
21
    addpath(directory(d))
22
    subj_slice = sprintf('%i_%s',subj(d),slice(d));
23
    fprintf('Processing: %s\n',subj_slice);
24
    
25
    disp('Loading images');
26
    
27
    files = fullfile(directory(d),'tile*.tiff');
28
    input_images = dir(files);
29
    input_images = {input_images.name}';
30
    
31
    if (isempty(input_images))
32
        files = fullfile(directory(d), 'tile*.jpg'); % adjust extension if needed
33
        input_images = dir(files);
34
        input_images = {input_images.name}';
35
    end
36
    
37
    name = strsplit(input_images{numel(input_images)},{'_','.'});
38
    xmax = str2num(name{2}(2:end));
39
    ymax = str2num(name{3}(2:end));
40
    
41
    x = [1 xmax];
42
    y = [1 ymax];
43
    
44
    xx = 1;
45
    yy = 1;
46
    
47
    
48
    if strcmp(scanner(d),'Huron')
49
        resize_factor = 10; % 8 nikon/olympus 12 huron
50
    else
51
        resize_factor = 8;
52
    end
53
    
54
    im = uint8(imread(input_images{numel(input_images)}));
55
    im_size = size(im);
56
    im = imrotate(imresize(im,1/8),90);
57
    ximage = cell(1,numel(input_images));
58
    yimage = cell(1,numel(input_images));
59
    for i = 1:numel(input_images)
60
        ximage{i} = ones(size(im(:,:,1)),'uint8') * xx;
61
        ximage{i} = imresize(ximage{i},[1 size(im,1)],'nearest');
62
        ximage{i} = imrotate(ximage{i},90);
63
        
64
        xx = xx + 1;
65
        if xx > xmax
66
            xx = 1;
67
        end
68
        
69
        yimage{i} = ones(size(im(:,:,1)),'uint8') * yy;
70
        yimage{i} = imresize(yimage{i},[1 size(im,2)],'nearest');
71
        yimage{i} = imrotate(yimage{i},90);
72
        
73
        yy = yy + 1;
74
        if yy > ymax
75
            yy = 1;
76
        end
77
    end
78
    
79
    disp('Creating rows');
80
    % Arrange rows
81
    ind1 = y(1);
82
    ind2 = y(2);
83
    rows = cell(1,xmax);
84
    for i = 1:xmax
85
        im = cell(1,ymax);
86
        ind3 = 1;
87
        for j = ind1:ind2
88
            im{ind3} = imrotate(imresize(uint8(imread(input_images{j})),1),90);
89
            ind3 = ind3 + 1;
90
        end
91
92
        rows{i} = imtile(im,'GridSize',[1 ymax]); clear im;
93
        rows{i} = imrotate(rows{i},180); % flips orientation
94
        
95
        ind1 = ind1 + ymax;
96
        ind2 = ind2 + ymax;
97
        if ind2 > numel(input_images)
98
            break
99
        end
100
    end
101
    
102
    toc
103
    xx = 1;
104
    xrows = cell(1,xmax);
105
    missing_vals = cell(1,xmax);
106
    for i = 1:xmax
107
        xrows{i} = ximage(xx:xmax:size(ximage,2)); % creates image rows
108
        xrows{i} = imtile(xrows{i},'GridSize',[1 size(rows{1},2)]);
109
        missing_vals{i} = uint8((xrows{i} == 0)*i); % xrows is filled with 0s beyond what was created above
110
        xrows{i} = xrows{i} + missing_vals{i};
111
        
112
        xx = xx + 1;
113
        if xx > xmax
114
            break
115
        end
116
    end
117
    
118
    yy = 1;
119
    ycols = cell(1,ymax);
120
    missing_vals = cell(1,ymax);
121
    for i = 1:ymax
122
        ycols{i} = yimage(yy:ymax:size(yimage,2)); % creates image cols
123
        ycols{i} = imtile(ycols{i},'GridSize',[1 xmax*size(rows{1},1)])'; % inverting creates col from row
124
        missing_vals{i} = uint8((ycols{i} == 0)*i);
125
        ycols{i} = ycols{i} + missing_vals{i};
126
        
127
        yy = yy + 1;
128
        
129
        if yy > ymax
130
            break
131
        end
132
    end
133
    
134
    toc
135
    
136
    disp('Compiling image');
137
       
138
    whole_image = imtile(rows,'GridSize',[xmax 1]);
139
    whole_image = imrotate(whole_image,-180);
140
141
    whole_ximage = flipud(imtile(xrows,'GridSize',[xmax 1])); % tile numbering starts in LL
142
    whole_ximage = double(whole_ximage);
143
    % figure(); imagesc(whole_ximage);
144
    
145
    whole_yimage = imtile(ycols,'GridSize',[1 ymax]);
146
    whole_yimage = double(whole_yimage);
147
    % figure(); imagesc(whole_yimage);
148
    toc
149
    disp('Saving image');
150
%     figure(); imshow(whole_image);
151
    %                 saveas(gcf,sprintf('%s_whole_mount_recon_%i',subj_slice,resize_factor),'tif');
152
153
toc
154
msg = 'done';
155
disp(msg)