Skip to content

Commit

Permalink
Merge pull request #3 from khoben/android-update
Browse files Browse the repository at this point in the history
Android update
  • Loading branch information
khoben committed Feb 29, 2020
2 parents dfbb2c3 + 31547dd commit d632470
Show file tree
Hide file tree
Showing 40 changed files with 1,593 additions and 530 deletions.
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Currently have PC and Android version (JNI).

## Built With

* CMake 3.6
* OpenCV 4.1 (PC and Android)
* CMake 3.6 / C++17
* OpenCV 4.2.0 (PC and Android)
* Android NDK 20

## Tests
Expand All @@ -35,6 +35,5 @@ Currently have PC and Android version (JNI).
</p>

## Known issues
* Unable to find multiple objects with same marker
* Sometimes it calculates incorrect object coordinates on tracking phase
* Sometimes it calculates incorrect object`s coordinates on tracking phase

2 changes: 2 additions & 0 deletions android/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@
/build
/captures
.externalNativeBuild
/cv42
/opencv*
4 changes: 4 additions & 0 deletions android/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# How to run
1) Download appreciate opencv version [(4.2.0)](https://sourceforge.net/projects/opencvlibrary/files/4.2.0/opencv-4.2.0-android-sdk.zip/download)
2) [Import](https://android.jlelse.eu/a-beginners-guide-to-setting-up-opencv-android-library-on-android-studio-19794e220f3c) opencv sdk as module
3) Try to build it
3 changes: 1 addition & 2 deletions android/app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
cmake_minimum_required(VERSION 3.6)


#SET(OpenCV_DIR D:/Android/OpenCV31/sdk/native/jni)
SET(OpenCV_DIR D:/Android/OpenCV-android-sdk/sdk/native/jni)
SET(OpenCV_DIR D:/Android/OpenCV42/sdk/native/jni)
find_package(OpenCV REQUIRED)
message(STATUS "opencv found: ${OpenCV_LIBS}")

Expand Down
5 changes: 3 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ android {
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags "-std=c++14 -frtti -fexceptions"
cppFlags "-std=c++17 -frtti -fexceptions"
//abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
//arguments "-DANDROID_STL=c++_shared"
}
Expand All @@ -27,6 +27,7 @@ android {
}
buildTypes {
release {
buildConfigField "Boolean", "DEBUG_MODE", "false"
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
Expand All @@ -45,5 +46,5 @@ dependencies {
testImplementation 'junit:junit:4.13-beta-3'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation project(path: ':opencv410')
implementation project(path: ':opencv42')
}
3 changes: 2 additions & 1 deletion android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
android:theme="@style/AppFullScreenTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity android:name=".MainActivity"
android:screenOrientation="landscape">
android:screenOrientation="landscape"
tools:ignore="LockedOrientationActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand Down
59 changes: 11 additions & 48 deletions android/app/src/main/cpp/android.cpp
Original file line number Diff line number Diff line change
@@ -1,75 +1,38 @@
#include "android.hpp"

AR *ar; // AR instance
Mat query; // query frame
int scale = 1; // initial scale
std::shared_ptr<AR> ar; // AR instance
const int maxFrameSize = 800; // maximum frame size
bool isTracked = false; // tracking status: false - not detected
int trackedId = -1; // id of detected marker

cv::Mat makeQueryMat(cv::Size size, int max_size, int &scale) {
int frame_max_size = std::max(size.width, size.height);
scale = 1;
while ((frame_max_size / scale) > max_size) {
scale *= 2;
}
return cv::Mat(size.height / scale, size.width / scale, CV_8UC1);
}

void init(Mat frame) {
// init AR instance
ar = new AR();
scale = 1;
query = makeQueryMat(frame.size(), maxFrameSize, scale);
if (!ar)
ar = std::make_shared<ARMarkerless>();
ar->init(frame.size(), maxFrameSize);
}

int addMarker(cv::Mat img) {
if (ar == nullptr)
if (!ar)
return -1;
// load marker images
// load marker image
ar->add(img);
return 0;
}

int process(Mat frame, Mat &out) {
if (ar == nullptr)
if (!ar)
return -1;
cv::Mat gray;

if (frame.empty())
return -1;
cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);
// frame.copyTo(gray);
if (isTracked) {
LOGD("CONTINUE..\n");
isTracked = ar->keepTracking(gray);
} else {
cv::resize(gray, query, query.size());
std::vector<QueryItem> result = ar->process(query);
if (!result.empty()) {
std::vector<cv::Point2f> objPose;
QueryItem r = result[0];
trackedId = r.imgId;
LOGD("MATCHED: IMG_ID: %d\n", r.imgId);
std::cout << "Matched: img_id:" << r.imgId << std::endl;
objPose = r.objPose;
objPose = CvUtils::scalePoints(objPose, scale);
std::cout << "Pose: " << objPose << " probability: " << r.probability << std::endl;
ar->startTracking(gray, objPose);
isTracked = true;
}
}
std::vector<QueryItem> result = ar->process(frame);
frame.copyTo(out);
if (isTracked) {
for (auto &r: result) {
cv::Scalar val(255);
ObjectPosition objPose = ar->getTrackingInstance()->objectPosition;
Boundary objPose = CvUtils::scalePoints(r.objPose, ar->getScale());
cv::line(out, objPose[3], objPose[0], val, 3);
for (int i = 0; i < 3; i++) {
line(out, objPose[i], objPose[i + 1], val, 3);
}
cv::Point center((objPose[0] + objPose[2]) / 2);

cv::putText(out, std::to_string(trackedId), center, FONT_HERSHEY_TRIPLEX, 6, val, 3);
cv::putText(out, std::to_string(r.imgId), center, FONT_HERSHEY_TRIPLEX, 6, val, 3);
}

return 0;
Expand Down
15 changes: 3 additions & 12 deletions android/app/src/main/cpp/android.hpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#ifndef AR_CORE_ANDROID_HPP
#define AR_CORE_ANDROID_HPP

#include "opencv2/opencv.hpp"
#include "AR/Ar.hpp"
#include "Utils/CvUtils.hpp"
#include <opencv2/opencv.hpp>
#include <AR/ARMarkerless.hpp>
#include <Utils/CvUtils.hpp>

using namespace cv;

Expand Down Expand Up @@ -46,15 +46,6 @@ using namespace cv;
printf(__VA_ARGS__);
#endif // ANDROID

/**
* @brief Make query resised frame
*
* @param size Size of source frame
* @param max_size Max size
* @param scale Initial scale
* @return cv::Mat Query-resized frame
*/
cv::Mat makeQueryMat(cv::Size size, int max_size, int &scale);

/**
* @brief Init AR instance
Expand Down
25 changes: 11 additions & 14 deletions android/app/src/main/cpp/native-lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,18 @@ Java_com_khoben_arcore_OpenCVJNI_init(JNIEnv *env, jclass type, jlong matAddrRgb

extern "C"
JNIEXPORT jint JNICALL
Java_com_khoben_arcore_OpenCVJNI_start(JNIEnv *env, jclass type, jlong matAddrRgba,
jlong matAddrGray) {
Java_com_khoben_arcore_OpenCVJNI_addMarker(JNIEnv *env, jclass type, jlong matAddrRgba) {

Mat& mRgb = *(Mat*)matAddrRgba;
addMarker(mRgb);
return 0;

}
extern "C"
JNIEXPORT jint JNICALL
Java_com_khoben_arcore_OpenCVJNI_process(JNIEnv *env, jclass clazz, jlong matAddrRgba,
jlong matAddrGray) {
Mat& mRgb = *(Mat*)matAddrRgba;
Mat& mGray = *(Mat*)matAddrGray;

int conv;
Expand All @@ -34,15 +42,4 @@ Java_com_khoben_arcore_OpenCVJNI_start(JNIEnv *env, jclass type, jlong matAddrRg
retVal = (jint)conv;

return retVal;

}

extern "C"
JNIEXPORT jint JNICALL
Java_com_khoben_arcore_OpenCVJNI_addMarker(JNIEnv *env, jclass type, jlong matAddrRgba) {

Mat& mRgb = *(Mat*)matAddrRgba;
addMarker(mRgb);
return 0;

}
}
8 changes: 3 additions & 5 deletions android/app/src/main/java/com/khoben/arcore/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,14 @@ protected void onCreate(Bundle savedInstanceState) {

javaCameraView = findViewById(R.id.java_camera_view);
javaCameraView.setVisibility(View.VISIBLE);
javaCameraView.setCameraPermissionGranted();
javaCameraView.setCvCameraViewListener(this);
}

private void loadMarkers() {
// load marker
// load markers
Mat mat_1 = UtilsJNI.loadMatFromDrawables(this, R.drawable.miku);
Mat mat_2 = UtilsJNI.loadMatFromDrawables(this, R.drawable.ar);
Mat mat_3 = UtilsJNI.loadMatFromDrawables(this, R.drawable.czech);
OpenCVJNI.addMarker(mat_2.getNativeObjAddr());
OpenCVJNI.addMarker(mat_3.getNativeObjAddr());
OpenCVJNI.addMarker(mat_1.getNativeObjAddr());
}
Expand Down Expand Up @@ -128,9 +127,8 @@ public void onCameraViewStopped() {

@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
Log.i(TAG, "on frame");
frame = inputFrame.rgba();
OpenCVJNI.start(frame.getNativeObjAddr(), processedFrame.getNativeObjAddr());
OpenCVJNI.process(frame.getNativeObjAddr(), processedFrame.getNativeObjAddr());
return processedFrame;
}
}
2 changes: 1 addition & 1 deletion android/app/src/main/java/com/khoben/arcore/OpenCVJNI.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.khoben.arcore;

public class OpenCVJNI {
public static native int start(long matAddrRgba, long matAddrGray);
public static native int process(long matAddrRgba, long matAddrGray);
public static native int init(long matAddrRgba);
public static native int addMarker(long matAddrRgba);
}
2 changes: 1 addition & 1 deletion android/settings.gradle
Original file line number Diff line number Diff line change
@@ -1 +1 @@
include ':app', ':opencv410'
include ':app', ':opencv42'
66 changes: 66 additions & 0 deletions src/AR/AR.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#ifndef AR_CORE_AR_HPP
#define AR_CORE_AR_HPP

#include "../Tracking/Tracker.hpp"
#include "../Detection/DetectMarkerless.hpp"

/**
* Base class AR
*/
class AR {
protected:
// scale factor for queryMat
float scale;
// scaled mat for querying
cv::Mat queryMat;
// masked mat for querying
cv::Mat maskedMat;
// size of queryMat (w x h)
cv::Size querySize;

// tracking instances
std::vector<std::pair<QueryItem, std::unique_ptr<Tracker>>> trackingItems;
// recognition instance
std::shared_ptr<Detect> recognitionInstance;

public:
/**
* @brief Initialize AR instance: set querying image size
*
* @param frameSize source frame size
* @param maxSize maximum size of querying image in pixels
* for one of sides
*/
virtual void init(const cv::Size &frameSize, int maxSize) = 0;

/**
* @brief Start recognition&tracking process
*
* @param frame Frame
* @return std::vector<QueryItem> Result
*/
virtual std::vector<QueryItem> process(const cv::Mat &frame) = 0;

/**
* @brief Add marker image
*
* @param img Marker image
* @return int
*/
virtual int add(const cv::Mat &img) = 0;

/**
* @brief Add marker image objects
*
* @param imgs marker images
* @return int
*/
virtual int addAll(const std::vector<cv::Mat> &imgs) = 0;

float getScale() {
return scale;
}
};


#endif //AR_CORE_AR_HPP

0 comments on commit d632470

Please sign in to comment.