OpenCV环境搭建
1.下载SDK
2.项目配置
新建项目后,第一步,引入openCVLibrary330模块,并添加依赖。
直接import module,OpenCV-android-sdk\sdk\java文件;
若由于Android SDK Platform版本差异报错,则参考项目app下的build.gradle修改openCVLibrary330下的build.gradle。
第二步,将opencv的so文件添加到libs中
so文件:OpenCV-android-sdk\sdk\native\libs
第三步,创建人脸特征文件(xml)的raw资源文件夹,并添加特征文件。
人脸特征文件:OpenCV-android-sdk\sdk\etc\lbpcascades\lbpcascade_frontalface.xml
最后,也可以直接在其他module中引用此library module,方法如下:
File->project structure->对应app->dependencies->+->module dependency
人脸检测的实现
使用OpenCV实现人脸检测主要用到两个类:CascadeClassifier
首先是CascadeClassifier(级联分类器),用于根据特征文件(xml)检测人脸,因此在检测前必须先初始化它,检测函数为detectMultiScale(),会在检测时使用。
注意,第一步要引用库:
// 手动装载openCV库文件,以保证手机无需安装OpenCV Manager
static {
System.loadLibrary("opencv_java3");
}
二,初始化分类器
// 初始化人脸级联分类器,必须先初始化
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();
classifier = new CascadeClassifier(cascadeFile.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
}
}
三、检测模块
// 这里执行人脸检测的逻辑, 根据OpenCV提供的例子实现(face-detection)
public Mat detect(Bitmap bitmap) {
// Bitmap转为Mat
Mat src = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC4);
Utils.bitmapToMat(bitmap, src);
Mat srcGray = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC4);
// 图像置灰
Imgproc.cvtColor(src, srcGray, Imgproc.COLOR_BGRA2GRAY);
float mRelativeFaceSize = 0.15f;
if (mAbsoluteFaceSize == 0) {
int height = srcGray.rows();
if (Math.round(height * mRelativeFaceSize) > 0) {
mAbsoluteFaceSize = Math.round(height * mRelativeFaceSize);
}
}
MatOfRect faces = new MatOfRect();
if (classifier != null)
classifier.detectMultiScale(srcGray, faces, 1.1, 3, 0,
new Size(mAbsoluteFaceSize, mAbsoluteFaceSize), new Size());
Rect[] facesArray = faces.toArray();
Scalar faceRectColor = new Scalar(0, 255, 0, 255);
for (Rect faceRect : facesArray)
Imgproc.rectangle(src, faceRect.tl(), faceRect.br(), faceRectColor, 3);
return src;
}
四、mat转bitmap
Mat dst = detect(data.get(loc));
// Mat转Bitmap
Bitmap resultImage = Bitmap.createBitmap(dst.cols(), dst.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(dst, resultImage);