Android学习8 -- NDK2--练习2(Opencv)

以下是一个简单的安卓项目示例,通过NDK调用OpenCV来处理图像(例如,将彩色图像转换为灰度图像)。


开发环境

  1. 安装 Android Studio(支持NDK开发)。
  2. 配置NDK和CMake(通过Android Studio的SDK Manager)。
  3. 下载OpenCV Android库:OpenCV Releases

步骤

1. 下载并配置OpenCV
  • 下载OpenCV Android库,解压后会有一个 sdk 文件夹。
  • sdk/native/libs 文件夹中的 .so 文件和 include 目录添加到项目中:
    • .so 文件放到 app/src/main/jniLibs/<ABI>/ 目录,例如 armeabi-v7a
    • include 文件夹放到 app/src/main/cpp/include

2. 创建Android项目
  • 创建一个新项目并选择 Include C++ Support

3. 添加C++代码

创建 cpp/image_processor.cpp

复制代码
#include <jni.h>
#include <opencv2/opencv.hpp>
#include <android/log.h>

#define LOG_TAG "ImageProcessor"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)

extern "C" JNIEXPORT void JNICALL
Java_com_example_opencvndk_MainActivity_convertToGray(
        JNIEnv *env, jobject /* this */, jlong inputMatAddr, jlong outputMatAddr) {
    cv::Mat &inputMat = *(cv::Mat *) inputMatAddr;
    cv::Mat &outputMat = *(cv::Mat *) outputMatAddr;

    if (inputMat.empty()) {
        LOGD("Input image is empty!");
        return;
    }

    cv::cvtColor(inputMat, outputMat, cv::COLOR_BGR2GRAY);
}

4. 修改 CMakeLists.txt

app/src/main/cpp/CMakeLists.txt 中:

复制代码
cmake_minimum_required(VERSION 3.10.2)
project("opencvndk")

# 添加 OpenCV 头文件路径
include_directories(${CMAKE_SOURCE_DIR}/include)

# 添加库
add_library(image_processor SHARED image_processor.cpp)

# 指定 OpenCV 动态库路径
add_library(opencv_java4 SHARED IMPORTED)
set_target_properties(opencv_java4 PROPERTIES
    IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}/libopencv_java4.so)

# 链接库
target_link_libraries(
        image_processor
        opencv_java4
        log) # log 库用于 Android 日志

5. 编写JNI接口

MainActivity.java 中:

复制代码
package com.example.opencvndk;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.android.Utils;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {

    static {
        System.loadLibrary("image_processor");
    }

    private native void convertToGray(long inputMatAddr, long outputMatAddr);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (!OpenCVLoader.initDebug()) {
            throw new RuntimeException("Unable to load OpenCV");
        }

        // 加载图片
        Mat inputMat = Imgcodecs.imread("/sdcard/input.jpg");
        Mat outputMat = new Mat();

        // 调用 JNI 转灰度
        convertToGray(inputMat.getNativeObjAddr(), outputMat.getNativeObjAddr());

        // 显示图片
        ImageView imageView = findViewById(R.id.imageView);
        imageView.setImageBitmap(Utils.matToBitmap(outputMat));
    }
}

6. 配置 AndroidManifest.xml

确保权限:

复制代码
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

7. 运行项目
  1. 将一张彩色图片(如 input.jpg)放在设备的 /sdcard 目录下。
  2. 运行项目,可以看到图片被转换为灰度。

扩展功能

  • 添加更多OpenCV图像处理功能,如边缘检测、模糊处理等。
  • 实现视频实时处理功能,使用 CameraX 和 OpenCV 相结合。
相关推荐
网安蟹佬霸7 分钟前
蓝队防御实战:SIEM与SOAR构建安全运营中心(万字详解+实战配置)
android·安全·web安全·网络安全·网安
深蓝海拓15 分钟前
基于QtPy (PySide6) 的PLC-HMI工程实战记录(五)为当前动作画面的信号连接变量
网络·笔记·python·学习·pyqt
云贝教育-郑老师35 分钟前
Oracle 块清除(Block Cleanout):commit 之后,数据块里的“战场“谁来打扫?
数据库·学习·oracle
敢敢のwings1 小时前
世界模型与FlashWorld:从“在梦中学习“到秒级3D场景生成
android·学习·3d
那年窗外下的雪.1 小时前
AIDC 学习日志|第 14 天|MAC Flapping 与 EVPN 多归属分层排障
网络·git·学习·macos·github·spine
薛定e的猫咪2 小时前
(arXiv 2026)GLiBRL :可学习基函数的深度贝叶斯元强化学习 ----待补充
人工智能·深度学习·学习·算法·机器学习
sunshine22 girl2 小时前
Angular7,9,学习笔记一 创建项目,基本语法
笔记·学习
小雪崩2 小时前
嵌入式学习 day30:minilog
linux·c语言·学习
Dovis(誓平步青云)2 小时前
牛奶不能减成负数:冰箱库存的筛选、去重与不可变更新
android·java·开发语言
Awna2 小时前
MySQL 存储空间与索引运维实战:从空间排查到在线扩容
android·运维·mysql