Introduction
Detecting
a face in digital image is simply a way to find pixels location
containing face pattern in it. Examples of this application resides
in our smart-phone camera that has an ability to detect face in
captured frame, security system that many applied in CCTV (Closed
Circuit Television) system, and Marketing field (but this is still
rarely found). One thing needed to remember is that the term of ‘face
detection’ is different from ‘face recognition’ that the latter
means a system can identify ‘whose’ person of any face detected,
while the former means a system just ‘point out’ a face in an
image – without knowing ‘who’ is he or she’. For this post,
Java programming language will be used to detect a face in an image.
Prerequisites
In
this post, bellow prerequisites are assumed have been installed on
your system
- OpenCV 4.1.1 library or latter
- Java – JDK 1.8
- Your favorite text editor or IDE, such as Eclipse, Netbeans, or etc. Here Vim text editor with Ant to coplile
Codes
Before
going through the code, we need to prepare these files first:
lena.jpg
(the image that we use to test our program), and
haarcascade_frontalface_alt.xml
(the trained classifier for detection ‘utility’)
The
two files mention above has been there in OpenCV directory you
installed, just find them on your OpenCV installation directory. In
my computer the xml file is in
installation/OpenCV-4.1/share/opencv4/haarcascades, and for the image
you can save the lena.jpg image from this post (in figure 1).
Figure 1. Our image lena.jpg (source: OpenCV org) |
After
the files above we have, the next thing to do is to make a file named
FaceDetect.java and followed
by the steps bellow.
Note
that in this post, I am going to explain the code by parts, which
means you can copy the code per parts until the end, and therefore
can compile all parts in a file named FaceDetect.java.
Post related:
Post related:
Modules
Imported
So here we go, in the file
that we have made above just copy the following imported module to
the file. In Java, any module name – where any class resides in the
module - is usually ‘imported’ first before we can use the
class. Hence Bellow are modules we need to import:
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.highgui.HighGui;
import org.opencv.core.MatOfByte;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.core.MatOfRect;
import org.opencv.core.Rect;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
All the module reside in
org.opencv.
Main
Class
The next step is to provide
our main class.
public class FaceDetect{
… //our next code lines continue here
}
note that the class name must
be the same name as the file name. A compilation error for this type
of different name
Within
FaceDetect Class
To be able to use OpenCV
library in java, the first thing we need to do is to load all the
native libraries with this line of code:
static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }
this line of code can be put
inside or outside main() function. For this case, I prefer the
former, putting it outside the main function.
public static void main(String[] args){
… //our next code lines continue here
}
Within
main() Function
The first thing to do is to
give our window a name and read an image (lena.jpg)
String image_path = new String(“/path/to/lena.jpg”);
Mat im = Imgcodecs.imread(image_path);
Mat im_gray = new Mat();
Imgproc.cvtColor(im,im_gray, Imgproc.COLOR_BGR2GRAY);
Imgproc.equalizeHist(im_gray,im_gray);
The
image that we give to CascadeClassifier instance latter needs to be
in gray-scale mode. This is achieved by cvtColor() function above
-The first and the second argument are for input and output image
respectively, while the last argument is color space conversion code
flag.
To
be well detected, equalizeHist() function is usually used to equalize
the histogram for the frame / image given, decreasing ‘dark’
pixels value to balance all other pixels, or simply to brighten a
dark image.
Finding
Face Location
This is where face location in
an image is found. In other words the face detection process happens
in these lines of code bellow:
String cascade_path = new String(“/path/to/haarcascade_frontalface_alt.xml”);
CascadeClassifier classifier = new CascadeClassifier(cascade_path);
MatOfRect faceDetections = new MatOfRect();
classifier.detectMultiScale(im_gray, faceDetections);
First we need to identify the
haarcascade_frontalface_alt.xml file
path tusing String instance, here the name of the instance is
cascade_path where we
pass the path directly through the String constructor.
Next, we make an instance of CascadeClassifier class by
passing a constructor argument cascade_path that we have
declared above. By doing that, the haarcascade_frontalface_alt.xml
file
is automatically loaded.
The next two
lines
are
where face detection happens by using detectMultiscale() method of
the instance. According to OpenCV reference manual, it
state that the method detects object of different size in
the input image and the detected object are returned as a list of
rectangles. Therefore, we need
the MatOfRect instance to be able to do that.
For the first and the second
argument of this methods are input and output images respectively.
Note that the output is in form of a list of rectangle that we have
provided it by faceDetections instance.
Signifying
Face Detected
So far, we have detected the
face object or the location of the pixel has been found. Therefore it
will be meaningless if the frame which will be shown doesn’t give
any information about where the pixel (or face location) is in the
image. The bellow code will give a blue line rectangle that surrounds
our lena.jpg face image, and then showing the image with a
face detected on computer screen.
for (Rect rect : faceDetections.toArray()) {
Point blPoint = new Point(rect.x,rect.y); //bottom-left point
Point trPoint = new Point(rect.x + rect.width,rect.y + rect.height); //top-ri
Scalar imgColor = new Scalar(255,0,0,0); //green color
Imgproc.rectangle(im,blPoint,trPoint,imgColor,3);
}
the for() loop
expression above just counts and processes how many face of the image
detected. Within the for() loop statement, we use rectangle()
function to draw a blue rectangle of our face-detected image. The
first im argument is for input image, the next second and
third arguments, blPoint and trPoint are for
bottom-left point and top-right point respectively. These two
arguments are for area of our rectangle with its start and end point.
The last two arguments (but not least), imgColor and 3
are for color and line size of a rectangle surrounding the face.
Note that for the
Scalar(0,0,255) will cause our rectangle blue, because the it is in
BGR format. You can try to experiment with other values with this
function.
Showing the Image Result
and Waiting for a ‘Q’ Key
As all the face detecting
operation is done, the next thing is to show the result using the
imshow() method and waiting ‘Q’ key to be pressed to exit
the program and closing the window.
HighGui.imshow("FaceDetect",im);
while((char)HighGui.waitKey(0) != 'Q');
HighGui.destroyAllWindows();
System.exit(0);
When the code is run, the output will be like on the figure 2.
Figure 2. Face detected surrounded by a red line (rectangle) |
Conclusion
Detecting a face in an image
is relatively easy to do especially for a beginner who just start to
learn. Since almost all necessary functions/methods and “stuffs”
has been prepared by OpenCV library, like one we use
haarcascade_frontalface_alt.xml file and some methods and
classes that support it. There are also so many trained cascade file
that you can find out there, like on github, such as banana, dog, cat
many other else trained files detector. Just have fun with them.
0 Comments
Post a Comment