Skip to content

Instantly share code, notes, and snippets.

@salehjg
Last active March 25, 2023 15:24
Show Gist options
  • Save salehjg/8bb920d457661b74069979594b8738d6 to your computer and use it in GitHub Desktop.
Save salehjg/8bb920d457661b74069979594b8738d6 to your computer and use it in GitHub Desktop.
Android Studio+NDK+OpenCV shared library (tested on Android Studio 2022.1, SDK 33, NDK 21, and Device API 26)
  1. Follow this gist to build OpenCV shared library for Android.
  2. Create a new project, Java, MinSDK API26.
  3. In Project Side Bar, right click on App and select New -> Folder -> JNI Folder.
  4. Check the Change Folder Location check box and rename the last part of the path from src/main/jni/ to src/main/jniLibs/ .
  5. Go to your OpenCV/01_ndk_outputs/sdk/native/libs source directory and select all the folders and copy them into jniLibs of your Android Studio project.
  6. It is assumed that your phone is a arm64-v8a.
  7. Open your app's build.gradle and add this to defaultConfig entry:
externalNativeBuild{
            cmake{
                cppFlags "-frtti -fexceptions"
                abiFilters 'arm64-v8a'
            }
        }
  1. Also, make sure that app's build.gradle, the android entry has this member (you can skip steps 3 and 4, create jniLibs manualy and copy this into build.gradle):
sourceSets {
        main {
            jni {
                srcDirs 'src/main/jni', 'src/main/jniLibs'
            }
        }
    }
  1. Copy opencv/01_ndk_outputs/sdk into the base directory of your Android Studio project and then rename the sdk into opencv.
  2. Inside the opencv directory, open build.gradle with a code editor.
  3. Edit compileSdkVersion, targetSdkVersion, and minSdkVersion to match your Android Studio project.
  4. Edit JavaVersion and change it to VERSION_1_8, otherwise your app will crash on startup.
  5. In Android Studio, change the Project Side Bar mode from Android to Project.
  6. Find the opencv directory and open local.properties and make sure the sdk.dir is set correctly.
  7. Find and open settings.gradle in the Project Side Bar on Project mode and append include ':opencv' to it and Sync the gradle script.
  8. Find and open app's build.gradle and add implementation project(path: ':opencv') to the dependencies entry and Sync the gradle script.
  9. Open activity_main.xml and copy this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:opencv="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <org.opencv.android.JavaCameraView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:visibility="gone"
        android:id="@+id/HelloOpenCvView"
        opencv:show_fps="true"
        opencv:camera_id="any" />

</LinearLayout>
  1. Open AndroidManifest.xml and add these outside the application entry:
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    <uses-feature android:name="android.hardware.camera.front" />
    <uses-feature android:name="android.hardware.camera.front.autofocus" />
  1. Open MainActivity.java and replace the content with:

public class MainActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener2 {
    private CameraBridgeViewBase mOpenCvCameraView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        System.loadLibrary("opencv_java3");
        Mat a = new Mat(100,200, CvType.CV_8UC1);
        Mat b = new Mat(100,200, CvType.CV_8UC1);

        getPermissions();

        mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.HelloOpenCvView);
        mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
        mOpenCvCameraView.setCvCameraViewListener(this);

    }

    private void getPermissions() {
        String[] requiredPermission = {
                android.Manifest.permission.CAMERA,
        };
        ActivityCompat.requestPermissions(MainActivity.this, requiredPermission, 100);
    }

    @Override
    public void onRequestPermissionsResult (int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults){
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (requestCode == 100) {

            boolean allPermission = true;
            for (int i = 0; i < grantResults.length-2; i++) {
                if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                    allPermission = false;
                }
            }
            if (allPermission) {
                Toast.makeText(this, "Perms granted.", Toast.LENGTH_SHORT).show();
                mOpenCvCameraView.enableView();
            } else {
                Toast.makeText(this, "Failed to get the perms.", Toast.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    public void onCameraViewStarted(int width, int height) {

    }

    @Override
    public void onCameraViewStopped() {

    }

    @Override
    public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
        Mat src = inputFrame.rgba();

        Mat gray = new Mat(src.rows(), src.cols(), src.type());
        Mat edges = new Mat(src.rows(), src.cols(), src.type());

        org.opencv.imgproc.Imgproc.cvtColor(src, gray, org.opencv.imgproc.Imgproc.COLOR_RGB2GRAY);
        org.opencv.imgproc.Imgproc.Canny(gray, edges, 100, 100*3);
        return edges;
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mOpenCvCameraView != null)
            mOpenCvCameraView.disableView();
    }

    public void onDestroy() {
        super.onDestroy();
        if (mOpenCvCameraView != null)
            mOpenCvCameraView.disableView();
    }
}
  1. Build the project.
  2. Connect your phone and run the app on the device.
  3. On the device (mine is API26) accept the permissions.
  4. Now you should be able to see the live camera feed with Canny algorithm applied.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment