jsalvador
jsalvador

Reputation: 733

RGB to norm rgb transformation. Vectorizing

I'm writing a piece of code that has to transform from an RGB image to an rgb normalized space. I've got it working with a for format but it runs too slow and I need to evaluate lots of images. I'm trying to vectorize the full function in order to faster it. What I have for the moment is the following:

     R = im(:,:,1);
     G = im(:,:,2);
     B = im(:,:,3);

     r=reshape(R,[],1);
     g=reshape(G,[],1);
     b=reshape(B,[],1);

     clear R G B;

     VNormalizedRed = r(:)/(r(:)+g(:)+b(:));
     VNormalizedGreen = g(:)/(r(:)+g(:)+b(:));
     VNormalizedBlue = b(:)/(r(:)+g(:)+b(:));

     NormalizedRed = reshape(VNormalizedRed,height,width);
     NormalizedGreen = reshape(VNormalizedGreen,height,width);
     NormalizedBlue = reshape(VNormalizedBlue,height,width);

The main problem is that when it arrives at VNormalizedRed = r(:)/(r(:)+g(:)+b(:)); it displays an out of memory error (wich is really strange because i just have freed three vectors of the same size). Were is the error? (solved)

Its possible to do the same process in a more efficiently way?

Edit:

After using Martin sugestions I found the reshape function was not necessary, being able to do the same with a simple code:

     R = im(:,:,1);
     G = im(:,:,2);
     B = im(:,:,3);

     NormalizedRed = R(:,:)./sqrt(R(:,:).^2+G(:,:).^2+B(:,:).^2);
     NormalizedGreen = G(:,:)./sqrt(R(:,:).^2+G(:,:).^2+B(:,:).^2);
     NormalizedBlue = B(:,:)./sqrt(R(:,:).^2+G(:,:).^2+B(:,:).^2);

     norm(:,:,1) = NormalizedRed(:,:);
     norm(:,:,2) = NormalizedGreen(:,:);
     norm(:,:,3) = NormalizedBlue(:,:);

Upvotes: 3

Views: 3957

Answers (2)

Amro
Amro

Reputation: 124543

Your entire first code can be rewritten in one vectorized line:

im_normalized = bsxfun(@rdivide, im, sum(im,3,'native'));

Your second slightly modified version as:

im_normalized = bsxfun(@rdivide, im, sqrt(sum(im.^2,3,'native')));

BTW, you should be aware of the data type used for the image, otherwise one can get unexpected results (due to integer division for example). Therefore I would convert the image to double before performing the normalization calculations:

im = im2double(im);

Upvotes: 1

Martin B
Martin B

Reputation: 24130

I believe you want

VNormalizedRed = r(:)./(r(:)+g(:)+b(:));

Note the dot in front of the /, which specifies an element-by-element divide. Without the dot, you're solving a system of equations -- which is likely not what you want to do. This probably also explains why you're seeing the high memory consumption.

Upvotes: 5

Related Questions