CombinedDatastore not returning a cell array

3 views (last 30 days)
I'm having trouble with combine in the context of doing an image-to-image regression task; basically, predicting the content of a target image volume (in one imaging modality) from a different image volume. I'm expecting to get a cell array of data when I call read(combinedDS) but instead I'm getting a scalar volume that's the wrong size. Downstream, this is causing trainnet to crash with the error "The number of datastore outputs (1) must match the number of network inputs plus the number of targets (2)." and I'm not sure how to fix it.
The code that I'm using looks like the following:
% Get the underlying data
ds1 = imageDatastore('../data/mode-1/','FileExtensions','.nii','ReadFcn',@(x) niftiread(x));
ds2 = imageDatastore('../data/mode-2/','FileExtensions','.nii','ReadFcn',@(x) niftiread(x));
% these correspond to subject-1 scan-1, subject-2 scan-1, ...
% subject-1 scan-2, subject-2 scan-2, etc.
% all of the NIFTI files have the same size
img_size = size(preview(inv1));
% NIFTI files were saved with real, imaginary concatenated on DIM3 - convert this to channel
fix_dims = @(x) reshape(x,img_size(1),img_size(2), [], 2);
ds1_4d = transform(ds1, fix_dims);
ds2_4d = transform(ds2, fix_dims);
% Split into training and validation data
n_subjects = numel(ds1.Files)
idx_validation = [12, 29, 35, 37, 43, 50, ... 245 ] % not exactly how I define these but that's not the point
idx_training = setdiff(1:n_subjects, idx_validation );
ds1_train = subset(ds1_4d, idx_training);
ds2_train = subset(ds2_4d, idx_training);
training = combine(ds1_train, ds2_train);
% and similar for validation
The documentation shows that the expected output of read(training) is something like:
dataOut=1×2 cell array {480×640×3 uint8} {480×640 uint8}
What I'm instead getting is something like:
dataOut= 4D single [176×480×256×2 single] % size(read(training))
The previous steps seem correct:
check_ds14d = 4D single [176×240×256×2 single] % size(read(ds1_4d))
check_ds1 = 3D single [176×240×512 single] % size(read(ds1))
Is this an issue with the fact that the datatype is single instead of uint8? Or possibly with the fact that the images are the same size, so they get concatenated instead of returned as cells? Is there a workaround for my issue?

Accepted Answer

Jayanti
Jayanti on 21 Oct 2024
Hi Calvin,
The transformation function you used returns a reshaped array, not a cell array. As a result, when the “transform” function is applied, the output remains a numeric array, not a cell array.
To address this, you can modify it as follows:
fix_dims = @(x) {reshape(x, imgSize(1), imgSize(2), [], 2)};
By wrapping the reshaped array in curly braces {}, you convert it into a cell array. This ensures that each read operation from the transformed datastore returns a cell array, allowing the combine function to produce a 1x2 cell array as output.
Hope this will resolve your query!
  1 Comment
Calvin Eiber
Calvin Eiber on 27 Oct 2024
That's not where I was having a problem - it's the combine() step, further down.
I wound up fixing this in a similar way to the fix_dims, by adding an extra transformation step. Now, I just need to figure out why trainnet() hangs the second time it tries to do a validation pass.
% my solution:
unhack = @(x) {x(:,1:end/2,:,:), x(:,end/2+1:end,:,:)};
training = transform(training, unhack);
validation = transform(validation, unhack);

Sign in to comment.

More Answers (0)

Categories

Find more on Image Data Workflows in Help Center and File Exchange

Products


Release

R2024b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!