CombinedDatastore not returning a cell array

18 ビュー (過去 30 日間)
Calvin Eiber
Calvin Eiber 2024 年 10 月 21 日
コメント済み: Calvin Eiber 2024 年 10 月 27 日 9:21
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?

採用された回答

Jayanti
Jayanti 2024 年 10 月 21 日
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 件のコメント
Calvin Eiber
Calvin Eiber 2024 年 10 月 27 日 9:21
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);

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeImage Data Workflows についてさらに検索

製品


リリース

R2024b

Community Treasure Hunt

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

Start Hunting!

Translated by