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);

 채택된 답변

Geoff Hayes
Geoff Hayes 2017년 2월 15일

1 개 추천

Zoubeir - I'm noticing the same with your code for a 3744x5616 RGB image. It seems though that the bottleneck is with the "second" part of the code where you update the blue matrix. Since you haven't defined a size for it, it is constantly being resized on all subsequent iterations of your for loops. I suggest that you pre-size this matrix as
blue = zeros(x,y,3,'uint8');
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
There may be some other optimizations to your first set of for loops but I would start with the pre-sizing of blue. (Note that with this modification, it took about five seconds to execute your code. With the previous version, I killed the processing after a couple of minutes.)

댓글 수: 1

Zoubeir Afifi
Zoubeir Afifi 2017년 2월 16일
Thank you very much, Geoff. Can you tell me the other optimizations that I could do to my first set of for loops? Thank you again. Best Regards.

댓글을 달려면 로그인하십시오.

추가 답변 (3개)

Steven Lord
Steven Lord 2017년 2월 16일

2 개 추천

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

Jan
Jan 2017년 2월 16일
편집: Jan 2017년 2월 20일
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

댓글을 달려면 로그인하십시오.

Jan
Jan 2017년 2월 16일
편집: Jan 2017년 2월 16일

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
Jan 2017년 2월 16일

1 개 추천

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

Zoubeir Afifi
Zoubeir Afifi 2017년 2월 16일
Thank you very much, Simon. With this code, I could save 4 sec.
Jan
Jan 2017년 2월 16일
The runtime was 7 minutes and now it is 6:54? Oh, I hoped it is ways faster.
Zoubeir Afifi
Zoubeir Afifi 2017년 2월 16일
편집: Zoubeir Afifi 2017년 2월 16일
No, I meant with the pre-sizing of Geoff was the runtime 7 sec. Now, it is only 3 sec
Zoubeir Afifi
Zoubeir Afifi 2017년 2월 16일
Vielen Dank, es ist erledigt.

댓글을 달려면 로그인하십시오.

카테고리

질문:

2017년 2월 15일

편집:

Jan
2017년 2월 20일

Community Treasure Hunt

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

Start Hunting!

Translated by