Android OpenGL+Camera2渲染(1) —— OpenGL简单介绍
Android OpenGL+Camera2渲染(2) —— OpenGL实现Camera2图像预览
Android OpenGL+Camera2渲染(3) —— 大眼,贴纸功能实现
Android OpenGL+Camera2渲染(4) —— 美颜功能实现
Android OpenGL+Camera2渲染(5) —— 录制视频,实现快录慢录
————————————————
版权声明:本文为优快云博主「行走的荷尔蒙CC」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/wangchao1412/article/details/103832867
在实现大眼,贴纸的功能前提,贴纸需要知道人脸的坐标点,大眼自然是需要找到眼睛的坐标点。
本篇使用OpenCV来定位人脸, SeetaFaceEngine中的Alignment模块来定位眼睛,使用的原因的opencv定位眼睛的模型不好用,测试seeta中的眼睛定位还是可以的,可以定位五个点,左眼、右眼、鼻子、左嘴巴、右嘴巴。
首先需要交叉编译opencv,拿到库文件和头文件,对于seeTaAlignment,把代码直接拿过来,参考它的makeList文件修改即可。
我这里是先把模型文件加载到了本地,opencv需要的 lbpcascade_frontalface_improved 和 seeta 定位大眼的seeta_fa_v1.1.bin。
public GlRenderWrapper(GlRenderView glRenderView) {
this.glRenderView = glRenderView;
Context context = glRenderView.getContext();
//拷贝 模型
OpenGlUtils.copyAssets2SdCard(context, "lbpcascade_frontalface_improved.xml",
"/sdcard/lbpcascade_frontalface.xml");
OpenGlUtils.copyAssets2SdCard(context, "seeta_fa_v1.1.bin",
"/sdcard/seeta_fa_v1.1.bin");
}
在onSurfaceChanged中,创建FaceTracker
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
//1080 1899
....
....
/
tracker = new FaceTracker("/sdcard/lbpcascade_frontalface.xml", "/sdcard/seeta_fa_v1.1.bin", camera2Helper);
tracker.startTrack();
...
}
FaceTracker jni类,
public class FaceTracker {
static {
System.loadLibrary("native-lib");
}
....
....
//传入模型文件, 创建人脸识别追踪器和人眼定位器
private native long native_create(String model, String seeta);
//开始追踪
private native void native_start(long self);
//停止追踪
private native void native_stop(long self);
//检测人脸
private native Face native_detector(long self, byte[] data, int cameraId, int width, int
height);
....
....
}
这里我们只看一下native_detector的实现。
JNIEXPORT jobject JNICALL
Java_com_example_cameraglrender_face_FaceTracker_native_1detector(JNIEnv *env, jobject thiz,
jlong self, jbyteArray data_,
jint camera_id, jint width,
jint height) {
if (self == 0) {
return NULL;
}
jbyte *data = env->GetByteArrayElements(reinterpret_cast<jbyteArray>(data_), NULL);
FaceTracker *faceTracker = reinterpret_cast<FaceTracker *>(self);
Mat src(height + height / 2, width, CV_8UC1, data);
//颜色格式的转换 nv21->RGBA
//将 nv21的yuv数据转成了rgba
cvtColor(src, src, COLOR_YUV2RGBA_I420);
// 正在写的过程 退出了,导致文件丢失数据
if (camera_id == 1) {
//前置摄像头,需要逆时针旋转90度
rotate(src, src, ROTATE_90_COUNTERCLOCKWISE);
//水平翻转 镜像
flip(src, src, 1);
} else {
//顺时针旋转90度
rotate(src, src, ROTATE_90_CLOCKWISE);
}
Mat gray;
//灰色
cvtColor(src, gray, COLOR_RGBA2GRAY);
//增强对比度 (直方图均衡)
equalizeHist(gray, gray);
vector<Rect2f> rects;
//送去定位
faceTracker->detector(gray, rects);
env->ReleaseByteArrayElements(data_, data, 0);
int w = src.cols;
int h = src.rows;
src.release();