android 美颜大眼特效

需要知识点,从相机抓取到数据,给opencv进行人脸定位,再用SeetaFaceEngine眼睛的定位,然后渲染的时候在片元着色器中进行计算,对眼睛进行局部放大;

1.开始集成opencv

opencv官网地址:Releases - OpenCV

下载Android 版本:

android 美颜大眼特效_第1张图片

把已经编译号的库放到我们项目中

android 美颜大眼特效_第2张图片

android 美颜大眼特效_第3张图片

把整个头文件放到项目中

android 美颜大眼特效_第4张图片

android 美颜大眼特效_第5张图片

 把训练的人脸模板放到项目中:

android 美颜大眼特效_第6张图片

 android 美颜大眼特效_第7张图片

 最后在app build.gradle中添加opencv的相关配置:

        externalNativeBuild {
            cmake {
                //OpenCV新版本用这个C++11的特效
                cppFlags "-std=c++11"
                //NDK从r16开始就切换到了llvm的libC++,所以opencv4从libstdC++切换到了libc++。
                //导致链接错误的根本原因是设置了-DANDRID_STL=gnustl_shared,
                //因为opencv利用的libc++编的,而非gnustl
                //arguments "-DANDROID_STL=gnustl_static" // OpenCV旧版本用这个
                //新版本的opencv 需要添加这个变量
                arguments "-DANDROID_STL=c++_shared"
                abiFilters 'armeabi-v7a'
            }
        }

 在CmakeLists中配置:


cmake_minimum_required(VERSION 3.4.1)

#opencv 头文件
include_directories(include)

#opencv 库文件
set(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS}")

add_library( # Sets the name of the library.
        native-lib
        SHARED
        native-lib.cpp)

target_link_libraries( # Specifies the target library.
        native-lib
        #链接opencv,也就是libopencv_java4
        opencv_java4
        )

人脸关键点定位使用中科院开源的

https://github.com/seetaface/SeetaFaceEngine

集成到项目中:

android 美颜大眼特效_第8张图片

 android 美颜大眼特效_第9张图片

把model中的模板放到项目中:

android 美颜大眼特效_第10张图片

 修改CMakeList:

# 他需要用到 C++11特性
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
# 设置他需要的参数
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")
# 设置他需要的参数
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1")
# 导入头文件
include_directories(include)

set(src_files # CPP源码关联
        src/cfan.cpp
        src/face_alignment.cpp
        src/sift.cpp
        )
# 生成静态库
add_library(seeta_fa_lib STATIC ${src_files})

 在总的CMakeList中引入

android 美颜大眼特效_第11张图片

结合前面的音视频录制,把数据给opencv 定位出人脸,再给SeetaFace去定位眼睛的关键点,然后传给着色器,

FaceTrack.cpp  中处理人脸定位,关键点定位

初始化opencv追踪器,及seeta关键点

FaceTrack::FaceTrack(const char *model, const char *seet) {
        Ptr mainDetector = makePtr(makePtr(model)); // OpenCV主探测器
    Ptr trackingDetector = makePtr(makePtr(model)); // OpenCV跟踪探测器
    DetectionBasedTracker::Parameters detectorParams;
    // OpenCV创建追踪器,为了下面的(开始跟踪,停止跟踪)
    tracker = makePtr(mainDetector, trackingDetector, detectorParams);

    // 上面是OpenCV模板代码人脸追踪区域, 下面是Seeta人脸关键点代码+OpenCV
    faceAlignment = makePtr(seet); // Seeta中科院关键特征点
}

获取关键点

void FaceTrack::detector(Mat src, vector  &rects) {
    vector faces;
    // src :灰度图(去除 不需要的色彩信息)
    tracker->process(src); // 处理灰度图(OpenCV的东西,灰度,色彩 影响我们人脸追踪)
    tracker->getObjects(faces); // 得到人脸框框的Rect - OpenCV的东西
    if (faces.size()) { // 判断true,说明非零,有人脸
        Rect face = faces[0]; // 有人脸就去第一个人脸,我没有去管,多个人脸了哦
        // 然后把跟踪出来的这个人脸,保存到rects里面去
        rects.push_back(Rect2f(face.x, face.y, face.width, face.height));

        // 根据前面的OpenCV人脸最终结果, 做人脸关键点定位
        seeta::ImageData image_data(src.cols, src.rows); // image_data就是图像数据
        image_data.data = src.data; // (人脸的信息 要送去检测的) = (把待检测图像)

        // 人脸追踪框 信息绑定  人脸关键点定位
        seeta::FaceInfo face_info; // 人脸的信息 要送去检测的
        seeta::Rect bbox; // 人脸框框的信息
        bbox.x = face.x;           // 把人脸信息的x 给 face_info
        bbox.y = face.y;           // 把人脸信息的y 给 face_info
        bbox.width = face.width;   // 把人脸信息的width 给 face_info
        bbox.height = face.height; // 把人脸信息的height 给 face_info
        face_info.bbox = bbox;     // 把人脸信息的bbox 给 face_info

        seeta::FacialLandmark points[5]; // 特征点的检测,固定了5个点

        // 执行采集出 五个点
        faceAlignment->PointDetectLandmarks(image_data, face_info, points);

        // 把五个点 转换 ,因为第二个参数需要 Rect2f
        for (int i = 0; i < 5; ++i) { // 为何不需要宽和高,只需要保存点就够了
            rects.push_back(Rect2f(points[i].x, points[i].y, 0, 0));
        }
    }
}

大眼算法见:http://www.gson.org/thesis/warping-thesis.pdf

代码地址:Seven: Android音视频

你可能感兴趣的:(音视频,音视频)