Reputation: 54
I have a matrix named IMG, it is a n * m * 3 shaped matrix (an hsv image). What I am trying to achieve is
IF IMG(x, y, 1) < 1/2
THEN IMG(X, Y, 2) = 0.
Logical indexing looks like a solution but with that way we can only access the condition index (IMG(x, y, 1)). With the code below I am changing first indices of the pixels but I want to change second one.
IMG( IMG(:, :, 1) > 1/2 ) = 0;
Thanks for your help.
Upvotes: 3
Views: 269
Reputation: 1630
looking for another one-line solution without any intermediate holding variable, the following was proposed for a multi-dimensional array on the Octave Help list:
a( (a(:,:,3)<.5) & shiftdim(1:size(a,3)==2,-1) ) = 0
for example:
>> a = rand(2,3,3)
a =
ans(:,:,1) =
0.63416 0.28912 0.33463
0.76642 0.51474 0.28130
ans(:,:,2) =
0.99748 0.26000 0.45671
0.73153 0.44499 0.24099
ans(:,:,3) =
0.94726 0.77252 0.12698
0.27069 0.46458 0.55833
>> a( (a(:,:,3)<.5) & shiftdim(1:size(a,3)==2,-1) ) = 0
a =
ans(:,:,1) =
0.63416 0.28912 0.33463
0.76642 0.51474 0.28130
ans(:,:,2) =
0.99748 0.26000 0.00000
0.00000 0.00000 0.24099
ans(:,:,3) =
0.94726 0.77252 0.12698
0.27069 0.46458 0.55833
Upvotes: 0
Reputation: 60695
One simple solution is to extract the whole plane, modify it, then put it back:
s = IMG(:, :, 2);
s(IMG(:, :, 1) > 1/2) = 0;
IMG(:, :, 2) = s;
It is also possible to play around with linear indices, which is more generic, but also more complex:
index = find(IMG(:, :, 1) > 1/2);
offset = size(IMG, 1) * size(IMG, 2);
IMG(index + offset) = 0;
Upvotes: 4
Reputation: 15867
You can multiply the image by a mask:
IMG(:, :, 2) = IMG(:, :, 2) .* (IMG(:, :, 1) <= (1/2)) ;
Or use compound assignment:
IMG(:, :, 2) .*= IMG(:, :, 1) <= (1/2);
Another fast option is reshaping the array:
sz =size(IMG) ;
IMG = reshape(IMG, [], 3);
IMG(IMG(:,1)>1/2, 1), 2) = 0;
IMG = reshape(IMG, sz) ;
Other, possibly less efficient, option is using ifelse :
IMG(:, :, 2) = ifelse(IMG(:, :, 1) > 1/2, 0, IMG(:, :, 2) ) ;
Upvotes: 3