Faster alternative to mode?
Show older comments
Simple as that, in my code I am first determining the neighbourhood of a voxel and then determining the most frequent value in the neighbourhood. I am doing this for millions of voxels, so the computation time adds up. I am expecting this to take quite some time, however my entire code has been running for about 2.5 days now with no end in sight and I've determined that the bottleneck is this section of my code. Using profiler it appears that the function "mode" takes up almost 50% of the computation time of the this function, and about 25% of my entire code.
My method of determining the neighbourhood is the next slowest part of the code using: neighbourhood = im(i-1:i+1,j-1:j+1,k-1:k+1);
Does anyone have a good alternative to "mode" i can use in this situation? If anyone has any more efficient suggestions for finding the neighbourhood of the voxels that would also be appreciated.
Thanks!
for i = 1:size(lcoords,1)
%Get neighbourhood of voxel i from list of image voxel subscripts
neighbourhood = im(lcoords(i,1)-1:lcoords(i,1)+1,lcoords(i,2)-1:lcoords(i,2)+1, lcoords(i,3)-1:lcoords(i,3)+1);
neighbourhood(neighbourhood == imcoords(i,2)) = []; %Ignore parts of the neighbourhood that have same value as current voxel
if ~isempty(neighbourhood) %If the voxel is surrounded by any values not including its own region, find the mode of the neighbourhood
imcoords(i,3) = mode(neighbourhood(:)); %record the mode
end
end
5 Comments
darova
on 6 Apr 2020
Please show your code
Eric Chadwick
on 7 Apr 2020
darova
on 7 Apr 2020
The only idea i have is to change these lines
neighbourhood(neighbourhood == imcoords(i,2)) = []; %Ignore parts of the neighbourhood that have same value as current voxel
if ~isempty(neighbourhood) %If the voxel is surrounded by any values not including its own region, find the mode of the neighbourhood
On
tmp = neighbourhood == imcoords(i,2)
if any(~tmp)
I think it would be faster
What about mode? Is there something to simplify there?
darova
on 7 Apr 2020
Example:
tic
for i = 1:1e6
a = ones(5);
a(3) = [];
end
toc
tic
for i = 1:1e6
a = ones(5);
a(3) = 0;
end
toc
Because ofre-sizing the arrays on each iteration
Eric Chadwick
on 7 Apr 2020
Accepted Answer
More Answers (1)
It would be better not to implement the mode calculation repeatedly in a loop over the voxels. If you have enough RAM to hold 27 copies of your image volume, then this is one way to replace the loop with a vectorized calculation:
[di,dj,dk]=ndgrid(-1:+1);
Ishifts=repmat(im,1,1,1,27);
for n=1:27
Ishifts(:,:,:,n)=circshift(im,[di(n),dj(n),dk(n)]);
end
result=mode( Ishifts , 4);
6 Comments
Eric Chadwick
on 7 Apr 2020
John D'Errico
on 7 Apr 2020
Matt - I'd bet a decent sum of money the problem is mainly pre-allocation, or the lack thereof.
In the code as shown by the op, the variable imcoords is never pre-allocated, yet grown millions of times. That would surely explain the multiple day run time as seen.
The maximum RAM i have access to is 128 so there is no way I could even fit 27 copies of the 8-bit image.
That's less convenient but it is still no reason to go voxel-by-voxel. You can break the image into smaller (overlapping) sub-chunks and apply my proposal to each of the sub-images.
My image is 16 GB in 8-bit format
What are the dimensions of this image?
The version of the image I am using for this step must be 32-bit
That's not possible. If the original data is 8 bit, there is no way the neighborhood modes require more than 8 bits to represent.
Matt - I'd bet a decent sum of money the problem is mainly pre-allocation, or the lack thereof.
John - even if a missing pre-allocation step is remedied, looping element by element through a 16GB image will still make things impractically slow.
Eric Chadwick
on 7 Apr 2020
Matt J
on 7 Apr 2020
The 32-bit image has replaced the formerly binary values of the image with numbers ranging from -1 to greater than 255.
Is there any sparsity that you can take advantage of? Does the image contain mostly zeros?
Eric Chadwick
on 7 Apr 2020
Categories
Find more on Image Processing Toolbox in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!