android openCV 应用 (一)

目录

一、概述

二、集成

1)添加依赖

2)初始化

3) 配置摄像头权限(可选)

4)验证openCV是否正常工作

三、图片的读取和写入

1)从资源文件(res/drawable)读取

2)从文件路径读取

3)从 Uri 读取(例如相册选择)

4)将 Mat 保存为文件

5)将 Mat 转换为 Bitmap 并显示

示例 1:读取资源图片并保存至本地

示例 2:从相册选择图片并处理


一、概述

        OpenCV即Open Source Computer Vision Library,意为开源的计算机视觉库。具有跨平台性、高效性‌、功能强大易于集成‌、开发者社区活跃等多个优点

二、集成

1)添加依赖

implementation 'org.opencv:opencv:4.8.0'

        也可手动导入,先在官网https://opencv.org/releases/下载 android 版 sdk,解压复制 java 文件夹至根目录,重命名为 opencv,并在setting.gradle中添加:

include ':opencv'
project(':opencv').projectDir = new File(rootProject.projectDir, 'path/to/opencv')

        在 app/build.gradle 中:

dependencies {
    implementation project(':opencv')
}

2)初始化

        在 application 或首个 activity 中的 onCreate 方法中添加:

if (!OpenCVLoader.initLocal()) {
    Log.e("OpenCV", "静态初始化失败");
} else {
    Log.d("OpenCV", "静态初始化成功");
}

        或是动态初始化

public class MainActivity extends AppCompatActivity {
    private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            if (status == LoaderCallbackInterface.SUCCESS) {
                Log.d("OpenCV", "动态初始化成功");
            } else {
                super.onManagerConnected(status);
            }
        }
    };

    @Override
    protected void onResume() {
        super.onResume();
        if (!OpenCVLoader.initDebug()) {
            OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
        } else {
            mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
        }
    }
}

3) 配置摄像头权限(可选)

4)验证openCV是否正常工作

Mat mat = new Mat();
Log.d("OpenCV", "Mat 对象创建: " + mat.toString());

ps:

1.推荐使用静态初始化避免依赖外部 apk。

2.通过 abiFilters 仅保留需要的架构以减小 apk 体积:

android {
    defaultConfig {
        ndk {
            abiFilters 'armeabi-v7a', 'arm64-v8a'
        }
    }
}

三、图片的读取和写入

1)从资源文件(res/drawable)读取

// 将资源图片转换为 Bitmap
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.logo);

// 将 Bitmap 转换为 OpenCV 的 Mat 格式
Mat mat = new Mat();
Utils.bitmapToMat(bitmap, mat); // 默认转换为 RGBA 格式的 Mat

// 如果图片需要以 BGR 格式处理(例如 OpenCV 默认处理格式),需转换颜色空间
Imgproc.cvtColor(mat, mat, Imgproc.COLOR_RGBA2BGR);

2)从文件路径读取

需要确保应用有存储权限(READ_EXTERNAL_STORAGE)。

// 获取图片路径(例如从相册选择)
String imagePath = "/sdcard/DCIM/Camera/test.jpg";

// 使用 OpenCV 直接读取图片为 Mat(默认 BGR 格式)
Mat mat = Imgcodecs.imread(imagePath);

// 如果读取失败,mat 会是空的
if (mat.empty()) {
    Log.e("OpenCV", "图片读取失败");
    return;
}

3)从 Uri 读取(例如相册选择)

// 通过 ContentResolver 获取输入流
InputStream inputStream = getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);

// 转换为 Mat
Mat mat = new Mat();
Utils.bitmapToMat(bitmap, mat);
Imgproc.cvtColor(mat, mat, Imgproc.COLOR_RGBA2BGR); // 转 BGR 格式

4)将 Mat 保存为文件

// 假设已经有一个处理后的 Mat 对象(BGR 格式)
Mat processedMat = ...;

// 保存到文件(支持格式:JPEG、PNG、WEBP 等)
String outputPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + "/output.jpg";
boolean success = Imgcodecs.imwrite(outputPath, processedMat);

if (success) {
    Log.d("OpenCV", "图片保存成功");
} else {
    Log.e("OpenCV", "图片保存失败");
}

5)将 Mat 转换为 Bitmap 并显示

// 将 Mat 转换为 Bitmap(需先转回 RGBA 格式)
Mat rgbaMat = new Mat();
Imgproc.cvtColor(processedMat, rgbaMat, Imgproc.COLOR_BGR2RGBA); // BGR 转 RGBA
Bitmap outputBitmap = Bitmap.createBitmap(rgbaMat.cols(), rgbaMat.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(rgbaMat, outputBitmap);

// 显示到 ImageView
ImageView imageView = findViewById(R.id.image_view);
imageView.setImageBitmap(outputBitmap);

示例 1:读取资源图片并保存至本地

// 1. 读取资源图片
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.input_image);
Mat mat = new Mat();
Utils.bitmapToMat(bitmap, mat);
Imgproc.cvtColor(mat, mat, Imgproc.COLOR_RGBA2BGR);

// 2. 处理图片(示例:灰度化)
Mat grayMat = new Mat();
Imgproc.cvtColor(mat, grayMat, Imgproc.COLOR_BGR2GRAY);

// 3. 保存灰度图到本地
String outputPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + "/gray_image.jpg";
Imgcodecs.imwrite(outputPath, grayMat);

// 4. 显示到 ImageView
Mat rgbaGrayMat = new Mat();
Imgproc.cvtColor(grayMat, rgbaGrayMat, Imgproc.COLOR_GRAY2RGBA);
Bitmap grayBitmap = Bitmap.createBitmap(rgbaGrayMat.cols(), rgbaGrayMat.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(rgbaGrayMat, grayBitmap);
imageView.setImageBitmap(grayBitmap);

示例 2:从相册选择图片并处理

// 在 onActivityResult 中处理返回的 Uri
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null) {
        Uri uri = data.getData();
        try {
            InputStream inputStream = getContentResolver().openInputStream(uri);
            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
            
            // 转换为 Mat 并处理
            Mat mat = new Mat();
            Utils.bitmapToMat(bitmap, mat);
            Imgproc.cvtColor(mat, mat, Imgproc.COLOR_RGBA2BGR);

            // ... 执行处理操作 ...

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

ps: 1.读写外部存储需动态申请权限。

2.openCV 默认使用 BGR格式,而 android 的 bitmap 默认使用 RGBA格式,需用Imgproc.cvtColor方法转换。

3.考虑到 android 各版本兼容,不建议直接访问 /sdcard 路径

4.高分辨率图片建议先缩放 bitmap 以节省内存

Bitmap scaledBitmap = Bitmap.createScaledBitmap(originalBitmap, newWidth, newHeight, true);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值