how to speed up basic image processing tasks
9 views (last 30 days)
Show older comments
Hi,
I'm trynig to explore the most basic image processing tasks and ideas with matlab. For that porpuse, I took a random image with the dimentions of 1200*900 pixels, loaded it to my matlab and got three matrixes in the same resolution, one for red, green and blue values in a pixel.
I tried to create a 1200*900 matrix that marks every dark-green pixel that was in the original image.
I made it with two 'for' loops.
I know that my code is far from perfect, but its not the important thing.
The problem is that the two 'for' loops taking few hours to complete, and I'm really surprised because 1200*900 its not that big size for an image and there's probably something really basic that I'm doing wrong. How can I preform those basic tasks faster?
picture = imread('1board.png')
darkcells (1200,900,3) = zeros
for i = 1:900
for j = 1:1200
if (( picture(i,j,1) < 40 ) && picture (i,j,1) > 19 ) == 1
darkcells (i,j,1) = 1
end
if (( picture(i,j,2) < 90 ) && picture (i,j,1) > 70 ) == 1
darkcells (i,j,2) = 1
end
if (( picture(i,j,3) < 75 ) && picture (i,j,1) > 55 ) == 1
darkcells (i,j,3) = 1
%and some additional code here.
end
end
0 Comments
Accepted Answer
Rik
on 10 Dec 2020
Most basic tasks can be vectorized. But for your code there is something that makes an even larger difference: you don't have a single semicolon in your code. Printing the entire array of 3 million elements every time you assign a value to one of the elements takes a huge amount of time.
As for the vectorization:
picture = imread('1board.png');
darkcells = zeros(1200,900,3);
L = picture(:,:,1) < 40 & picture (:,:,1) > 19 ;
darkcells (:,:,1) = L;
L = picture(:,:,2) < 90 & picture (:,:,2) > 70 ;
% ^ changed to 2, was 1 indeed a typo?
darkcells (:,:,2) = L;
L = picture(:,:,3) < 75 & picture (:,:,1) > 55 ;
darkcells (:,:,3) = L;
There were several other issues with your code, not least among them the way you created the darkcells array.
Have you done a basic Matlab tutorial?
3 Comments
Rik
on 15 Dec 2020
The code will run the same (at the same speed even), but Matlab will spend a lot of time updating the command window content.
Compare the second line of my code with the second line of your code. Do you see the difference?
I would suggest the Onramp tutorial (which is provided for free by Mathworks). It will teach you the basics, and might help you solve future problems on your own as well.
Image Analyst
on 15 Dec 2020
The third one
L = picture(:,:,3) < 75 & picture (:,:,1) > 55 ;
was also suspect (typo?) so I changed the (:,:,1) to (:,:,3) in my answer.
blueMask = rgbImage(:,:,3) < 75 & rgbImage(:,:,3) > 55;
You might also like to know about imsplit()
[r, g, b] = imsplit(rgbImage);
Though it will use up twice the memory as if you used picture (:,:,1), but memory is plentiful -- usually you have way more than enough.
More Answers (1)
Image Analyst
on 10 Dec 2020
Try this:
rgbImage = imread('1board.png');
% Get masks for every color channel.
redMask = rgbImage(:,:,1) < 40 & rgbImage(:,:,1) > 19;
greenMask = rgbImage(:,:,2) < 90 & rgbImage(:,:,2) > 70;
blueMask = rgbImage(:,:,3) < 75 & rgbImage(:,:,3) > 55;
% Get the overall mask where all three are true.
darkcells = redMask & greenMask & blueMask;
% Display everything
subplot(1, 2, 1);
imshow(rgbImage);
subplot(1, 2, 2);
imshow(darkcells);
Or better yet, use the Color Thresholder app on the apps tab of the tool ribbon.
See Also
Categories
Find more on Debugging and Analysis 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!