Time for action – automating our function for red eye reduction

This time, we will use one extra tool in our function, removing the need for ROI selection. The rationale of the refined function will be to first check the image for circular regions in color channel a* (we must find two) and then perform masking of the pixels in these regions having high a* values. You may have noticed that we did not mention any manual ROI selection step. However, we should state the suspected radii for the circle detection.

  1. Let's see if this approach works, by first writing our function:
    function output = RedEyeReductionCircular(input, thresh, radii) 
     
    % Function for red eye reduction in input image 
    % Inputs:
    % input - Input image
    % thresh – Threshold value in channel a*
    % radii – 2x1 matrix with lowest and highest radius
    % 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*
     
    a = img_lab(:,:,2); % Isolate a* channel
    [I,r] = imfindcircles(a,radii); % Detect circles in ROI
     
    mask = zeros(size(a)); % Make a mask full of zeros
     
    if size(I,1) ~= 2   % If we don't detect a pair of eyes
      disp('No pair of eyes detected in ROI!')
      % In case of failure, revert to the manual function  
    output = RedEyeReduction(input, thresh); 
    else
      mask(round(I(1,2)),round(I(1,1)))=1; % First eye center
      mask(round(I(2,2)),round(I(2,1)))=1; % Second eye center
      average_radius = round((r(1)+r(2))/2); % Find average eye radius
      mask = imdilate(mask,strel('disk',average_radius)); % Enlarge ROIs
      mask = (mask > 0) & a > thresh; % Keep pixels with high a* 
        values 
      % 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
    end
  2. This time, the results are computed automatically, so if we have chosen proper values for the threshold and radii, the result should be correct. Let's check if this is true. First, we load our image and call the function with the proper inputs:
    >> img = imread('my_red_eyes.bmp'),
    >> output = RedEyeReductionCircular(img, 150, [10 25]);
  3. Now, it is time to visualize our results:
    >> figure,subplot(1,2,1),imshow(img),title('Original image')
    >> subplot(1,2,2),imshow(output),title('Automatic red eye reduction')
    Time for action – automating our function for red eye reduction
  4. So far, so good. Our function seems to be working like a charm! But what happens when wrong radii are chosen? Will our function revert to the manual method, or will it fail completely? Let's see what happens if we give very large radii values:
    >> figure; % Open new figure
    >> output = RedEyeReductionCircular(img, 150, [40 45]);

    The output of the previous code is as follows:

    No pair of eyes detected in ROI!
    Warning: Image is too big to fit on screen; displaying at 33%
    > In imuitoolsprivateinitSize at 72
      In imshow at 283
      In roipoly>parse_inputs at 184
      In roipoly at 81
      In RedEyeReduction at 13
      In RedEyeReductionCircular at 22
  5. The result of the previous action was as expected. The warning message is nothing to worry about; it comes up every time the image we try to display is very large to fit on the screen. After the warning message, our image is displayed at 33% of its size and we must, as before, select the ROI of the eyes:
    Time for action – automating our function for red eye reduction
  6. After selecting our ROI, we can display the results:
    >> figure,subplot(1,2,1),imshow(img),title('Original image')
    >> subplot(1,2,2),imshow(output),title('Automatic red eye reduction')
    Time for action – automating our function for red eye reduction

What just happened?

You have just mastered the secrets behind a simple automated red eye reduction. The process of ROI selection is no longer needed, as we use the proper MATLAB function to detect circular objects. We also included a safety check, so that the function does not do anything if no pair of eyes is detected (or if more than two circular objects are detected). In this case, we use disp to display an error message in the command line and then we return the input as output. In case there is a pair of circular objects detected, we locate the coordinates of their centers, create an empty mask of equal size to our image, and set the pixels of the centers equal to one. Then, we find the average radius of the two eyes, round it to the nearest integer, and use it to make a disk structuring element to dilate the centers. This process leads to an almost perfect mask creation. The mask is then refined using the color thresholding process used in the previous example and finally, we replace the red pixels as already described. In the case that no pair of circles is detected, our function falls back to the previous method implemented and uses the selected threshold and a user-selected ROI to perform red eye reduction.

Pop quiz – working with color

Q1. Which of the following sentences are true?

  1. A pixel with RGB values equal to {0,255,0} is red.
  2. If we set all the pixels of the first dimension, of a three-dimensional matrix representing an image equal to zero, we will have no red pixels left.
  3. HSV and CIE-L*a*b* handle illumination fluctuations more efficiently, because they have separate channels for brightness and color information.
  4. Using histeq is the best out-of-the-box method to correct the illumination of an RGB image.
  5. Red eye reduction can be handled efficiently just by thresholding the red channel of the picture.
..................Content has been hidden....................

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