OpenCV 库导入可参考:https://blog.csdn.net/zhrjyl/article/details/104442030
Demo:链接:https://pan.baidu.com/s/1z0WsF0nI5GuXilcBHnPWPA 提取码:5a0m
目录
人脸检测效果
开发环境
人脸检测原理
人脸检测实践
步骤 1:权限声明与申请
步骤 2:布局文件中导入 JavaCameraView 控件
步骤 3:Activity 实现 CameraBridgeViewBase.CvCameraViewListener2 接口
步骤 4:Activity 初始化 JavaCameraView 控件
步骤 5:导入 OpenCV 提供的人脸模型
步骤 6:初始化 CascadeClassifier 级联分类器
步骤 7:重写 onCameraFrame 检测人脸
补充
补充 1:Activity 中的 onCreate 方法
人脸检测效果 开发环境 Android Studio:3.5 OpenCV:opencv-3.4.1-android-sdk 工程基础:已经实现 OpenCV 的库导入 人脸检测原理 初步认知 OpenCV 的人脸检测逻辑: 步骤 1:通过 JavaCameraView 控件实现相机预览。 步骤 2:通过 CameraBridgeViewBase.CvCameraViewListener2 获取预览时每一帧的数据。 步骤 3:通过 CascadeClassifier,将每一帧的数据与训练好的人脸模型数据比对。 步骤 4:通过 Imgproc.rectangle 给识别出的人脸画框。 人脸检测实践人脸检测实践分为以下几个步骤:
步骤 1:权限声明与申请 步骤 2:布局文件中导入 JavaCameraView 控件 步骤 3:Activity 实现 CameraBridgeViewBase.CvCameraViewListener2 接口 步骤 4:Activity 初始化 JavaCameraView 控件 步骤 5:导入 OpenCV 提供的人脸模型 步骤 6:初始化 CascadeClassifier 级联分类器 步骤 7:重写 onCameraFrame 检测人脸 步骤 1:权限声明与申请
private void askPermission(){
ActivityCompat.requestPermissions(
this,
new String[]{
Manifest.permission.CAMERA
},
1
);
}
步骤 2:布局文件中导入 JavaCameraView 控件
步骤 3:Activity 实现 CameraBridgeViewBase.CvCameraViewListener2 接口
private Mat matRgba;// 彩色图象容器
private Mat matGray;// 灰色图象容器
@Override
public void onCameraViewStarted(int width, int height) {
matRgba = new Mat();
matGray = new Mat();
}
@Override
public void onCameraViewStopped() {
matRgba.release();
matGray.release();
}
@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
matRgba = inputFrame.rgba();
matGray = inputFrame.gray();
return matRgba;
}
步骤 4:Activity 初始化 JavaCameraView 控件
private JavaCameraView mCameraView;
private void initCamera(){
mCameraView = findViewById(R.id.javaCameraView);
if(mCameraView != null){
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
mCameraView.setCvCameraViewListener(this);
mCameraView.enableFpsMeter();// 显示fps信息
mCameraView.setCameraIndex(0);// 设置摄像头 0 后置摄像头 1 前置摄像头
mCameraView.enableView();
}
}
注意:
为了更改相机预览方向做了以下修改
至此已静可以实现相机预览。
步骤 5:导入 OpenCV 提供的人脸模型
将 \opencv-3.4.1-android-sdk\OpenCV-android-sdk\sdk\etc\lbpcascades 下的 lbpcascade_profileface.xml 与 lbpcascade_frontalface.xml 文件拷贝到 MyApplication\app\src\main\res\raw 目录下
步骤 6:初始化 CascadeClassifier 级联分类器
private CascadeClassifier frontClassifier;// 正脸,级分类器
private CascadeClassifier profileClassifier;// 侧脸,级分类器
private void initClassifier() {
// 初始化正脸,级分类器
try {
InputStream is =
getResources().openRawResource(R.raw.lbpcascade_frontalface);// 正脸模型
File cascadeDir = getDir("cascade", Context.MODE_PRIVATE);
File cascadeFile = new File(cascadeDir, "lbpcascade_frontalface.xml");
FileOutputStream os = new FileOutputStream(cascadeFile);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
is.close();
os.close();
frontClassifier = new CascadeClassifier(cascadeFile.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
}
// 初始化侧脸,级分类器
try {
InputStream is =
getResources().openRawResource(R.raw.lbpcascade_profileface);//侧脸模式
File cascadeDir = getDir("cascade", Context.MODE_PRIVATE);
File cascadeFile = new File(cascadeDir, "lbpcascade_profileface.xml");
FileOutputStream os = new FileOutputStream(cascadeFile);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
is.close();
os.close();
profileClassifier = new CascadeClassifier(cascadeFile.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
}
}
步骤 7:重写 onCameraFrame 检测人脸
@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
// 步骤 1:获取相机捕捉到的帧的彩色和灰色数据,并保存到 Mat 图象容器中
matRgba = inputFrame.rgba();
matGray = inputFrame.gray();
// 步骤 2:计算绝对面尺寸
float mRelativeFaceSize = 0.15f;
int mAbsoluteFaceSize = 0;
int height = matGray.rows();
if (Math.round(height * mRelativeFaceSize) > 0) {
mAbsoluteFaceSize = Math.round(height * mRelativeFaceSize);
}
// 步骤 3:定义矩阵图象容器,存放检测出来的人脸数据矩阵
MatOfRect frontFaces = new MatOfRect();
MatOfRect profileFaces = new MatOfRect();
// 步骤 4:人脸检测
if (frontClassifier != null)
frontClassifier.detectMultiScale(
matGray,
frontFaces,
1.1,
3,
0,
new Size(mAbsoluteFaceSize, mAbsoluteFaceSize),
new Size());
if (profileClassifier != null)
profileClassifier.detectMultiScale(
matGray,
profileFaces,
1.1,
3,
0,
new Size(mAbsoluteFaceSize, mAbsoluteFaceSize),
new Size());
// 步骤 5:根据检测出来的人脸矩阵数据在彩色图像上画方框
for (Rect faceRect : frontFaces.toArray())
Imgproc.rectangle(
matRgba, // 图象源
faceRect.tl(), // 矩形框的 x 起点
faceRect.br(), // 矩形框的 y 起点
new Scalar(0, 255, 0, 255),// 矩形框颜色
3); // 矩形框厚度
for (Rect faceRect : profileFaces.toArray())
Imgproc.rectangle(
matRgba,
faceRect.tl(),
faceRect.br(),
new Scalar(0, 255, 0, 255),
3);
return matRgba;
}
补充
补充 1:Activity 中的 onCreate 方法
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_a2);
askPermission();
initCamera();
initClassifier();
}
作者:Look For Answer