Error: Unable to perform assignment because the size of the left side is 320-by-320 and the size of the right side is 320-by-320-by-1-by-90.
1 回表示 (過去 30 日間)
古いコメントを表示
s = dicomread('IMG-0001-00001.dcm');
[r c x] = size(s);
img = repmat(double(0), [r c 1 26]);
for p=1:26
filename = sprintf('IMG-000%d-00001.dcm', p);
img(:,:,1,p) = double(dicomread(filename));
end
I basically used this Read DICOM files and create a Montage but the error shows up for the statement "img(:,:,1,p) = double(dicomread(filename));"
I have read the similar questions posted by the others, but I still could not figure out. Any help will be much appreciated. Thank you.
0 件のコメント
回答 (1 件)
Walter Roberson
2020 年 11 月 5 日
This is expected for some DICOM modalities, as they deal with time series (such as Ultrasound). DICOM that deal with multiple slices such as CT are more typically 3 dimensional, especially if they have already been reconstructed.
img = dicomread('IMG-0001-00001.dcm');
img(1,1,1,1,26) = 0;
for p=2:26
filename = sprintf('IMG-000%d-00001.dcm', p);
img(:,:,:,:,p) = dicomread(filename);
end
If what you are reading is not already double then using just double() is typically not correct. For example for CT you would typically need to pull out rescale slope and rescale intercept headers and use those to convert, and in theory those could vary from file to file (but it would be uncommon for them to differ within a single run.) If the 4th dimension is z (third dimension being color) then you also need headers about the x and y and z scales and there are tricks about finding the z scale.
Once you have the data you need to figure out what a montage of multidimensional data means. You might squeeze down to 4d... x y z time? Montage of 3d gets difficult to interpret without rotation or slice planes...
5 件のコメント
Walter Roberson
2020 年 11 月 5 日
num_slices = 26;
filenames = compose("IMG-%05d-00001.dcm", 1:N);
for slice_idx = num_slices: -1 : 1
slice_number = slices_to_read(slice_idx);
filename = filenames{slice_idx};
info(slice_idx) = dicominfo(filename);
if ~isfield(info(slice_idx), 'RescaleSlope') || isempty(info(slice_idx).RescaleSlope)
info(slice_idx).RescaleSlope = 1;
end
if ~isfield(info(slice_idx), 'RescaleIntercept') || isempty(info(slice_idx).RescaleIntercept)
info(slice_idx).RescaleIntercept = 0;
end
thisimg = dicomread(info(slice_idx));
thisimg = double(thisimg) .* info(slice_idx).RescaleSlope + info(slice_idx).RescaleIntercept;
img(:,:,:,:,slice_idx) = thisimg;
end
Walter Roberson
2020 年 11 月 5 日
In my earlier code, I had read the first file into the variable img. That was going to give you a 320 x 320 x 1 x 90 variable. Then, instead of just using that to figure out what the size is, build a new variable and copy everything to the new variable, I decided to take the data just read in and extend it in-place to hold more data
img(1,1,1,1,26) = 0;
is taking the 320 x 320 x 1 x 90 image, which is also 320 x 320 x 1 x 90 x 1, and assigning to location (1,1,1,1,26), which automatically extends the array to 320 x 320 x 1 x 90 x 26, filling in all of the other values with 0.
The reason to do this is pre-allocating all of the memory for the images ahead of time, so that you do not end up extending the img array each time you add one more image.
In the newer code I just posted that deals with rescale slopes and so on, I took a completely different approach to pre-allocating. Notice I have for slice_idx = num_slices: -1 : 1 which is starting at slice 26 and moving backwards down to slice 1. That way, the img array is assigned to from back to front, which means that the first time it gets assigned to the full space gets allocated, and the other times are filling in the content into the space already reserved.
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!