Skip to content

Repository files navigation

CvCamera-Mobile

A production-shaped OpenCV 4 camera template for Android. Camera2 preview, a native C++/JNI bridge, and every feature in its own pluggable file.

MIT OpenCV Kotlin JDK Gradle AGP minSdk

🚀 Android CI 🚀 Build and Release pre-commit.ci status CodeFactor snyk-security Conventional Commits

Live camera preview with the FPS overlay Bottom bar menu Effect picker

What this is

A barebones but complete starting point for OpenCV 4.x on Android. It wires up a live Camera2 preview through OpenCV's JavaCamera2View, adds an NDK bridge so the same frames can be processed in C++ via JNI, and keeps every user-facing capability in its own file.

The last part is the point: the app doubles as a template. Each feature is a CameraFeature registered on one line, so the project can be reduced to a bare preview or extended without touching unrelated code.

Examples

Three apps with the same UI, one per integration style. Everything shared lives in the camera-ui library: the camera view, the bottom bar, the dialogs and the feature framework. Each app supplies only its own effect implementations, which is the part that differs by language.

Module Language Effects implemented in Effect count
app/ Kotlin Mat extension functions over the OpenCV Java bindings 17
java/ Java OpenCV Java bindings, no Kotlin in this app's sources 11
cpp/ Kotlin plus C++ Native cv:: calls over JNI, only the Mat address crosses 11

app/ additionally has Haar cascade face detection. Build any of them with ./gradlew :app:installDebug, :java:installDebug or :cpp:installDebug.

Each app is a thin subclass of CameraScreenActivity that names its effects:

class MainActivity : CameraScreenActivity() {
    override fun createFeatures(): List<CameraFeature> =
        listOf(
            FilterPicker(this, KotlinEffects.all()),
            FaceDetection(this),
        ) + defaultFeatures()
}

defaultFeatures() supplies torch, canvas scaling, the FPS overlay, resolution selection, shutter feedback, EXIF orientation and rotating control icons, so a new example gets the whole UI for free.

Camera features

Feature File Notes
Effect picker features/FilterPicker.kt 16 OpenCV effects, "No Effect" default, applied per frame
Face detection features/FaceDetection.kt Haar cascade, boxes drawn on the frame
Resolution picker features/ResolutionPicker.kt Every supported size, with aspect ratio and megapixels
Canvas fit / fill features/CanvasScaleControl.kt Letterbox or centre-crop, no camera restart
Flash torch features/TorchControl.kt Availability-checked per camera
FPS overlay features/FpsOverlayControl.kt Tinted chip, toggleable
Shutter flash features/ShutterEffect.kt Flash plus the system shutter sound
Photo orientation features/PhotoOrientation.kt Writes the EXIF orientation tag
Rotating controls features/ControlsRotator.kt Icons rotate, the bar stays at the bottom

Also included: front/back switching and capture to MediaStore.

Adding or removing a feature

Features are registered in a single list in MainActivity:

private val features: List<CameraFeature> by lazy {
    listOf(
        FilterPicker(this),
        FaceDetection(this),
        ResolutionPicker(this, binding.CvCamera),
        // ...
    )
}

The list order is also the frame-processing order, so effects run before face boxes are drawn on top. A new capability means a new file implementing CameraFeature plus one line here. Dropping a capability means deleting its file and its line.

CameraFeature provides attach/detach, onResume/onPause, onMenuItemSelected, processFrame, onCameraSwitched, onPhotoCaptureStarted and onPhotoSaved, all optional.

Getting started

  1. Install Android Studio.

  2. Install the NDK and CMake.

  3. Install JDK 21.

  4. Clone the repository, then fetch the OpenCV SDK:

    ./setupOpenCV_4x.sh

    This downloads the OpenCV 4.14.0 Android SDK, verifies its SHA-256, extracts it to opencvsdk4140/, and applies the patches in patches/. Re-running it on a prepared SDK is a no-op.

    To do it by hand instead: download the OpenCV 4.14.0 Android release, unzip it beside the project, rename OpenCV-android-sdk to opencvsdk4140, and adjust the path in settings.gradle.kts if you put it elsewhere.

  5. Sync Gradle and run on a device:

    ./gradlew installDebug

Running without a device

The Android emulator's virtualscene back camera renders a 3D room, which is enough to exercise the preview, effects and capture:

emulator -avd <name> -camera-back virtualscene -no-snapshot-load
./gradlew installDebug
adb shell pm grant com.os.cvCamera android.permission.CAMERA
adb shell am start -n com.os.cvCamera/.MainActivity

-no-snapshot-load matters: loading a snapshot written by a different GPU backend crashes the emulator with "change of renderer detected".

Development

./gradlew spotlessApply                      # format (ktlint)
./gradlew spotlessCheck assembleDebug \
          :app:lintDebug :app:testDebugUnitTest   # what CI runs
  • Version catalog: every dependency and SDK level lives in gradle/libs.versions.toml.
  • Kotlin DSL: all build scripts are .kts.
  • Spotless + ktlint: enforced in CI.
  • Timber: logging, debug builds only.
  • Conventional commits: enforced by convention; cliff.toml drives the changelog.

CvCheckUnitTest asserts the linked OpenCV version, which is the guard that the SDK swap in setupOpenCV_4x.sh actually took effect.

Keywords

Kotlin, OpenCV 4, Android, Android Studio, Camera2, NDK, JNI, C++, Version Catalog, Kotlin DSL, Spotless, Material 3

About

Using OpenCv's Android Camera2(JavaCamera2View) with OpenCV 4.10.0-4.14.0

Topics

Resources

Code of conduct

Security policy

Stars

51 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages