0

I'm doing a project on facial feature extraction. I have written MATLAB code for histogram equalization, face detection and face cropping. Now I want to straighten the face if it is tilted. Can you help me with the MATLAB code? Here is the code I have written so far.

clear all
clc

I=imread('100_3082.jpg');
figure(1)
imshow(I);
J=rgb2gray(I);
figure(2)
imshow(J);                                                             
P = histeq(J);
figure(3)
imshow(P);

FDetect = vision.CascadeObjectDetector;

BB = step(FDetect,P);
hold on
for i = 1:size(BB,1)
rectangle('Position',BB(i,:),'LineWidth',5,'LineStyle','-','EdgeColor','r');

end
for i = 1:size(BB,1)
Q= imcrop(P,BB(i,:));
figure(4)
imshow(Q);
end
title('Face Detection');   

hold off;

This is the image ('100_3082.jpg') I'm working on:-

100_3082.jpg

Community
  • 1
  • 1
Tejashree
  • 51
  • 8

1 Answers1

3

Algorithm:-
My solution implements your task using the following algorithm:

1. Finding the position of both eyes.
2. Finding the angle between them.
3. Rotating the image based on that angle.

Input Image:-
Input image of this code is the one you're getting at the end of your code i.e. Q.

input

Code:-

% Dividing the image in two halves for better detection
% To see why , see this: https://www.mathworks.com/matlabcentral/answers/155126-how-does-the-vision-cascadeobjectdetector-detect-left-and-right-eyes-separately-it-is-constantly-de
n = fix(size(Q,2)/2);
lefthalf = Q(:,1:n,:);
righthalf = Q(:,n+1:end,:);

RightEyeDetect = vision.CascadeObjectDetector('RightEyeCART');
LeftEyeDetect = vision.CascadeObjectDetector('LeftEyeCART');
% vision.CascadeObjectDetector(EyePairBig) is not much efficient in this case
% because the image is tilted. So, detecting both eyes separately.

%Bounding Boxes
BBREye= step(RightEyeDetect,lefthalf); %Right eye is on our left
BBLEye= step(LeftEyeDetect,righthalf); %Left eye is on our right
BBLEye(1)=BBLEye(1)+n; %correcting the x position of left eye (caused due to dividing the image in two halves)

figure
imshow(imrotate(Q,(180/pi)*atan((BBREye(2)-BBLEye(2))/(BBREye(1)-BBLEye(1)))));

Output:-

Output


P.S:
1. This may not be a perfect solution.
2. It is assumed that there is only one tilted face to be corrected.
3. The accuracy of this solution is dependent on the accuracy of detection of eyes for which the built-in MATLAB functions, which are based on Viola-Jones Algorithm, are used.
4. In case if this code fails, you can check whether the eyes were correctly detected or not by adding these lines:

BBEyes= [BBLEye ; BBREye];
figure,
imshow(Q); 
for i = 1:size(BBEyes,1)
 rectangle('Position',BBEyes(i,:),'LineWidth',4,'LineStyle','-','EdgeColor','r');
end

For your image, since this worked, you can still check whether the eyes were correctly detected or not. The result is the following which is correct:-

eyes detection

Sardar Usama
  • 19,536
  • 9
  • 36
  • 58
  • This is perfect. I thought that there is a built-in function to do this. but thanks! This is something new for me. I will study the code now. :) – Tejashree Sep 06 '16 at 04:20
  • can you explain this line? 'BBLEye(1)=BBLEye(1)+n;' What does that 1 indicate? If I run the same code for any other image it gives me this error _Attempted to access BBLEye(1); index out of bounds because numel(BBLEye)=0_ – Tejashree Sep 06 '16 at 05:05
  • @Emma I've already explained that line in the comments! since i divided the image in two parts, therefore the x-coordinate of the right half will start from 0 but it actually should start from some other value depending on the last value of the left half of the image!! `1` is indicating the first term of `BBLEye` which is x-coordinate. Regarding the error, I already mentioned that it is dependent on the accuracy of eye-detection! No detection or wrong detection will lead to errors/incorrect results. But if you detect the face correctly, it is most likely that it will work – Sardar Usama Sep 06 '16 at 05:15