0

更新:是 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);

    }

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

如果有人能给我小费或告诉我一些关键点,我将不胜感激。

是我对我的应用程序的期望的一个很好的例子。我已经检查了代码,但无法理解。

谢谢!

4

2 回答 2

1

您必须提取面部的地标(一个很好的库是http://dlib.net/)。

在此处输入图像描述

对于这个任务,实际上不需要使用 Haar Cascade Classifier 来检测人脸。

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

一旦您获得了这些点,您就可以轻松地将所需的图像重叠在从相机捕获的各种帧上。

于 2017-06-09T10:35:36.437 回答
0

[解决了]

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

感谢@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;}
于 2017-11-15T15:52:28.847 回答