Overcome for loops for fast processing

I have the following part of MATLAB code
skin_rgb = zeros(256.^3,1);
for i = [2000 : 2003,2008,2010:2011,2013:2015,2017:2018,2021,2024,2027:2041,2043,2045:2059,2061:2063]
I = imread(['skin_img',num2str(i),'.tif']);
[x,y,~]= size(I);
for l = 1:x
for j = 1:y
if (I(l,j,1) ~= 255 && I(l,j,2) ~= 255 && I(l,j,3) ~= 255)
aa = double([I(l,j,1) , I(l,j,2) , I(l,j,3)]);
[~,ee1] = ismember(aa,rgb_hist,'rows');
skin_rgb(ee1) = skin_rgb(ee1) + 1;
b1 = b1 + 1;
end
end
end
end
The output of the code is perfect. The issue is it is very slow. Inside the if loop the size of rgb_hist variable is 255.^3 x 3. Is there any way to get rid of the two nested for loops? As I am doing Image processing on high resolution image the variable x and y (different for each "i" iteration) have a big number in it.
Thank you

2 个评论

Is every possible combination in rgbhist?
Yes, every possible combination is in rgb_hist.

请先登录,再进行评论。

 采纳的回答

skin_rgb = 0;
for i = [2000 : 2003,2008,2010:2011,2013:2015,2017:2018,2021,2024,2027:2041,2043,2045:2059,2061:2063]
I = imread(['skin_img',num2str(i),'.tif']);
RGB = reshape(double(I),[],3)+1;
skin_rgb = skin_rgb + accumarray(RGB,1,256+[0 0 0]);
end
skin_rgb = permute(skin_rgb,[3 2 1]);
skin_rgb = skin_rgb(:);

更多回答(1 个)

skin_rgb = zeros(256.^3,1);
for i = [2000 : 2003, 2008, 2010:2011, 2013:2015, 2017:2018, 2021, 2024, 2027:2041, 2043, 2045:2059, 2061:2063]
I = imread(['skin_img',num2str(i),'.tif']);
r = 1 + double(I(:,:,1)); g = 1 + double(I(:,:,2)); b = 1 + double(I(:,:,3));
skin_rgb = skin_rgb + accumarray([r(:), g(:), b(:)], 1, [256.^3, 1]);
end

15 个评论

Thank you for the kind response, but MATLAB giving an error that "
Error using accumarray
Third input SZ must be a full row vector with one element for each column of SUBS.
Error in hist_RGB (line 33)
skin_rgb = skin_rgb + accumarray([r(:), g(:), b(:)], 1, [256.^3, 1]);
Waiting for your kind response.
skin_rgb = skin_rgb + accumarray([r(:), g(:), b(:)], 1, [256, 256, 256]);
And after the loop
skin_rgb = skin_rgb(:) ;
You'll notice my answer correct these two errors
I have tested it many times but found that
skin_rgb = skin_rgb(:) ;
is not working fine. Do I need to reshape after skin_rgb after 3 columns?
256^3 = 16777216 is obviously not divisible by 3. So on earth you want to reshape in 3 columns???
Sorry for that, but skin_rgb = skin_rgb(:) is not arranged in order as asked in the question. I just wanted to solve that issue.
The order depends on entirely on the content of rgb_hist that you never specify what's in and in which order. Question never correctly formulated.
I accept my mistake of asking question. rgb_hist has the following order
rgb_hist = [1 1 1 ; 1 1 2 ; .... ; 1 1 256; 1 2 1 ; 1 2 2; ,.... ;1 256 256 ; ..... ; 256 256 256];
Its a 256.^3 x 3 matrix. Starting from 1,1,1 to 256,256,256.
Usually RGB values are in [0:255] range not [1:256]. Assuming the above rgb_hist is to be substracted by 1, on this case just change
skin_rgb = skin_rgb(:);
to
skin_rgb = permute(skin_rgb,[3 2 1]);
skin_rgb = skin_rgb(:);
I apologize for this, in the following code now i am working with only one image "i = 2000" . As you can see that aa is selected from image I so it must have occur once. "a2" variable has location of "aa" in "rgb_hist" array. This implies that skin_rgb(a2) should atleast be equal to 1. But it is not. Which in my understanding is due to the order of skin_rgb.
>> aa = 1 + [I(500,500,1),I(500,500,2),I(500,500,3)];
>> [a1,a2] = ismember(aa,rgb_hist,'rows');
>> skin_rgb(a2)
ans =
0
For easiness I am providing the rgb_hist variable order again
rgb_hist = [1 1 1 ; 1 1 2 ; .... ; 1 1 256; 1 2 1 ; 1 2 2; ,.... ;1 256 256 ; 2 1 1;..... ; 256 256 256];
Thank you.
Original RGB value starts from 0 ends at 255. This is the reason we add 1 before doing accumarray.
So skin_rgb(10,20,30) actually stores the number of image pixels that have the RGB = [09,19,29]
Yes, I understad that, but in the folowing code I have already added 1 in variable "aa".
>> aa = 1 + [I(500,500,1),I(500,500,2),I(500,500,3)];
>> [a1,a2] = ismember(aa,rgb_hist,'rows');
>> skin_rgb(a2)
ans =
0
Then your rgb_hist is wrong.
This test code returns 1 everytime
% Such simple generate thing that you never bother to post
[B,G,R] = ndgrid(1:256);
rgb_hist = [R(:),G(:),B(:)];
% Quick check for order
rgb_hist(1:10,:)
rgb_hist(end+(-9:0),:)
% Random data
I = floor(256*rand(100,100,3));
aa = 1 + [I(100,100,1),I(100,100,2),I(100,100,3)]
% Counting algo
skin_rgb = accumarray(aa,1,256+[0 0 0]);
skin_rgb = permute(skin_rgb,[3 2 1]);
skin_rgb = skin_rgb(:);
% Check
[a1,a2] = ismember(aa,rgb_hist,'rows');
skin_rgb(a2) % <- This returns correctly 1

请先登录,再进行评论。

类别

帮助中心File Exchange 中查找有关 Programming 的更多信息

标签

Community Treasure Hunt

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

Start Hunting!

Translated by