Time for action – writing a function for red eye reduction

In this example, we will use a photograph of me, to try and reduce the red eye effect. In order to be able to use this tool in other photographs as well, we should make it as generic as possible.

  1. First, we should write the following function in our editor (we'll call it RedEyeReduction.m):
    function output = RedEyeReduction(input, thresh) 
    
    % Function for red eye reduction in input image 
    % Inputs:
    % input  - Input image
    % thresh – Threshold value in channel a*
    % Output:   
    % output - Output image (after red-eye reduction)
    
    cform = makecform('srgb2lab'), % Make the transform structureimg_lab = applycform(input,cform); % Apply transform to L*a*b*
    
    eyes = roipoly(input);	% Select area of eyes
    mask = (img_lab(:,:,2) > thresh) & (eyes > 0); % Red pixels in eyes
    
    % Split the three color channels
    R=input(:,:,1);
    G=input(:,:,2);
    B=input(:,:,3);
    
    R(mask) = round((G(mask)+B(mask))/2); % Replace R value with (G+B)/2
    
    output = cat(3,R,G,B); % Join color channels to form output image
  2. Let's now test our function to see if it actually works on my picture. We will choose an area containing the eyes and use a fairly high threshold value for a* (that is, 150):
    >> img = imread('my_red_eyes.bmp'),
    >> output = RedEyeReduction(img, 150);
    Time for action – writing a function for red eye reduction
  3. Then, it is time to see what our function has done to the image:
    >> subplot(1,2,1),imshow(img),title('Original image')
    >> subplot(1,2,2),imshow(output),title('Image after red-eye correction')
    Time for action – writing a function for red eye reduction
  4. The result of our red eye reduction function proved to be a huge success! Or didn't it? The truth is that, we actually haven't thoroughly tested our function. Let's change our threshold and see what happens. We'll try with a lower and a higher threshold:
    >> output = RedEyeReduction(img, 170); % Picking a very high threshold
    >> output2 = RedEyeReduction(img, 120); % Picking a very low threshold
    >> figure,subplot(1,2,1),imshow(output),title('Very high threshold')
    >> subplot(1,2,2),imshow(output2),title('Very low threshold')
    Time for action – writing a function for red eye reduction
  5. The results of the previous steps reveal that our function relies very heavily on color; hence, we should very carefully choose our threshold. Now let's see what happens if we select a larger area (the results that follows show the selection and result):
    >> output3 = RedEyeReduction(img, 150); % Picking a very large area
    Time for action – writing a function for red eye reduction

What just happened?

When choosing the right threshold, the results achieved in this example are very satisfying, given that we have only written less than 10 lines of functional code. The process described above was followed, that is, transforming the image to CIE-L*a*b*, choosing the area containing the eyes, combining it with our threshold to generate a mask, and then using the mask to replace R values with the average values of G and B. You should note that in order to get the average, we performed addition of the two channels, followed by division by two. This could lead to a non-integer result, so we converted it to integer using the function round, which rounds the result to the nearest integer value. In the last two steps, we revealed the ugly truth; our function relies too much on a proper selection of the color threshold and the eyes area from the user.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset