petersaj / AP_histology

Histology processing
64 stars 22 forks source link

Original Image to CCF aligned #8

Closed juliencarponcy closed 2 years ago

juliencarponcy commented 2 years ago

Hi,

I read with interest the previous ongoing issue about transforming coordinates into the CCF framework. For the past days, I tried to assist a colleague in aligning different brain section onto a standard CCF section but I struggled on several points. First, it seems that the functions working inside the GUI won't take original files as input. As a consequence, original images have been rotated to align them to dorso/ventral axis, which is I think one parameter needed to obtain the final transformation to CCF coordinates. Also, I must confess that I struggled with the imref2d part. So in the end, I manage to have an image roughly transformed as the CCF one, but i'm missing a few things to realign different original images together onto the same CCF section.

Here is a very bad piece of prototype code of me trying to realign:

SlicesFolder = 'Z:\00 IMAGES\+0.50 mm';
load(fullfile(SlicesFolder,'atlas2histology_tform.mat'))
load(fullfile(SlicesFolder,'histology_ccf.mat'))

fold = dir(SlicesFolder);
idxtifs = [];

for f=1:length(fold)
    if contains(fold(f).name,'.tif')
        idxtifs = [idxtifs; f];
    end
end

fold=fold(idxtifs);

for s=1:length(fold)
    Images(s).raw = imread(fullfile(fold(s).folder, fold(s).name));
    tform = affine2d;
    tform.T = atlas2histology_tform{s};
    % (transform is CCF -> histology, invert for other direction)
    tform = invert(tform);

%     Images(s).RefAtlas = imref2d(size(histology_ccf(s).tv_slices,[1 2]),10,10);
    Images(s).RefHisto = imref2d(size(Images(s).raw,[1 2]),1,1); % 0.69 

    [Images(s).transformed_im, Images(s).transformed_ref2d] = imwarp(Images(s).raw, Images(s).RefHisto, tform)
%     h=figure; imshow(Images(s).transformed_im)
%     
%     % redraw line in case of original section not aligned with
%     % dorso-ventral axis
%     [x,y] = ginput(2)
%     
%     % calculate vector from the 2 points
%     ab = sqrt((y(2)-y(1))^2+(x(2)-x(1)^2))
%     
%     
%     diff = (atan((y(2)-y(1))/(x(2)-x(1))) - atan(0)) * 180/pi;
%     if abs(diff -90 ) > 2
%         % roate image only if angle > 2degrees
%         Images(s).trans_rotated_im = imrotate(Images(s).transformed_im,diff-90,'nearest','crop')
%     else
%         Images(s).trans_rotated_im  = Images(s).transformed_im
%     end
%         hrot=figure; imshow(Images(s).trans_rotated_im)

    Images(s).RefAtlas = imref2d(size(histology_ccf(s).tv_slices,[1 2]),10,10);
    Images(s).RefHisto = imref2d(size(Images(s).transformed_im,[1 2]),0.69,0.69); % 0.69 
    figure;imshowpair(Images(s).transformed_im,Images(s).transformed_ref2d,histology_ccf(s).tv_slices,Images(s).RefAtlas)
end

A couple of image examples of the results:

image

I tried to adjust the imref2d to take into account the order of the different transforms but never managed to get everything right. Notably the first transform (based on the inverse of the tform saved) gave me notably smaller picture from the original which i don't get (specifically when i specify imref2d pixelextent of 1). So all of that is still messy to me, don't get to make sense and reverse-engineer it from the original pictures.

Anyway, just checking in after the other issue to see whether you could possibly help for getting directly atlas aligned pictures from original pictures and transform, which should be derived from the function you suggested in the previous issue, but integrating the first downsampling transform, and possibly the first rotation to put the image vertical.

Thank you very much in advance,

Julien

petersaj commented 2 years ago

Yeah I think I can store some more info to make it easy to apply alignments to original files, let me check some things:

You were doing the right thing to go backwards, but the rotation/padding/downsampling isn't stored at the moment so wouldn't match up perfectly. Probably in your first example the offset is from padding the slice image (they're padded to be the same size in AP_rotate_histology, but don't have to be), and the second is probably related to resizing the imaging in AP_process_histology.

juliencarponcy commented 2 years ago

Thank you very much for your insightful answer, it looks like there is shared interest to transform histology ROIs AND pictures to the CCF framework through your version!

petersaj commented 2 years ago

Might be worth first trying to just not downsample the images (just setting resize_factor = 1) in AP_process_histology? The load times would be longer but I wouldn't think the computation time would be much longer, the rate-limiting step would be automatic alignment but that can be done when you're away from the computer.

If that's not a good solution for your images, I see the benefit of restructuring the code to do alignments on isolated/downsampled/flattened slice images, then applying those alignments to the original slide images for any real processing. In that case, it probably shouldn't save the intermediate small images if they're not useful for anything.

petersaj commented 2 years ago

(closing this for now, but let me know of there are continued issues)