Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update dependencies #5

Merged
merged 7 commits into from
Feb 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 0 additions & 1 deletion .gitattributes

This file was deleted.

14 changes: 6 additions & 8 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,17 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: set up JDK 11
uses: actions/setup-java@v2
- uses: actions/checkout@v4
- name: set up JDK
uses: actions/setup-java@v4
with:
java-version: '11'
distribution: 'adopt'
java-version: '21'
distribution: 'temurin'
cache: gradle

- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew assembleDebug
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
with:
name: APK
path: app/build/outputs/apk/debug/
13 changes: 5 additions & 8 deletions .github/workflows/release_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,15 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: set up JDK 11
uses: actions/setup-java@v2
- name: set up JDK
uses: actions/setup-java@v4
with:
java-version: '11'
distribution: 'adopt'
java-version: '21'
distribution: 'temurin'
cache: gradle

- name: grant execute permission for gradlew
run: chmod +x gradlew

- name: Build APK with Gradle
run: ./gradlew assembleDebug

Expand Down
695 changes: 674 additions & 21 deletions LICENSE

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Augmented Reality Template Matching for >= Android 4 #
# Augmented Reality Template Matching using OpenCV 4 for Android
## Approach: Sum of squared differences (SSD)
[![Android CI](https://github.com/michaeltroger/template-matching-android/actions/workflows/android.yml/badge.svg)](https://github.com/michaeltroger/template-matching-android/actions/workflows/android.yml)

Attention: This app was created in 2016. I was a beginner to Android development and Computer Vision back then.
So don't expect a perfect code please. In 2021 I updated the project to build with the latest Android Studio (2020.3.1), updated most dependencies and converted it to Kotlin, while the business logic remained unchanged.
Attention: This app was created in 2016. I was a beginner to Android development and Computer Vision back then. So don't expect a perfect code please. Over the years I updated the dependencies and converted it to Kotlin, while the business logic remained unchanged.

Note: Originally I targeted min SDK 15 (Android 4), more architectures ("mips", "mips64", "armeabi") and OpenCV 3 with this project. Nowadays the repo uses newer versions. If you need to support older devices, then you can look back in the repo's Git history (app version 1.3 / Git tag 4)

<img src="/screenshots/demo.gif" alt="Augmented Reality template matching" width="800px"/>
Copyright of the logo: Hogeschool PXL
Expand All @@ -15,9 +16,8 @@ Copyright of the logo: Hogeschool PXL
* More computer vision projects at https://michaeltroger.com/computervision/

### How do I get set up? ###
* IDE: Android Studio (tested with 2020.3.1)
* IDE: Android Studio (tested with 2023.3.1)
* Android SDK
* Dependencies: OpenCV 3 library (included) [License](/opencv-3-4-15/LICENSE)
* Template image location: res/drawable - Image is referenced in MainActivity

### Test image ###
Expand Down
34 changes: 15 additions & 19 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,41 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'

android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
namespace "com.michaeltroger.templatematching"
compileSdk 34

defaultConfig {
applicationId "com.michaeltroger.templatematching"
minSdkVersion 15
targetSdkVersion 30
versionCode 4
versionName "1.3"
minSdkVersion 21
targetSdkVersion 34
versionCode 5
versionName "1.4"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = "11"
}

splits {
abi {
enable true
reset()
include "x86", "x86_64", "mips", "mips64", "armeabi", "armeabi-v7a", "arm64-v8a"
include "x86", "x86_64", "armeabi-v7a", "arm64-v8a"
universalApk true
}
}
}

kotlin.jvmToolchain(java_version)

dependencies {
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.activity:activity-ktx:1.3.1'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation project(':opencv-3-4-15')
implementation 'androidx.core:core-ktx:1.12.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.activity:activity-ktx:1.8.2'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'org.opencv:opencv:4.9.0'
}
repositories {
mavenCentral()
Expand Down
17 changes: 6 additions & 11 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.michaeltroger.templatematching">
<manifest xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front.autofocus" android:required="false"/>
<supports-screens android:resizeable="true"
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:anyDensity="true" />
<application
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
<activity android:name="com.michaeltroger.templatematching.MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar" >
<activity android:name=".MainActivity"
android:screenOrientation="landscape"
android:configChanges="keyboardHidden|orientation">
android:exported="true"
tools:ignore="DiscouragedApi">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,66 +30,28 @@ class MainActivity : ComponentActivity(), CvCameraViewListener2 {
/**
* the result matrix
*/
var result: Mat? = null
private var result: Mat? = null

/**
* the camera image
*/
var img: Mat? = null
private var img: Mat? = null

/**
* the template image used for template matching
* or for copying into the camera view
*/
var templ: Mat? = null
private var templ: Mat? = null

/**
* the crop rectangle with the size of the template image
*/
var rect: Rect? = null
private var rect: Rect? = null

/**
* selected area is the camera preview cut to the crop rectangle
*/
var selectedArea: Mat? = null
private val mLoaderCallback: BaseLoaderCallback = object : BaseLoaderCallback(this) {
override fun onManagerConnected(status: Int) {
when (status) {
SUCCESS -> {
Log.i(TAG, "OpenCV loaded successfully")

// load the specified image from file system in bgr color
var bgr: Mat? = null
try {
bgr = Utils.loadResource(
applicationContext,
TEMPLATE_IMAGE,
Imgcodecs.CV_LOAD_IMAGE_COLOR
)
} catch (e: IOException) {
e.printStackTrace()
}

// convert the image to rgba
templ = Mat()
Imgproc.cvtColor(bgr, templ, Imgproc.COLOR_BGR2GRAY) //Imgproc.COLOR_BGR2RGBA);

// Imgproc.Canny(templ, templ, 50.0, 200.0);

// init the crop rectangle, necessary for copying the image to the camera view
rect = Rect(0, 0, templ!!.width(), templ!!.height())

// init the result matrix
result = Mat()
img = Mat()
mOpenCvCameraView!!.enableView()
}
else -> {
super.onManagerConnected(status)
}
}
}
}

private val requestPermissionLauncher =
registerForActivityResult(
Expand All @@ -111,12 +73,13 @@ class MainActivity : ComponentActivity(), CvCameraViewListener2 {
}
}

fun onPermissionGranted() {
private fun onPermissionGranted() {
if (FIXED_FRAME_SIZE) {
mOpenCvCameraView!!.setMaxFrameSize(FRAME_SIZE_WIDTH, FRAME_SIZE_HEIGHT)
}
mOpenCvCameraView!!.visibility = SurfaceView.VISIBLE
mOpenCvCameraView!!.setCvCameraViewListener(this)
mOpenCvCameraView!!.setCameraPermissionGranted()
}

/** Called when the activity is first created. */
Expand All @@ -138,13 +101,35 @@ class MainActivity : ComponentActivity(), CvCameraViewListener2 {

public override fun onResume() {
super.onResume()
if (!OpenCVLoader.initDebug()) {
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization")
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION, this, mLoaderCallback)
} else {
Log.d(TAG, "OpenCV library found inside package. Using it!")
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS)
OpenCVLoader.initLocal()

Log.i(TAG, "OpenCV loaded successfully")

// load the specified image from file system in bgr color
var bgr: Mat? = null
try {
bgr = Utils.loadResource(
applicationContext,
TEMPLATE_IMAGE,
Imgcodecs.IMREAD_COLOR
)
} catch (e: IOException) {
e.printStackTrace()
}

// convert the image to rgba
templ = Mat()
Imgproc.cvtColor(bgr, templ, Imgproc.COLOR_BGR2GRAY) //Imgproc.COLOR_BGR2RGBA);

// Imgproc.Canny(templ, templ, 50.0, 200.0);

// init the crop rectangle, necessary for copying the image to the camera view
rect = Rect(0, 0, templ!!.width(), templ!!.height())

// init the result matrix
result = Mat()
img = Mat()
mOpenCvCameraView!!.enableView()
}

public override fun onDestroy() {
Expand Down Expand Up @@ -208,7 +193,7 @@ class MainActivity : ComponentActivity(), CvCameraViewListener2 {
/**
* the template image to use
*/
private const val TEMPLATE_IMAGE = R.drawable.logo
private val TEMPLATE_IMAGE = R.drawable.logo

/**
* frame size width
Expand Down
1 change: 0 additions & 1 deletion app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<FrameLayout 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" >
Expand Down
10 changes: 0 additions & 10 deletions app/src/main/res/menu/menu_main.xml

This file was deleted.

9 changes: 0 additions & 9 deletions app/src/main/res/values-v21/styles.xml

This file was deleted.

6 changes: 0 additions & 6 deletions app/src/main/res/values-w820dp/dimens.xml

This file was deleted.

6 changes: 0 additions & 6 deletions app/src/main/res/values/dimens.xml

This file was deleted.

1 change: 0 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
<resources>
<string name="app_name">Template matching</string>
<string name="action_settings">Settings</string>
</resources>
15 changes: 2 additions & 13 deletions app/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@
<resources>

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>

<style name="AppTheme.NoActionBar">
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
</style>

<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />

<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />

</resources>
Loading