Nested For Loop! Long running Time
Mostrar comentarios más antiguos
Hello Everybody, I have written a code to process Images. Images will be processed using nested for loop to change Pixel by pixel so that the running time for one Picture with 12MB is 7 min. Is there another possibility to do the same but within 2 or 3 sec? Thank you very much for your Help. This is my Code:
rgb = imread('Image.jpg');
figure;
imshow(rgb);
R=rgb(:,:,1); %red
G=rgb(:,:,2); %green
B=rgb(:,:,3); %blue
[x,y,z]=size(rgb);
for i=1:x
for j=1:y
if((R(i,j) < 0))
R(i,j) = 0;
G(i,j) = 0;
B(i,j) = 0;
elseif ( (R(i,j) >= 0) && (R(i,j) <=26) )
R(i,j) = 0;
G(i,j) = 97;
B(i,j) = 254;
elseif ( (R(i,j) > 26) && (R(i,j) <=51) )
R(i,j) = 0;
G(i,j) = 197;
B(i,j) = 254;
elseif ( (R(i,j) > 51) && (R(i,j) <=77) )
R(i,j) = 0;
G(i,j) = 250;
B(i,j) = 204;
elseif ( (R(i,j) > 77) && (R(i,j) <=102) )
R(i,j) = 0;
G(i,j) = 250;
B(i,j) = 104;
elseif ( (R(i,j) > 102) && (R(i,j) <=128) )
R(i,j) = 0;
G(i,j) = 250;
B(i,j) = 4;
elseif ( (R(i,j) > 128) && (R(i,j) <=153) )
R(i,j) = 96;
G(i,j) = 250;
B(i,j) = 0;
elseif ( (R(i,j) > 153) && (R(i,j) <=179) )
R(i,j) = 196;
G(i,j) = 250;
B(i,j) = 0;
elseif ( (R(i,j) > 179) && (R(i,j) <=204) )
R(i,j) = 254;
G(i,j) = 205;
B(i,j) = 0;
elseif ( (R(i,j) > 204) && (R(i,j) <=230) )
R(i,j) = 254;
G(i,j) = 105;
B(i,j) = 0;
elseif ( (R(i,j) > 230) && (R(i,j) <=255) )
R(i,j) = 254;
G(i,j) = 5;
B(i,j) = 0;
elseif ( (R(i,j) >= 255))
R(i,j) = 255;
G(i,j) = 255;
B(i,j) = 255;
end
end
end
for i=1:x
for j=1:y
blue(i,j,1) = R(i,j);
blue(i,j,2) = G(i,j);
blue(i,j,3) = B(i,j);
end
end
figure;
imshow(blue);
Respuesta aceptada
Más respuestas (3)
Steven Lord
el 16 de Feb. de 2017
Use discretize to discretize the red plane of your image, identifying the bin to which each element should belong. Use those bin numbers to index into the array of colors. For illustration purposes, I'll use a smaller matrix.
tic
% Generate sample data
sizeOfR = [10 10 3];
R = randi(intmax('uint8'), sizeOfR, 'uint8');
% Set up a bin & color matrix
binAndColors = uint8(...
[ 0 0 97 254;
26 0 197 254;
51 0 250 204;
77 0 250 104;
102 0 250 4;
128 96 250 0;
153 196 250 0;
179 254 205 0;
204 254 105 0;
230 254 5 0]);
% Bin the elements of the red plane of R
D = discretize(R(:, :, 1), [binAndColors(:, 1); 255], 'includedEdge', 'right');
% These are the colors associated with each bin
colors = binAndColors(:, 2:4);
% Use the bin numbers to index into the appropriate column of the colors array
red = reshape(colors(D, 1), sizeOfR(1:2));
green = reshape(colors(D, 2), sizeOfR(1:2));
blue = reshape(colors(D, 3), sizeOfR(1:2));
% Stack the three planes together
R2 = cat(3, red, green, blue);
toc
% To check, display the original array R and the new array R2 side-by-side
% I added a layer of three 1's between the two arrays to make it easier
% to distinguish the boundaries. I would have used NaN, but NaN is converted
% to 0 in a uint8 array.
cat(2, R, repmat(1, sizeOfR(1), 3, sizeOfR(3)), R2)
On my Windows machine with release R2016b, running all these commands ( except the last one, which would print a very large array in the Command Window ) for an R array of size [3744 5616 3] took less than 2 seconds. Note that the binAndColors array doesn't contain entries for the <0 or >255 cases; if your data is uint8 as I think most of us have assumed, those cases cannot occur because of the range of values that can be stored in a uint8 array.
rangeOfUint8DataType = [intmin('uint8') intmax('uint8')]
1 comentario
Compare this, especially the creation of the binAndColors table, with my two solutions: While typing my suggestions has been tedious and in consequence prone to typos, this is compact and neat. I even gave up writing the 2nd suggestions in between.
This is an excellent example for the efficient use of Matlab for writing clean code. +1
For the first part: Instead of looping you can use "linear indexing": This can replace each ELSEIF branch:
R = rgb(:,:,1); %red
G = rgb(:,:,2); %green
B = rgb(:,:,3); %blue
RR = R; % Do not overwrite original values
index = (RR < 0)); % Is this possible at all???
R(index) = 0;
G(index) = 0;
B(index) = 0;
index = (RR >= 0) & (RR <= 26);
R(index) = 0;
G(index) = 97;
B(index) = 254;
index = (RR > 26) & (RR <=51);
R(index) = 0;
G(index) = 197;
B(index) = 254;
index = (RR > 51) & (RR <= 77);
R(index) = 0;
G(index) = 250;
B(index) = 204;
index = (RR > 77) & (RR <= 102);
R(index) = 0;
G(index) = 250;
B(index) = 104;
index = (RR > 102) & (RR <= 128);
R(index) = 0;
G(index) = 250;
B(index) = 4;
index = (RR > 128) & (RR <= 153);
R(index) = 96;
G(index) = 250;
B(index) = 0;
index = (RR > 153) & (RR <= 179);
R(index) = 196;
G(index) = 250;
B(index) = 0;
index = (RR > 179) & (RR <= 204);
R(index) = 254;
G(index) = 205;
B(index) = 0;
index = (RR > 204) & (RR <= 230);
R(index) = 254;
G(index) = 105;
B(index) = 0;
index = (RR > 230) & (R <= 255);
R(index) = 254;
G(index) = 5;
B(index) = 0;
index = (RR >= 255);
R(index) = 255;
G(index) = 255;
B(index) = 255;
Note that you could reuse e.g. (RR <= 204) to obtain (RR > 204) by a simple not() command. But this would make the code less clear, so I've omitted this.
Geoff's pre-allocation "zeros()" helps already. But you can try this also instead of the loop:
blue = cat(3, uint8(R), uint8(G), uint8(B));
Jan
el 16 de Feb. de 2017
And another apporach
R = rgb(:,:,1); %red
G = rgb(:,:,2); %green
B = rgb(:,:,3); %blue
G(R <= 0) = 0;
G(R > 0 & R < 26) = 97;
G(R > 26 & R <= 51) = 197;
G(R > 51 & R <= 204) = 250;
G(R > 204 & R <= 230) = 105;
G(R > 230) = 5;
B(R <= 0) = 0;
B(R > 0 & R <= 51) = 254;
B(R > 51 & R <= 77) = 204;
etc.
RR = R; % Do not overwrite the original data
...
This is even shorter than my other suggestion, but still tedious to type. So I leave this up to you.
4 comentarios
Zoubeir Afifi
el 16 de Feb. de 2017
Jan
el 16 de Feb. de 2017
The runtime was 7 minutes and now it is 6:54? Oh, I hoped it is ways faster.
Zoubeir Afifi
el 16 de Feb. de 2017
Editada: Zoubeir Afifi
el 16 de Feb. de 2017
Zoubeir Afifi
el 16 de Feb. de 2017
Categorías
Más información sobre Solver Outputs and Iterative Display en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!