-1

I have created a logical array of a double image based on wheter the pixel is green (image_mark_green = img2(:,:,2) >= 0.5;) is there a way for me to use this and repmat in order to turn all pixels in the image fullfilling the green requirment to black

rayryeng
  • 102,964
  • 22
  • 184
  • 193

2 Answers2

1

You can do it with repmat but you should rather do it with bsxfun. The idea for both is the same, just multiply the value of each pixel but the logical not of its corresponding pixel in the mask. This will either leave the value unchanged or make it zero:

img3 = bsxfun(@times, ~image_mark_green, img2)
Dan
  • 45,079
  • 17
  • 88
  • 157
  • Thank you for your answer, but I wanted to know how to do it specifically with repmat – Nikita Kholodnyi Apr 14 '16 at 13:07
  • @NikitaKholodnyi `img3 = img2.*repmat(~image_mark_green,1,1,3)` but this is the wrong way to do it. Use `bsxfun`, it's an essential function to understand if you're using MATLAB: http://blogs.mathworks.com/loren/2008/08/04/comparing-repmat-and-bsxfun-performance/ – Dan Apr 14 '16 at 13:08
  • Thank you for the answer. I get that bsxfun is the correct way, but when my proffesor says i have to use repmat than im using repmat – Nikita Kholodnyi Apr 14 '16 at 13:09
  • 1
    @NikitaKholodnyi or you could (should) talk to your professor about the glory of `bsxfun`... – Dan Apr 14 '16 at 14:08
  • 2
    @NikitaKholodnyi and email your professor some benchmark results on [runtime comparisons between `bsxfun` and `repmat`](http://stackoverflow.com/questions/29719674/comparing-bsxfun-and-repmat) :) – Divakar Apr 14 '16 at 15:05
1

For the sake of completeness, to do it with repmat simply duplicate img_mask_green in the third dimension, then do an element-wise multiplication:

img3 = img2 .* repmat(cast(~image_mark_green, class(img2)), [1 1 size(img2,3)]);

The cast call is required because img2 will most likely be an unsigned integer type while image_mark_green will be logical. The casting is performed to ensure that image_mark_green is the same type as img2 as this is required before performing element-wise multiplications in this particular scenario.

However, bsxfun is much more elegant and you don't have to know how many elements to replicate in each dimension for the element-wise operations to work.


You can also avoid repmat if you wish and you can split up the channels individually, use that single 2D mask to index into each channel and set the elements that are green to black, then merge everything together. This method requires the memory to temporarily store each channel in separate variables though:

r = img2(:,:,1);
g = img2(:,:,2);
b = img2(:,:,3);
r(image_mask_green) = 0;
g(image_mask_green) = 0;
b(image_mask_green) = 0;
img3 = cat(3, r, g, b);

cat concatenates matrices of compatible sizes in the desired dimension. In this case, we are concatenating the red, green and blue channels in the third dimension to create an RGB image for display and writing to file.

rayryeng
  • 102,964
  • 22
  • 184
  • 193