I am wondering if anyone can help me. I have developed some code which alters the amount of redness/greenness in photographs of faces, by adding or subtracting values of 'A' using the CIE LAB colour space. I now want to develop the code further, so that I can leave the eyes and lips unchanged, and just change the amount of redness/greeness in the skin of the face. Here is the code which allows me to alter the amount of redness/greeness in the image:
%load original photograph of face
rgbimage = imread('Original.jpg');
%Convert image from RGB to l*a*b
cform = makecform('srgb2lab');
labimage = applycform (rgbimage, cform);
%Convert lab image from unit8 to double labdoubleimage = lab2double(labimage);
%ascertain original values of channels l, a and b/divide lab image into l, %a and b channels l_channel = labdoubleimage(:,:,1); a_channel = labdoubleimage(:,:,2); b_channel = labdoubleimage(:,:,3);
% tell matlab what you want the new value of channel a (redness) to be. A %minus value makes image greener, a plus value makes image redder a_channelnew = a_channel-14;
%tell matlab that the new lab image is made up of the two unaltered ‘l’and ‘b’ % channels, plus the altered ‘a’ (redness) channel labimagenew = cat(3, l_channel, a_channelnew, b_channel);
%determine original values of 'l', ‘a’ and 'b' and check that new values of a are correct OriginalLightnessmean = mean(mean(l_channel)); OriginalLightnessmean Originalredmean = mean(mean(a_channel)); Originalredmean Originalbluemean = mean(mean(b_channel)); Originalbluemean Newredmean = mean(mean(a_channelnew)); Newredmean
%convert the image back into RGB format, then from double to uint 8
cform2 = makecform('lab2srgb');
rgbnewone = applycform(labimagenew, cform2);
one = im2uint8(rgbnewone);
At first I tried making a binary mask, then using roifilt2 to attempt to change the colour only in the black parts of the binary mask, however, roifilt2 only allows you to process 2D matrices. Does anyone know how I could adapt the above code to leave out certain parts of the image when I add or subtract values from the ‘A’ channel? Any pointers would be much appreciated.
Thank you!
No products are associated with this question.
There are many ways to do this type of thing and I am not completely clear so I will just give a small example:
%Sample image and rectangular mask
I = imread('peppers.png');
M = false(size(I));
M(50:100,50:200,:) = true;
%Do some operation to change the color: here we are going to add 10 to the red channel, 40 to the green and -20 to the blue. I2 = bsxfun(@plus,double(I),reshape([10,40,-20],1,1,3)); I(M) = uint8(I2(M)); %extract only the relevant parts
%Display imshow(I)
This can obviously be built up and there is often no reason to perform the operation on the whole image. If you can provide code and images for us to run then we can likely be of more assistance.
Hello,
Thanks for getting back to me. The code I have been using to change the colour in my images is as above (working in the CIE lab colour space).
I have tried adapting the code you gave me above by making an ellipse, then a binary mask, to define the eye area in my images (which I want to leave out of my colour transform):
%load original photograph of face
rgbimage = imread('Original.jpg');
%display image and create a circular shaped binary mask h_im = imshow(rgbimage); e = imellipse(gca, []); binarymask = createMask(e, h_im);
%Convert image from RGB to l*a*b
cform = makecform('srgb2lab');
labimage = applycform (rgbimage, cform);
%Convert lab image from unit8 to double labdoubleimage = lab2double(labimage);
%tell matlab what parts of labdoubleimage are ‘false’ or ‘true’ based on binary mask m = false(size(labdoubleimage)); m(binarymask) = true.
It is then possible to change the colour of the masked area by using a code similar to yours:
%Do some operation to change the color: here we are going to add 10 to the red channel, 40 to the green and -20 to the blue. I2 = bsxfun(@plus,labdoubleimage,reshape([10,40,-20],1,1,3)); labdoubleimage(m) = uint8(I2(m)); %extract only the relevant parts %Display imshow(labdoubleimage);
%convert the image back into RGB format:
cform2 = makecform('lab2srgb');
rgbnewone = applycform(labdoubleimage, cform2);
imshow(rgbnewone);
However, firstly, I am not sure this code is acting on the l, a and b channels. It does not seem to be possible to change only redness (A) values, e.g., by changing the numbers for the colour change to:
I2 = bsxfun(@plus,labdoubleimage,reshape([0,100,0],1,1,3));
I thought that this would add 0 to the L and B channels, and 100 to the A channel, but it did not change colour anywhere in the image. Do you know whether the code you did would be specific to RGB images?
Secondly, I want to change the colour outside of the mask, leaving the inside of the mask the original colour.
Can I ask you what the values 1, 1, 3 are referring to in the following bit if code:
I2 = bsxfun(@plus,labdoubleimage,reshape([10,40,-20],1,1,3));
Thanks again for your help I really appreciate it, I wasn't sure how to attach an example image!
Laura
0 Comments