最近一直在捣腾openCV,看到美颜相机的眼睛放大觉得很好玩。本篇文章主要讨论:使用openCV做人脸检测、眼睛检测,然后实现人脸和眼睛的局部放大。当然这不仅局限于人脸于眼睛放大,可以做图片的任意区域的局部放大。

1、使用openCV时,先进行初始化:

    /**
     * 初始化openCV
     */
    private void initOpenCV(){
        boolean result = OpenCVLoader.initDebug();
        if(result){
            Log.i(TAG, "initOpenCV success...");
        }else {
            Log.e(TAG, "initOpenCV fail...");
        }
    }
2、然后初始化人脸和眼睛检测器:

    /**
     * 初始化人脸和眼睛检测器
     * @param context context
     */
    public void initDetector(Context context){
        mFaceRect = new MatOfRect();
        mFaceDetector = new ObjectDetector(context, R.raw.lbpcascade_frontalface,
                2, 0.2F, 0.2F,
                new Scalar(0, 0, 255, 0));

        mEyeRect = new MatOfRect();
        mEyeDetector = new ObjectDetector(context, R.raw.haarcascade_eye,
                2, 0.1F, 0.1F,
                new Scalar(0, 0, 255, 0));
    }
3、使用人脸检测器去检测人脸:

    /**
     * 检测人脸
     */
    private void detectFace(){
        Mat mGray = new Mat();
        Imgproc.cvtColor(mat, mGray, Imgproc.COLOR_RGBA2GRAY);
        Rect[] faceRect = mFaceDetector.detectObject(mGray, mFaceRect);
        if(faceRect != null && faceRect.length > 0){
            Rect face = faceRect[0];
            //矩形标识
            Imgproc.rectangle(mat, face.tl(), face.br(),
                    mFaceDetector.getRectColor(), 3);
            //待放大区域
            Mat zoomMat = mat.submat((int) face.tl().y, (int) face.br().y, (int) face.tl().x, (int) face.br().x);
            zoomOut(mat, zoomMat);
        }
        mGray.release();
    }
局部放大的方法,使用resize方法实现,默认放大倍数为1.5倍:
    /**
     * 局部放大
     * @param srcMat srcMat
     * @param zoomMat zoomMat
     */
    private void zoomOut(Mat srcMat, Mat zoomMat){
        double rowEnd = zoomMat.rows() * 1.5 < srcMat.rows() ? zoomMat.rows() * 1.5 : srcMat.rows();
        double colEnd = zoomMat.cols() * 1.5 < srcMat.cols() ? zoomMat.cols() * 1.5 : srcMat.cols();
        Mat zoomCorner = srcMat.submat(0, (int)rowEnd, 0, (int)colEnd);
        Imgproc.resize(zoomMat, zoomCorner, zoomCorner.size());
        zoomCorner.release();
        zoomMat.release();
        Utils.matToBitmap(srcMat, bitmap);
        img_zoom.setImageBitmap(bitmap);
    }

让我们看下人脸放大效果:

接下来,使用眼睛检测器去检测眼睛:

    /**
     * 检测眼睛
     */
    private void detectEye(){
        Mat mGray = new Mat();
        Imgproc.cvtColor(mat, mGray, Imgproc.COLOR_RGBA2GRAY);
        Rect[] eyeRect = mEyeDetector.detectObject(mGray, mEyeRect);
        if(eyeRect != null && eyeRect.length >= 2){
                //矩形标识
                Imgproc.rectangle(mat, eyeRect[0].tl(), eyeRect[1].br(),
                        mFaceDetector.getRectColor(), 3);
                //待放大区域
                Mat zoomMat = mat.submat((int) eyeRect[0].tl().y, (int) eyeRect[1].br().y,
                        (int) eyeRect[0].tl().x, (int) eyeRect[1].br().x);

                zoomOut(mat, zoomMat);
        }
        mGray.release();
    }
最后看下眼睛放大的效果(注意这里不是原位置放大,如果要做相机美颜效果需要稍作修改):

好了,图片的局部放大分析完毕。各位如果有问题或者建议,欢迎交流。。。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐