{"id":25208275,"url":"https://github.com/1010code/android-opencv-sift","last_synced_at":"2025-10-12T10:18:03.709Z","repository":{"id":118675980,"uuid":"350368207","full_name":"1010code/android-OpenCV-SIFT","owner":"1010code","description":"Android OpenCV 4.5.1 + SIFT Tutorial","archived":false,"fork":false,"pushed_at":"2021-03-27T07:17:31.000Z","size":21852,"stargazers_count":2,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-28T21:41:30.253Z","etag":null,"topics":["android-opencv","gradle","opencv-sdk","sift-tutorial"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/1010code.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-03-22T14:11:49.000Z","updated_at":"2024-11-22T15:15:00.000Z","dependencies_parsed_at":null,"dependency_job_id":"e89b67db-cca1-4531-95b0-3ca47929f456","html_url":"https://github.com/1010code/android-OpenCV-SIFT","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/1010code/android-OpenCV-SIFT","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/1010code%2Fandroid-OpenCV-SIFT","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/1010code%2Fandroid-OpenCV-SIFT/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/1010code%2Fandroid-OpenCV-SIFT/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/1010code%2Fandroid-OpenCV-SIFT/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/1010code","download_url":"https://codeload.github.com/1010code/android-OpenCV-SIFT/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/1010code%2Fandroid-OpenCV-SIFT/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279011056,"owners_count":26084864,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-12T02:00:06.719Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android-opencv","gradle","opencv-sdk","sift-tutorial"],"created_at":"2025-02-10T12:19:13.563Z","updated_at":"2025-10-12T10:18:03.703Z","avatar_url":"https://github.com/1010code.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# android-OpenCV-SIFT\n此範例透過 Android Native C++ 與 OpenCV 4.5.1 來執行電腦視覺專案。將會以 2020 年開源的 SIFT 演算法來計算圖片的特徵點。\n\n![](./screenshot/img14.png)\n\n## YouTube Tutorial\n[\u003cimg src=\"./screenshot/cover.jpg\" width=\"550px\"\u003e](https://youtu.be/rIu-mHX_MXM)\n\n## Step 1: 建立專案\n開啟 Android Studio 建立一個以 Android Native C++ 為基底的專案。這一個選項他會建構一個 C/C++ 環境能夠透過 JNI (Java Native Interface) ，執行呼叫 C/C++ 語言的程式。\n\n![](./screenshot/img01.png)\n![](./screenshot/img02.png)\n\n建立完成後我們可以將專案視窗改成 `Project` 的資料夾模式，以利後續操作。\n\n![](./screenshot/img03.png)\n\n## Step 2: 下載 OpenCV SDK\n進入 OpenCV [官網](https://opencv.org/releases/) 挑選版號本(此範例採用4.5.1)並下載 Android 版本。下載後進入 SDK 資料夾，找到 java 資料夾並將他改名成 `openCVLibrary451` (此動作是為了等等要匯入此資料夾，先將它命名完成)。說個題外話之前的版本匯入 java 資料夾時會系統自動將他改名成相對應版本號的 library，個人覺得是 Bug 因此要手動處理名稱較麻煩(未來應該會解決)。\n\n![](./screenshot/img04.png)\n\n## Step 3: 匯入 OpenCV SDK\n點選上方工具列 File \u003e New \u003e Import Module。選擇剛剛第二步驟已經改名後的 `openCVLibrary451` 資料夾，完成後點選下一步並按完成匯入。\n\n![](./screenshot/img05.png)\n\n匯入完成後可以看到 `openCVLibrary451` 在主目錄資料夾中，但是我們匯入的是要當作 module 使用並非 APP(下圖紅框)。因此我們要手動將它改成 library。(之前版本沒這問題4.3版本以後的問題有點多，但是為了展示最新版的SIFT API不得不使用)\n\n![](./screenshot/img06.png)\n\n修改 `openCVLibrary451` 的 build.gradle。把 OpenCV 從 application 改成 library 才能 import。修改 `apply plugin: 'com.android.application'` ，把 `application` 改成 `library`。並且將 applicationId 刪除掉。刪除以下:\n\n```\ndefaultConfig {\n    applicationId \"org.opencv\n}\n```\n\n修改後build.gradle(openCVLibrary451)如下:\n\n![](./screenshot/img07.png)\n\n## Step 4: dependencies加入OpenCV\n點選File \u003e Project Structure ，進入 Project Structure 畫面，點選左邊 Dependencies 選項，Modules 選 app ，點 [+] 選 `3 Module Dependency`，如下圖:\n\n![](./screenshot/img08.png)\n\n點選剛剛稍早匯入的 `openCVLibrary451` module。點選 ok 後我們的專案就能成功使用 OpenCV 的函式庫囉。\n\n![](./screenshot/img09.png)\n\n我們可以開啟 build.gradle(app) 來查看 `openCVLibrary451` 是否已經成功被匯入。\n\n![](./screenshot/img10.png)\n\n## Step 5: 新增Native Libraries\n將最早下載的 `\\OpenCV-android-sdk\\sdk\\native\\libs`中的 `armeabi-v7a` 與 `x86` 檔案複製到 `\\app\\libs` 下，常見通常都需要這兩個 CPU 類型。前者是現在手機目前主流架構 arm7，後者是給開發者在模擬器上除錯執行用。直到目前為止，Android 共有7種不同的 CPU 分別為 ARMv5，ARMv7（從2010年起）x86（從2011年起）MIPS（從2012年起）ARMv8，MIPS64 和 x86_64（從2014年起）。為了支援這些 CPU 我們就需要包相對應的 so 檔進 apk 裡。\n\n![](./screenshot/img11.png)\n\n接下來指定 `jniLibs` 路徑，開啟 app 的 build.gradle，增加:\n\n```\nsourceSets{\n    main {\n        jniLibs.srcDirs = ['libs']\n    }\n}\n```\n\n![](./screenshot/img12.png)\n\n## activity_main.xml\n加入一個 `ImageView` 顯示 SIFT 特徵選取後的定位點結果。\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003candroidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\".MainActivity\"\u003e\n\n    \u003cTextView\n        android:id=\"@+id/sample_text\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"Hello World!\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintLeft_toLeftOf=\"parent\"\n        app:layout_constraintRight_toRightOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\" /\u003e\n\n    \u003cImageView\n        android:id=\"@+id/imageView\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        app:layout_constraintBottom_toTopOf=\"@+id/sample_text\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintHorizontal_bias=\"0.498\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        app:layout_constraintVertical_bias=\"0.641\"\n        app:srcCompat=\"@drawable/ic_launcher_background\" /\u003e\n\n\u003c/androidx.constraintlayout.widget.ConstraintLayout\u003e\n```\n\n## 完整 MainActivity.java\n變數 `inputImage` 可以隨意替換 drawable 資料夾中的任一圖片。下一步驟教各位如何開啟資料夾並放自己的相片。\n\n```java\nimport androidx.appcompat.app.AppCompatActivity;\n\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\nimport android.os.Bundle;\nimport android.widget.ImageView;\nimport android.widget.TextView;\n\nimport org.opencv.android.Utils;\nimport org.opencv.core.Mat;\nimport org.opencv.core.MatOfKeyPoint;\nimport org.opencv.features2d.Features2d;\nimport org.opencv.features2d.SIFT;\nimport org.opencv.imgproc.Imgproc;\n\npublic class MainActivity extends AppCompatActivity {\n\n    // Used to load the 'native-lib' library on application startup.\n    static {\n        System.loadLibrary(\"native-lib\");\n        System.loadLibrary(\"opencv_java4\");\n    }\n\n    private ImageView imageView;\n    // make bitmap from image resource\n    private Bitmap inputImage; \n    private SIFT sift = SIFT.create();\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_main);\n\n        // Example of a call to a native method\n        TextView tv = findViewById(R.id.sample_text);\n        tv.setText(stringFromJNI());\n\n        inputImage = BitmapFactory.decodeResource(getResources(), R.drawable.coca_cola);\n        imageView = (ImageView) this.findViewById(R.id.imageView);\n        sift();\n    }\n    public void sift() {\n        Mat rgba = new Mat();\n        Utils.bitmapToMat(inputImage, rgba);\n        MatOfKeyPoint keyPoints = new MatOfKeyPoint();\n        Imgproc.cvtColor(rgba, rgba, Imgproc.COLOR_RGBA2GRAY);\n        sift.detect(rgba, keyPoints);\n        Features2d.drawKeypoints(rgba, keyPoints, rgba);\n        Utils.matToBitmap(rgba, inputImage);\n        imageView.setImageBitmap(inputImage);\n    }\n\n    /**\n     * A native method that is implemented by the 'native-lib' native library,\n     * which is packaged with this application.\n     */\n    public native String stringFromJNI();\n}\n```\n\n## 加入測試圖片\n打開 app \u003e src \u003e main \u003e res \u003e drawable ，將測試圖片放到此資料夾中。\n\n![](./screenshot/img13.png)\n\n## 錯誤排除\n\n如果編譯執行後發生以下錯誤訊息:\n\n\u003e java.lang.UnsatisfiedLinkError: dlopen failed: library \"libc++_shared.so\" not found\n\n解決方式: 在build.gradle(app) 的 cmake 增加:\n\n```\ncmake {\n    arguments \"-DANDROID_STL=c++_shared\"\n}\n```\n\n## Reference\n- [Android studio載入OpenCV 4.3 module](https://hjwang520.pixnet.net/blog/post/404969512-android-studio%E8%BC%89%E5%85%A5opencv-4.3-module)\n- [How to configure OpenCV in Android Studio 4.1 or higher](https://www.youtube.com/watch?v=-0Yx1UzozzQ)\n- [OpenCV Android Installation + SIFT Tutorial 2016 EASY](https://www.youtube.com/watch?v=cLK9CjQ-pNI)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F1010code%2Fandroid-opencv-sift","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F1010code%2Fandroid-opencv-sift","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F1010code%2Fandroid-opencv-sift/lists"}