Clear Filters
Clear Filters

Array exceeds memory size (9GB), although it is smaller than other arrays that work well?!

2 views (last 30 days)
Hi everyone,
so I use the 'imclose' in-built function from MATLAB for images of sizes around 2000*1000 pixels.
When I apply the function to the whole image everything works fine, but when I use indices, like
x=[1:500], y=[1:500],
and apply the function
imclose(IM(x,y))
I am getting an error
Requested 35124x35124 (9.2GB) array exceeds maximum array size preference. Creation of arrays greater than this limit may take a
long time and cause MATLAB to become unresponsive. See array size limit or preference panel for more information.
, which is confusing me, because the whole image is bigger than a 500*500 area inside the image. So I think it has to do something with the use of he indices?!
I am thankful for every help!
Greets!
  2 Comments
Guillaume
Guillaume on 11 Dec 2018
Can you post the exact code you're using and the full content of the error (particularly the bits that show the line that caused the errors)?
Have you checked that your x and y are actually the vectors you state at the point you're doing the indexing?
Payjay
Payjay on 11 Dec 2018
Hi and thanks for reply!
I get the coordinates from the 'PixelIdxList' of the 'bwconncom' in-built function and actually x and y are of length 35124 and represent a specific pixel cluster inside the image. So these are specific coordinates, whereas x=1:500 and y=1:500 represent a 'bounding box' containing 250000 pixel coordinates, which, however are not represented in a singular fashion.
Do you know a way to drive around this problem?
I tried also to to construct a box around the pixel cluster which works but if it is possible I just want to have the cluster and nothing else..
Here the code for a box around the pixel cluster. The output of this then work again for 'imclose'.
toy2D = zeros(size(im(:,:,1)));
toy3D = zeros(size(im));
ind = cat(1,SingleClusterIndices); % SingleClusterIndices = ind2sub(size(im),PixelIdxList{i})
x_max = max(ind(:,1));
y_max = max(ind(:,2));
x_min = min(ind(:,1));
y_min = min(ind(:,2));
SingleCluster2DSmall = zeros(x_max -x_min, y_max - y_min);
SingleCluster3DSmall = zeros(x_max -x_min, y_max - y_min, 3);
for i=1:3
toy3D(ind(:,1), ind(:,2), i) = im(ind(:,1), ind(:,2), i);
SingleCluster3DSmall(ind(:,1), ind(:,2), i) = im(ind(:,1), ind(:,2), i);
end
toy2D(ind(:,1), ind(:,2)) = thinned_rem(ind(:,1), ind(:,2));
SingleCluster2DSmall(ind(:,1), ind(:,2)) = thinned_rem(ind(:,1), ind(:,2));
SingleCluster2DSmall = SingleCluster2DSmall(x_min:x_max, y_min:y_max);
d1 = SingleCluster3DSmall(x_min:x_max, y_min:y_max, 1);
d2 = SingleCluster3DSmall(x_min:x_max, y_min:y_max, 2);
d3 = SingleCluster3DSmall(x_min:x_max, y_min:y_max, 3);
SingleCluster3DSmall = cat(3, d1, d2, d3);
SingleCluster2D = toy2D;
SingleCluster3D = toy3D;
Thanks again for your answer, hope you can help :) Greets!

Sign in to comment.

Answers (1)

Guillaume
Guillaume on 11 Dec 2018
If you pass two 1x35124 vectors as indices, you will indeed get a 35124x35124 matrix back, which is the intersections of the 35124 rows and 35124 columns (some obviously repeated) you've passed. That's not the way to index the pixels, for that you'd have to convert the row, column and page indices into linear indices first. But in any case, that's not what you want to do as you'd no longer have an image, just a vector of pixel values, something that you can't imclose.
You don't have a choice, if you want to use imclose or any morphological operation, you need a rectangular portion of your image. One way to get that portion is to do what you have done indeed, take the minimum and maximum of your pixe indices and extract that portion of the image. You can however make your life easier, by using regionprops which can do that for you:
cc = bwconncomp(somebwimage);
props = regionprops(cc, {'BoundingBox', 'Image'}); %get bounding box and subimage of each cluster
for prop = props' %iterate over the clusters
something = imclose(prop.Image, strel('disk', 3));
%...
end
However, your code is a bit confusing (with some lines that look pointless such as the cat(1, SingleClusterIndices)) as you seem to be operating on a colour image (3D) which can't be an input to bwconncomp. Are the clusters detected by bwconncomp used as a mask in the colour image? If so, you can use the BoundingBox to extract the corresponding culster from the colour image
cc = bwconncomp(somebwimage);
props = regionprops(cc, {'BoundingBox', 'Image'}); %get bounding box and subimage of each cluster
for prop = props' %iterate over the clusters
bbox = prop.BoundingBox;
%See https://www.mathworks.com/help/images/image-coordinate-systems.html#bs5mv7n
%for an explanation of why the top left coordinate of bbox is fractional
colourcluster = colourimage(ceil(bbox(2) + (0:bbox(4)-1)), ceil(bbox(1) + (0:bbox(3)-1)), :);
maskedcolourcluster = colourcluster .* prop.Image; %set all pixels outside the cluster to black
%...
end

Community Treasure Hunt

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

Start Hunting!