Help Vectorizing For-Loop with Complex Statements

% size of image
imageSize = 564;
% generate the color range used in the colormap
colormap_used_in_image = jet(256^3); % for perfect results use 256^3, 256^2 is good estimator
colormap_used_in_image = colormap_used_in_image * 255; % convert to actual RGB values
% example image where some of the data is in the jet colormap, some isn't
data = randi(255,564,564,3);
% convert data to doubles for math
data = double(data);
% empty array to be filled with our jet mapped data
jetmappedData = nan(imageSize,imageSize);
% this loop calculates which value from the colormap best fits the
% image
wb = waitbar(0,append('Colormapping Values for Image # ',string(1)));
for r = 1:imageSize % for each row in the image
for c = 1:imageSize % for each column in the image
diff1 = abs(data(r,c,1) - colormap_used_in_image(:,1)); % difference in R value
diff2 = abs(data(r,c,2) - colormap_used_in_image(:,2)); % difference in G value
diff3 = abs(data(r,c,3) - colormap_used_in_image(:,3)); % difference in B value
diffTotal = diff1 + diff2 + diff3; % difference in all the values
[val,loc] = min(diffTotal);
if val <= 3 % if the value isn't found in jet
jetmappedData(r,c) = loc;
else
jetmappedData(r,c) = NaN;
end
end
waitbar(r/imageSize,wb,append('Colormapping Values for Image # ',string(1)));
end
I have a lossless image (564x564) generated from MATLAB with a jet-colorbar from a range of [0,1]. The original data is lost and I'm trying to recover it from the image. Here I am converting RGB values to their original datapoints. Over sixteen trillion operations need to be performed per photo... far too many. How can I vectorize this for loop to increase efficiency? (I also have a 3070ti GPU if it would help to utilize).
Thanks!

2 Comments

Your code cannot be run. Input data has not been attached.
Updated with sample data - good call :)

Sign in to comment.

 Accepted Answer

Eliminating one of the loops should help.
cmap=reshape(colormap_used_in_image',1,3,[]);
for c = 1:imageSize % for each row in the image
D= reshape(data(:,c,:),[],3);
idx=circlePixels(:,c);
D=sum( abs(D(idx,:)-cmap),2);
[val,loc]=min(D,[],3);
loc(val<120)=nan;
jetmappedData(idx,c)=loc(:);
end

5 Comments

Requested 564x3x16777216 (211.5GB) array exceeds maximum array size preference (56.9GB). This might cause MATLAB to become unresponsive.
Error in Image2DataTemp (line 31)
D=sum(abs(D(idx,:)-cmap),2);
Any ideas?
I broke down your loop futher into even smaller parts (so it could fit into memory), but the runtime is still over 20 hours for a single 564x564 image. Any further optimization I could try?
Matt J
Matt J on 24 Apr 2022
Edited: Matt J on 24 Apr 2022
In your code comments, you remark that jet(256^2) might be good enough I would suggest that. Also, convert data to single floats instead of double.
Also, converting the data to gpuArrays (if you have the Parallel Comp. Toolbox) should indeed accelerate things.
I'll look into those - thanks!
You're welcome, but if they work, please Accept-click the answer.

Sign in to comment.

More Answers (0)

Products

Asked:

on 24 Apr 2022

Commented:

on 24 Apr 2022

Community Treasure Hunt

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

Start Hunting!