Reputation: 1
UPDATE: here is opencv c++ sample and shows exactly what I want to do. Only thing is I need it with java.
I have been working on a real-time Android application which detects face with front camera and add a mask on a detected face. So far face detection is working well with cascade classifier.
I am drawing rectangles around face and circles for eyes:
Rect[] facesArray = faces.toArray();
for (int i = 0; i < facesArray.length; i++)
{
Imgproc.rectangle(mRgba, facesArray[i].tl(), facesArray[i].br(), FACE_RECT_COLOR, 3);
xCenter = (facesArray[i].x + facesArray[i].width + facesArray[i].x) / 2;
yCenter = (facesArray[i].y + facesArray[i].y + facesArray[i].height) / 2;
Point center = new Point(xCenter, yCenter);
Imgproc.circle(mRgba, center, 10, new Scalar(255, 0, 0, 255), 3);
}
My question is, how to apply an image on detected face and show it at real time. (e.g. sunglasses, hat, moustache, and a funny animal face)
If anyone could give a tip or tell me some key points, I would be so grateful.
This is a good example what I expect from my application. I have examined the code though but couldn't understand.
Thanks!
Upvotes: 0
Views: 5871
Reputation: 1
[SOLVED]
Here is a working code for me for putting mask.
Thanks to @paul_poveda and @hariprasad
this is the method:
Mat putMask(Mat src, Point center, Size face_size){
//mask : masque chargé depuis l'image
Mat mask_resized = new Mat(); //masque resizé
src_roi = new Mat(); //ROI du visage croppé depuis la preview
roi_gray = new Mat();
Imgproc.resize(mask ,mask_resized,face_size);
// ROI selection
roi = new Rect((int) (center.x - face_size.width/2), (int) (center.y - face_size.height/2),(int) face_size.width, (int) face_size.height);
//Rect roi = new Rect(10, 10, (int) face_size.width, (int) face_size.height);
src.submat(roi).copyTo(src_roi);
Log.e(TAG, "MASK SRC1 :"+ src_roi.size());
// to make the white region transparent
Mat mask_grey = new Mat(); //greymask
roi_rgb = new Mat();
Imgproc.cvtColor(mask_resized,mask_grey, Imgproc.COLOR_BGRA2GRAY);
Imgproc.threshold(mask_grey,mask_grey,230,255, Imgproc.THRESH_BINARY_INV);
ArrayList<Mat> maskChannels = new ArrayList<>(4);
ArrayList<Mat> result_mask = new ArrayList<>(4);
result_mask.add(new Mat());
result_mask.add(new Mat());
result_mask.add(new Mat());
result_mask.add(new Mat());
Core.split(mask_resized, maskChannels);
Core.bitwise_and(maskChannels.get(0),mask_grey, result_mask.get(0));
Core.bitwise_and(maskChannels.get(1),mask_grey, result_mask.get(1));
Core.bitwise_and(maskChannels.get(2),mask_grey, result_mask.get(2));
Core.bitwise_and(maskChannels.get(3),mask_grey, result_mask.get(3));
Core.merge(result_mask, roi_gray);
Core.bitwise_not(mask_grey,mask_grey);
ArrayList<Mat> srcChannels = new ArrayList<>(4);
Core.split(src_roi, srcChannels);
Core.bitwise_and(srcChannels.get(0),mask_grey, result_mask.get(0));
Core.bitwise_and(srcChannels.get(1),mask_grey, result_mask.get(1));
Core.bitwise_and(srcChannels.get(2),mask_grey, result_mask.get(2));
Core.bitwise_and(srcChannels.get(3),mask_grey, result_mask.get(3));
Core.merge(result_mask, roi_rgb);
Core.addWeighted(roi_gray,1, roi_rgb,1,0, roi_rgb);
roi_rgb.copyTo(new Mat(src,roi));
return src;}
Upvotes: 0
Reputation: 1008
You have to extract the landmarks of the face (a good library is http://dlib.net/).
For this task it's not really necessary to use the Haar Cascade Classifier to detect the face.
But it could help if you pass just a portion of your image (the section with only the face) to the algorithm that calculates the landmarks. In this case, with less data to compute, the algorithm should be faster. But remember to re-map the points to the original coordinate reference system of the full image.
Once that you had obtained this points you can easily overlap the image you need on the various frames captured from your camera.
Upvotes: 1