OpenCV 核心由 C/C++ 編寫,為何能在 Android (Java/Kotlin) 專案中直接呼叫?本文揭示 JNI (Java Native Interface) 封裝機制、預編譯 .so 動態庫、Java 包裝層自動生成流程,並提供三層級源碼查找路徑:Java 包裝層 → JNI 橋接層 → C++ 核心演算法層。
+------------------------+ JNI Call +--------------------------+ | Android App (Java) | -----------------> | OpenCV Java Wrapper | | Imgproc.Canny(...) | | (auto-generated) | +------------------------+ +--------------------------+ | JNIEXPORT / JNICALL v +------------------------+ JNI Bridge +--------------------------+ | libopencv_java4.so | <----------------- | JNI Bridge (Cpp) | | (prebuilt .so) | RegisterNatives | (modules/java/gen/...) | +------------------------+ +--------------------------+ | Internal Call v +------------------------+ Core Impl +--------------------------+ | libopencv_imgproc.so | -----------------> | C++ Core Algorithm | | libopencv_core.so | | (modules/imgproc/src/) | +------------------------+ +--------------------------+
opencv/modules/java/generator/,透過 Python 腳本解析 C++ 標頭檔自動生成 Imgproc.java、Mat.java 等。native 方法宣告、static { System.loadLibrary("opencv_java4"); } 載入 .so。opencv/modules/java/generator/cpp/Imgproc.cpp (自動生成)。jlong (Java) ↔ Mat* (C++) 指標轉換、jboolean ↔ bool、例外轉換 cv::Exception → Java Exception。JNI_OnLoad 呼叫 RegisterNatives 綁定 Java native 方法與 C++ 函數指標。opencv/modules//src/ ,如 imgproc/src/canny.cpp、core/src/mat.cpp。// Android Studio / Eclipse
// 滑鼠懸停 Imgproc.Canny → Ctrl+B / F3
// 開啟 Imgproc.java,看到:
public static native void Canny_0(long image_nativeObj, ...);
opencv-4.x.x-src.zip 解壓。opencv/sources 根目錄。Imgproc.java 的 native 方法上跳轉,即可進入 modules/java/generator/cpp/Imgproc.cpp。cv::Canny。opencv/sources/modules/imgproc/src/canny.cpp。| 問題 | 答案 |
|---|---|
| 為什麼 Eclipse 導入的 opencv-library 只有 .class 沒有 .java? | 預編譯 AAR/JAR 可能已移除源碼,需手動關聯 sources 目錄或下載 opencv-src.jar。 |
| 如何修改 C++ 演算法並重新編譯給 Android 用? | 修改 modules/xxx/src/xxx.cpp → 用 CMake + Android NDK 編譯 libopencv_java4.so → 替換專案 jniLibs/arm64-v8a/ 下的 .so。 |
| Java 層的 Mat 物件如何對應 C++ cv::Mat? | Java Mat.nativeObj 存儲 C++ cv::Mat* 指標 (jlong),JNI 層透過 reinterpret_cast 互轉。 |
| 官方文件在哪? | docs.opencv.org,含完整模組、類別、方法參數說明。 |
ndk-stack 解析 tombstone,定位到具體 C++ 檔案行號。-DBUILD_opencv_imgproc=ON) 大幅縮減 .so 體積。OpenCV for Android 透過 自動生成的 Java 包裝層 + JNI 橋接層 + 預編譯 .so 將 C++ 核心能力暴露給 Java/Kotlin。查找源碼關鍵在於「下載完整源碼 → IDE 關聯 sources 目錄 → 三層跳轉」。掌握此架構,即可從 API 使用者進階為庫定制者與效能調優專家。