首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

OpenCV for Android 查看 Canny 底層源碼:JNI 呼叫鏈追蹤與 sources/modules 目錄結構指南

     編輯:程式設計綜合問答

OpenCV Android SDK 中 Imgproc.Canny() 對應兩個 native 方法 Canny_0、Canny_1,開發者常困惑如何在 Eclipse/Android Studio 中跳轉至 C++ 實作。本文說明 JNI 呼叫鏈、opencv/sources/modules 目錄結構、以及三種查看源碼的實用路徑。

Java 層雙重載對應關係

// Java 包裝 (opencv/modules/java/generator/cpp/Imgproc.cpp 生成)
public static void Canny(Mat image, Mat edges, double threshold1, double threshold2) {
    Canny_1(image.nativeObj, edges.nativeObj, threshold1, threshold2);
}

public static void Canny(Mat image, Mat edges, double threshold1, double threshold2,
                         int apertureSize, boolean L2gradient) {
    Canny_0(image.nativeObj, edges.nativeObj, threshold1, threshold2, apertureSize, L2gradient);
}

// Native 宣告
private static native void Canny_0(long image_nativeObj, long edges_nativeObj,
                                   double threshold1, double threshold2,
                                   int apertureSize, boolean L2gradient);
private static native void Canny_1(long image_nativeObj, long edges_nativeObj,
                                   double threshold1, double threshold2);

三種查看 C++ 源碼的方法

方法一:直接閱讀 OpenCV 源碼倉庫 (最推薦)

  1. 下載完整源碼:github.com/opencv/opencv 或官網 opencv-4.x.x-src.zip。
  2. 核心實作位於:opencv/modules/imgproc/src/canny.cpp
  3. JNI 橋接層:opencv/modules/java/generator/cpp/Imgproc.cpp (自動生成)
  4. CMake 編譯腳本:opencv/modules/java/CMakeLists.txt

方法二:IDE 中配置 Source Attachment (Eclipse/Android Studio)


Eclipse:
1. 右鍵專案 → Properties → Java Build Path → Libraries
2. 展開 opencv-xxx.jar → Source attachment → Edit
3. 指向 opencv/sources 目錄 (或 modules/java 源碼目錄)

Android Studio:
1. File → Project Structure → Modules → Dependencies
2. 找到 opencv 模組 → 編輯 Source JAR/目錄路徑

注意:OpenCV Android SDK 預編譯 AAR/JAR 通常不包含 C++ 源碼,僅含 Java 包裝層。需手動關聯完整源碼目錄才能跳轉至 canny.cpp。

方法三:線上瀏覽 GitHub (零配置)

Canny 核心流程速覽 (canny.cpp 關鍵步驟)

  1. 輸入驗證:檢查 image.type() == CV_8UC1 (單通道 8 位)。
  2. Sobel 梯度計算:Sobel(src, dx, CV_16S, 1, 0, apertureSize)、Sobel(src, dy, CV_16S, 0, 1, apertureSize)。
  3. 幅值與方向:magnitude(dx, dy, mag)、phase(dx, dy, angle) (若 L2gradient 用 L2 範數)。
  4. 非極大值抑制:根據量化方向 (0°/45°/90°/135°) 比較鄰域像素。
  5. 雙閾值邊緣追蹤:threshold1 (低)、threshold2 (高),滯後閾值演算法連接強/弱邊緣。
  6. 輸出:edges.setTo(255, strong_edges)。

常見問題 FAQ

問題答案
為何有 Canny_0 和 Canny_1?對應 Java 端兩個重載:含/不含 apertureSize、L2gradient 參數。
Eclipse 跳轉只能看到 Java 包裝層?因為 AAR 內未打包 C++ 源碼,需關聯外部 sources 目錄。
如何修改 Canny 演算法?修改 canny.cpp 後需重新編譯 OpenCV 原生庫 (.so),並替換專案中的 jniLibs。
官方文件在哪裡?https://docs.opencv.org/ 搜尋 Canny,含完整參數說明與範例。

總結

OpenCV Android 版 Canny 透過 JNI 呼叫 modules/imgproc/src/canny.cpp 核心實作。查看源碼最直接方式是瀏覽 GitHub 線上倉庫或下載完整源碼關聯至 IDE。理解 Java 包裝層 → JNI 橋接層 → C++ 核心層 三層架構,有助於深度除錯、效能調優與演算法客製化。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved