如何在 Android 项目中应用 OpenCV?
如何在 Android 项目中应用 OpenCV?
流程总览
- 导入 OpenCV 库
 - 在 Android 项目中配置 OpenCV
 - 创建人脸识别器
 - 识别并裁剪人脸区域
 - 显示裁剪后的人脸图片
 
具体实现
导入 OpenCV 库
- 先去 OpenCV 官网下载 OpenCV 的 Android 库并解压:https://opencv.org/releases/
 - 在项目中点击 
file->new->Import Module,选择解压后的opencv-android-sdk文件夹中的sdk文件夹,并将 Module name 的名字修改为lib_opencv - 修改 
build.gradle(Module:lib_opencv)的sdk版本和build.gradle(Module:app)保持一致 
- 在
build.gradle(Project:project-name)中增加如下代码: 
 buildscript {
    # add
    ext.kotlin_version = '1.5.20'
    repositories { ... }
    dependencies {
    ...
    # add
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
}
- 在 
settings.gradle中增加一行:include ':lib_opencv' - 应用 OpenCV 库到 APP 中:点击 
file->project structure->Dependencies->app->3 Module Dependency,然后给 opencv 打上对勾,应用即可,表现在build.gradle(Module:app)中: 
dependencies {
    ...
    implementation project(path: ':lib_opencv')
    ...
}
- 在 Android 项目的 
AndroidManifest.xml文件中添加如下权限: 
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
- 在 MainActivity 类中,添加如下代码来加载 OpenCV 库
 
static {
    System.loadLibrary("opencv_java4");
}
- 可选步骤:将 
lib_opencv/etc/haarcascade/haarcascade_frontalface_default.xml文件复制到app/src/main/assets/文件夹下,方便调用 
创建人脸识别器
public class FaceDetector {
    private final String TAG = "FaceUtils";
    private String xmlPath = "haarcascade_frontalface_default.xml";
    CascadeClassifier faceDetector;
    static {
        System.loadLibrary("opencv_java4");
    }
    public FaceDetector(String dataPath) {
        String xmlFilePath = dataPath + xmlPath;
        // 创建人脸检测器
        faceDetector = new CascadeClassifier(xmlFilePath);
    }
识别并裁剪人脸
在这一步中,我们将加载图像并使用人脸识别器进行人脸检测:
public Bitmap detectAndCropFace(Bitmap originalBitmap) {
    // 将 Bitmap 转换为 Mat
    Mat mat = new Mat();
    Utils.bitmapToMat(originalBitmap, mat);
    // 创建一个灰度 Mat
    Mat grayMat = new Mat();
    Imgproc.cvtColor(mat, grayMat, Imgproc.COLOR_BGR2GRAY);
    // 检测人脸
    MatOfRect faces = new MatOfRect();
    faceDetector.detectMultiScale(grayMat, faces);
    // 获取第一个检测到的人脸的边界框
    Rect[] facesArray = faces.toArray();
    if (facesArray.length > 0) {
        Rect faceRect = facesArray[0];
        // 扩大边界框:数值可调整
        int padding = 20;
        faceRect.y = Math.max(faceRect.y - padding, 0);
        faceRect.height = Math.min(faceRect.height + 2 * padding, mat.rows() - faceRect.y);
        // 裁剪人脸
        Mat faceMat = new Mat(mat, faceRect);
        // 将 Mat 转换为 Bitmap
        Bitmap faceBitmap = Bitmap.createBitmap(faceMat.cols(), faceMat.rows(), Bitmap.Config.ARGB_8888);
        Utils.matToBitmap(faceMat, faceBitmap);
        return faceBitmap;
    } else {
        return null;
    }
}
显示裁剪后的人脸图片
private void showFace(Bitmap faceBitmap) {
    ImageView faceImageView = findViewById(R.id.faceImageView);
    faceImageView.setImageBitmap(faceBitmap);
}
runOnUiThread(() -> showFace(faceBitmap));
                
            
        
浙公网安备 33010602011771号