检测面部并使用openCV在其上应用蒙版

时间:2017-06-09 00:15:16

标签: android opencv real-time face-detection cascade-classifier

更新:here是opencv c ++示例,并准确显示了我想要做的事情。唯一的问题是我需要用java。

我一直致力于实时Android应用程序,该应用程序使用前置摄像头检测脸部并在检测到的脸部上添加蒙版。到目前为止,人脸检测在级联分类器中运行良好。

我在脸上绘制矩形,为眼睛绘制圆圈:

 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);

    }

我的问题是,如何在检测到的脸部上应用图像并实时显示。 (例如太阳镜,帽子,小胡子和有趣的动物脸)

如果有人可以给出提示或告诉我一些关键点,我会非常感激。

This就是我对应用程序的期望。我已经检查了代码,但无法理解。

谢谢!

2 个答案:

答案 0 :(得分:1)

你必须提取脸部的地标(一个好的图书馆是http://dlib.net/)。

enter image description here

对于这项任务,没有必要使用Haar级联分类器来检测面部。

但如果您只将图像的一部分(仅包含面部的部分)传递给计算地标的算法,则可能会有所帮助。在这种情况下,由于要计算的数据较少,算法应该更快。但请记住将点重新映射到完整图像的原始坐标参考系统。

一旦获得此分数,您就可以轻松地在相机拍摄的各种帧上重叠所需的图像。

答案 1 :(得分:0)

[解决]

Here是我放置面具的工作代码。

感谢@paul_poveda和@hariprasad

这是方法:

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;}