├── LICENSE
├── Presentation.pdf
├── README.md
├── app
├── .gitignore
├── app.iml
├── build.gradle
├── build
│ └── generated
│ │ └── source
│ │ └── buildConfig
│ │ └── debug
│ │ └── org
│ │ └── med
│ │ └── darknetandroid
│ │ └── BuildConfig.java
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── org
│ │ └── med
│ │ └── darknetandroid
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ ├── labels.txt
│ │ ├── yolov2-tiny.cfg
│ │ └── yolov3-tiny.cfg
│ ├── java
│ │ └── org
│ │ │ └── med
│ │ │ └── darknetandroid
│ │ │ ├── CameraActivity.java
│ │ │ └── WelcomeActivity.java
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── ic_launcher_background.xml
│ │ ├── logo.png
│ │ ├── toolbar_logo.png
│ │ └── welcome.jpeg
│ │ ├── layout
│ │ ├── activity_main.xml
│ │ └── activity_welcome.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── org
│ └── med
│ └── darknetandroid
│ └── ExampleUnitTest.java
├── build.gradle
├── darknetandroid.iml
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── local.properties
└── settings.gradle
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Matteo Medioli
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Presentation.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matteomedioli/AndroidObjectDetection/1d38b178e1aae598d8556d288bd1659e9e8ae3ea/Presentation.pdf
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Android Object Detection - OpenCV and YOLO
2 |
3 |
4 |
5 |
6 |
7 | Real time object detection Android application using OpenCV 4.1 and YOLO.
8 |
9 |
10 | Author: Matteo Medioli
11 |
12 |
13 | YOLO: https://pjreddie.com/darknet/yolo/
14 |
15 |
16 | ## 1.Import OpenCV 4.1 Module in AndroidStudio 3.4.1
17 | 1) Dowload OpenCV SDK from https://sourceforge.net/projects/opencvlibrary/files/4.1.0/opencv-4.1.0-android-sdk.zip/download
18 | 2) Clone this project.
19 | 3) Open Android Studio and import this project.
20 | 4) Build project.
21 | 5) From AndroidStudio top-menù select **New -> Import Module** and select your path to OpenCV sdk folder (i.e */where_opencv_saved/OpenCV-android-sdk/sdk*) and rename module as OpenCV.
22 | 6) After load OpenCV module, re-build project.
23 |
24 | ## 2.Add OpenCV dependecies to your application
25 | After OpenCV module import:
26 | 1) From AndroidStudio top-menù select **File -> Project Structure**
27 | 2) Navigate to Dependencies and click on **app**. On the right panel there's a plus button **+** for add Dependency. Click on it and choose **Module Dependecy**.
28 | 3) Select **OpenCV** module loaded before.
29 | 4) Click Ok and Apply changes.
30 | 5) Build project.
31 |
32 | ## 3.How detection works: CameraActivity.java
33 | This activity is the core of application and it implements *org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2*.
34 | It has 2 main private instance variable: a **net** (*org.opencv.dnn.Net*) and a **cameraView** (*org.opencv.android.CameraBridgeViewBase*).
35 | Basically has three main features:
36 |
37 | #### a) Load Network
38 | Load convolutional net from *\*.cfg* and *\*.weights* files and read *labels name* (COCO Dataset) in assets folder when calls onCameraViewStarted() using **Dnn.readNetFromDarknet(String path_cfg, String path_weights)**.
39 | **NOTE**: this repo doesn't contain weights file. You have to download it from YOLO site.
40 |
41 |
42 | #### b) Detection from camera preview
43 | Iteratively generate a frame from CameraBridgeViewBase preview and analize it as an image. Real time detection and the frames flow generation is managed by **onCameraFrame(CvCameraViewFrame inputFrame)**.
44 | Preview frame is translate in a Mat matrix and set as input for **Dnn.blobFromImage(frame, scaleFactor, frame_size, mean, true, false)** to preprocess frames. Note that **frame_size** is 416x416 for YOLO Model (you can find input dimension in *\*.cfg* file). We can change the size by adding or subtracting by a factor of 32. Reducing the framesize increases the performance but worsens the accuracy.
45 | The detection phase is implemented by **net.forward(List\ results, List\ outNames)** that runs forward pass to compute output of layer with name *outName*. In *results* the method writes all detections in preview frame as Mat objects.
46 | Theese Mat instances contain all information such as positions and labels of detected objects.
47 |
48 |
49 | #### c) Draw bounding-box and labelling
50 | Performing **Non Maximum Suppression** by YOLO, in **List\ results** are stored all coordinates of optimal bounding boxes
51 | (the first 4 numbers are [*center_x, center_y, width, height*], followed by all class probabilities). *classId* is the corresponding index for label of detection in COCO Dataset list *className*.
52 |
53 | ## TO DO
54 | - [ ] Full screen JavaCameraView portrait mode
55 | - [ ] Speed up JavaCameraView
56 | - [ ] Add model chioce
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | generateDebugSources
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 29
5 | buildToolsVersion "29.0.0"
6 | defaultConfig {
7 | applicationId "org.med.darknetandroid"
8 | minSdkVersion 26
9 | targetSdkVersion 29
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | implementation fileTree(dir: 'libs', include: ['*.jar'])
24 | implementation 'androidx.appcompat:appcompat:1.0.2'
25 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
26 | testImplementation 'junit:junit:4.12'
27 | androidTestImplementation 'androidx.test:runner:1.2.0'
28 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
29 | }
30 |
--------------------------------------------------------------------------------
/app/build/generated/source/buildConfig/debug/org/med/darknetandroid/BuildConfig.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Automatically generated file. DO NOT MODIFY
3 | */
4 | package org.med.darknetandroid;
5 |
6 | public final class BuildConfig {
7 | public static final boolean DEBUG = Boolean.parseBoolean("true");
8 | public static final String APPLICATION_ID = "org.med.darknetandroid";
9 | public static final String BUILD_TYPE = "debug";
10 | public static final String FLAVOR = "";
11 | public static final int VERSION_CODE = 1;
12 | public static final String VERSION_NAME = "1.0";
13 | }
14 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/org/med/darknetandroid/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package org.med.darknetandroid;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.InstrumentationRegistry;
6 | import androidx.test.runner.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getTargetContext();
24 |
25 | assertEquals("org.med.darknetandroid", appContext.getPackageName());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
11 |
12 |
13 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/assets/labels.txt:
--------------------------------------------------------------------------------
1 | person
2 | bicycle
3 | car
4 | motorbike
5 | aeroplane
6 | bus
7 | train
8 | truck
9 | boat
10 | traffic light
11 | fire hydrant
12 | stop sign
13 | parking meter
14 | bench
15 | bird
16 | cat
17 | dog
18 | horse
19 | sheep
20 | cow
21 | elephant
22 | bear
23 | zebra
24 | giraffe
25 | backpack
26 | umbrella
27 | handbag
28 | tie
29 | suitcase
30 | frisbee
31 | skis
32 | snowboard
33 | sports ball
34 | kite
35 | baseball bat
36 | baseball glove
37 | skateboard
38 | surfboard
39 | tennis racket
40 | bottle
41 | wine glass
42 | cup
43 | fork
44 | knife
45 | spoon
46 | bowl
47 | banana
48 | apple
49 | sandwich
50 | orange
51 | broccoli
52 | carrot
53 | hot dog
54 | pizza
55 | donut
56 | cake
57 | chair
58 | sofa
59 | pottedplant
60 | bed
61 | diningtable
62 | toilet
63 | tvmonitor
64 | laptop
65 | mouse
66 | remote
67 | keyboard
68 | cell phone
69 | microwave
70 | oven
71 | toaster
72 | sink
73 | refrigerator
74 | book
75 | clock
76 | vase
77 | scissors
78 | teddy bear
79 | hair drier
80 | toothbrush
81 |
--------------------------------------------------------------------------------
/app/src/main/assets/yolov2-tiny.cfg:
--------------------------------------------------------------------------------
1 | [net]
2 | # Testing
3 | batch=1
4 | subdivisions=1
5 | # Training
6 | # batch=64
7 | # subdivisions=2
8 | width=416
9 | height=416
10 | channels=3
11 | momentum=0.9
12 | decay=0.0005
13 | angle=0
14 | saturation = 1.5
15 | exposure = 1.5
16 | hue=.1
17 |
18 | learning_rate=0.001
19 | burn_in=1000
20 | max_batches = 500200
21 | policy=steps
22 | steps=400000,450000
23 | scales=.1,.1
24 |
25 | [convolutional]
26 | batch_normalize=1
27 | filters=16
28 | size=3
29 | stride=1
30 | pad=1
31 | activation=leaky
32 |
33 | [maxpool]
34 | size=2
35 | stride=2
36 |
37 | [convolutional]
38 | batch_normalize=1
39 | filters=32
40 | size=3
41 | stride=1
42 | pad=1
43 | activation=leaky
44 |
45 | [maxpool]
46 | size=2
47 | stride=2
48 |
49 | [convolutional]
50 | batch_normalize=1
51 | filters=64
52 | size=3
53 | stride=1
54 | pad=1
55 | activation=leaky
56 |
57 | [maxpool]
58 | size=2
59 | stride=2
60 |
61 | [convolutional]
62 | batch_normalize=1
63 | filters=128
64 | size=3
65 | stride=1
66 | pad=1
67 | activation=leaky
68 |
69 | [maxpool]
70 | size=2
71 | stride=2
72 |
73 | [convolutional]
74 | batch_normalize=1
75 | filters=256
76 | size=3
77 | stride=1
78 | pad=1
79 | activation=leaky
80 |
81 | [maxpool]
82 | size=2
83 | stride=2
84 |
85 | [convolutional]
86 | batch_normalize=1
87 | filters=512
88 | size=3
89 | stride=1
90 | pad=1
91 | activation=leaky
92 |
93 | [maxpool]
94 | size=2
95 | stride=1
96 |
97 | [convolutional]
98 | batch_normalize=1
99 | filters=1024
100 | size=3
101 | stride=1
102 | pad=1
103 | activation=leaky
104 |
105 | ###########
106 |
107 | [convolutional]
108 | batch_normalize=1
109 | size=3
110 | stride=1
111 | pad=1
112 | filters=512
113 | activation=leaky
114 |
115 | [convolutional]
116 | size=1
117 | stride=1
118 | pad=1
119 | filters=425
120 | activation=linear
121 |
122 | [region]
123 | anchors = 0.57273, 0.677385, 1.87446, 2.06253, 3.33843, 5.47434, 7.88282, 3.52778, 9.77052, 9.16828
124 | bias_match=1
125 | classes=80
126 | coords=4
127 | num=5
128 | softmax=1
129 | jitter=.2
130 | rescore=0
131 |
132 | object_scale=5
133 | noobject_scale=1
134 | class_scale=1
135 | coord_scale=1
136 |
137 | absolute=1
138 | thresh = .6
139 | random=1
140 |
--------------------------------------------------------------------------------
/app/src/main/assets/yolov3-tiny.cfg:
--------------------------------------------------------------------------------
1 | [net]
2 | # Testing
3 | batch=1
4 | subdivisions=1
5 | # Training
6 | # batch=64
7 | # subdivisions=2
8 | width=416
9 | height=416
10 | channels=3
11 | momentum=0.9
12 | decay=0.0005
13 | angle=0
14 | saturation = 1.5
15 | exposure = 1.5
16 | hue=.1
17 |
18 | learning_rate=0.001
19 | burn_in=1000
20 | max_batches = 500200
21 | policy=steps
22 | steps=400000,450000
23 | scales=.1,.1
24 |
25 | [convolutional]
26 | batch_normalize=1
27 | filters=16
28 | size=3
29 | stride=1
30 | pad=1
31 | activation=leaky
32 |
33 | [maxpool]
34 | size=2
35 | stride=2
36 |
37 | [convolutional]
38 | batch_normalize=1
39 | filters=32
40 | size=3
41 | stride=1
42 | pad=1
43 | activation=leaky
44 |
45 | [maxpool]
46 | size=2
47 | stride=2
48 |
49 | [convolutional]
50 | batch_normalize=1
51 | filters=64
52 | size=3
53 | stride=1
54 | pad=1
55 | activation=leaky
56 |
57 | [maxpool]
58 | size=2
59 | stride=2
60 |
61 | [convolutional]
62 | batch_normalize=1
63 | filters=128
64 | size=3
65 | stride=1
66 | pad=1
67 | activation=leaky
68 |
69 | [maxpool]
70 | size=2
71 | stride=2
72 |
73 | [convolutional]
74 | batch_normalize=1
75 | filters=256
76 | size=3
77 | stride=1
78 | pad=1
79 | activation=leaky
80 |
81 | [maxpool]
82 | size=2
83 | stride=2
84 |
85 | [convolutional]
86 | batch_normalize=1
87 | filters=512
88 | size=3
89 | stride=1
90 | pad=1
91 | activation=leaky
92 |
93 | [maxpool]
94 | size=2
95 | stride=1
96 |
97 | [convolutional]
98 | batch_normalize=1
99 | filters=1024
100 | size=3
101 | stride=1
102 | pad=1
103 | activation=leaky
104 |
105 | ###########
106 |
107 | [convolutional]
108 | batch_normalize=1
109 | filters=256
110 | size=1
111 | stride=1
112 | pad=1
113 | activation=leaky
114 |
115 | [convolutional]
116 | batch_normalize=1
117 | filters=512
118 | size=3
119 | stride=1
120 | pad=1
121 | activation=leaky
122 |
123 | [convolutional]
124 | size=1
125 | stride=1
126 | pad=1
127 | filters=255
128 | activation=linear
129 |
130 |
131 |
132 | [yolo]
133 | mask = 3,4,5
134 | anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
135 | classes=80
136 | num=6
137 | jitter=.3
138 | ignore_thresh = .7
139 | truth_thresh = 1
140 | random=1
141 |
142 | [route]
143 | layers = -4
144 |
145 | [convolutional]
146 | batch_normalize=1
147 | filters=128
148 | size=1
149 | stride=1
150 | pad=1
151 | activation=leaky
152 |
153 | [upsample]
154 | stride=2
155 |
156 | [route]
157 | layers = -1, 8
158 |
159 | [convolutional]
160 | batch_normalize=1
161 | filters=256
162 | size=3
163 | stride=1
164 | pad=1
165 | activation=leaky
166 |
167 | [convolutional]
168 | size=1
169 | stride=1
170 | pad=1
171 | filters=255
172 | activation=linear
173 |
174 | [yolo]
175 | mask = 0,1,2
176 | anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
177 | classes=80
178 | num=6
179 | jitter=.3
180 | ignore_thresh = .7
181 | truth_thresh = 1
182 | random=1
183 |
--------------------------------------------------------------------------------
/app/src/main/java/org/med/darknetandroid/CameraActivity.java:
--------------------------------------------------------------------------------
1 | package org.med.darknetandroid;
2 |
3 | import android.Manifest;
4 | import android.content.Context;
5 | import android.content.pm.PackageManager;
6 | import android.content.res.AssetManager;
7 | import android.graphics.Bitmap;
8 | import android.os.Bundle;
9 | import android.os.Environment;
10 | import android.provider.MediaStore;
11 | import android.util.Log;
12 | import androidx.appcompat.app.AppCompatActivity;
13 | import androidx.core.content.ContextCompat;
14 | import java.io.BufferedInputStream;
15 | import java.io.File;
16 | import java.io.FileOutputStream;
17 | import java.io.IOException;
18 | import java.io.OutputStream;
19 | import java.text.DecimalFormat;
20 | import java.util.ArrayList;
21 | import java.util.List;
22 | import java.util.Random;
23 | import java.util.Scanner;
24 | import org.opencv.android.BaseLoaderCallback;
25 | import org.opencv.android.CameraBridgeViewBase;
26 | import org.opencv.android.LoaderCallbackInterface;
27 | import org.opencv.android.OpenCVLoader;
28 | import org.opencv.android.Utils;
29 | import org.opencv.core.Core;
30 | import org.opencv.core.CvType;
31 | import org.opencv.core.Mat;
32 | import org.opencv.core.Point;
33 | import org.opencv.core.Scalar;
34 | import org.opencv.core.Size;
35 | import org.opencv.dnn.Dnn;
36 | import org.opencv.dnn.Net;
37 | import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
38 | import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
39 | import org.opencv.imgproc.Imgproc;
40 |
41 |
42 | public class CameraActivity extends AppCompatActivity implements CvCameraViewListener2 {
43 | private static final String TAG = "CameraActivity";
44 | private static final int PERMISSIONS_REQUEST = 1;
45 | private static final String PERMISSION_CAMERA = Manifest.permission.CAMERA;
46 | private static final String PERMISSION_STORAGE = Manifest.permission.WRITE_EXTERNAL_STORAGE;
47 | private static List classNames;
48 | private static List colors=new ArrayList<>();
49 | private Net net;
50 | private CameraBridgeViewBase mOpenCvCameraView;
51 | private boolean permissionGranted = false;
52 |
53 |
54 | private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
55 | @Override
56 | public void onManagerConnected(int status) {
57 | switch (status) {
58 | case LoaderCallbackInterface.SUCCESS:
59 | {
60 | Log.i(TAG, "OpenCV loaded successfully");
61 | mOpenCvCameraView.enableView();
62 | } break;
63 | default:
64 | {
65 | super.onManagerConnected(status);
66 | } break;
67 | }
68 | }
69 | };
70 |
71 |
72 |
73 | @Override
74 | protected void onCreate(Bundle savedInstanceState) {
75 | super.onCreate(savedInstanceState);
76 | setContentView(R.layout.activity_main);
77 | if (!permissionGranted) {
78 | checkPermissions();
79 | }
80 | mOpenCvCameraView = findViewById(R.id.CameraView);
81 | mOpenCvCameraView.setVisibility(CameraBridgeViewBase.VISIBLE);
82 | mOpenCvCameraView.setCvCameraViewListener(this);
83 | classNames = readLabels("labels.txt", this);
84 | for(int i=0; i result = new ArrayList<>();
133 | List outBlobNames = net.getUnconnectedOutLayersNames();
134 |
135 | net.forward(result, outBlobNames);
136 | float confThreshold = 0.5f;
137 |
138 | for (int i = 0; i < result.size(); ++i) {
139 | // each row is a candidate detection, the 1st 4 numbers are
140 | // [center_x, center_y, width, height], followed by (N-4) class probabilities
141 | Mat level = result.get(i);
142 | for (int j = 0; j < level.rows(); ++j) {
143 | Mat row = level.row(j);
144 | Mat scores = row.colRange(5, level.cols());
145 | Core.MinMaxLocResult mm = Core.minMaxLoc(scores);
146 | float confidence = (float) mm.maxVal;
147 | Point classIdPoint = mm.maxLoc;
148 | if (confidence > confThreshold) {
149 |
150 | int centerX = (int) (row.get(0, 0)[0] * frame.cols());
151 | int centerY = (int) (row.get(0, 1)[0] * frame.rows());
152 | int width = (int) (row.get(0, 2)[0] * frame.cols());
153 | int height = (int) (row.get(0, 3)[0] * frame.rows());
154 |
155 | int left = (int) (centerX - width * 0.5);
156 | int top =(int)(centerY - height * 0.5);
157 | int right =(int)(centerX + width * 0.5);
158 | int bottom =(int)(centerY + height * 0.5);
159 |
160 | Point left_top = new Point(left, top);
161 | Point right_bottom=new Point(right, bottom);
162 | Point label_left_top = new Point(left, top-5);
163 | DecimalFormat df = new DecimalFormat("#.##");
164 |
165 | int class_id = (int) classIdPoint.x;
166 | String label= classNames.get(class_id) + ": " + df.format(confidence);
167 | Scalar color= colors.get(class_id);
168 |
169 | Imgproc.rectangle(frame, left_top,right_bottom , color, 3, 2);
170 | Imgproc.putText(frame, label, label_left_top, Imgproc.FONT_HERSHEY_SIMPLEX, 1, new Scalar(0, 0, 0), 4);
171 | Imgproc.putText(frame, label, label_left_top, Imgproc.FONT_HERSHEY_SIMPLEX, 1, new Scalar(255, 255, 255), 2);
172 | }
173 | }
174 | }
175 | return frame;
176 | }
177 |
178 |
179 |
180 | private boolean checkPermissions() {
181 |
182 | int permissionCheck = ContextCompat.checkSelfPermission(this,
183 | Manifest.permission.CAMERA);
184 |
185 | if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
186 | requestPermissions(new String[] {PERMISSION_CAMERA, PERMISSION_STORAGE}, PERMISSIONS_REQUEST);
187 | return false;
188 | } else {
189 | return true;
190 | }
191 |
192 | }
193 |
194 |
195 |
196 | private static String getAssetsFile(String file, Context context) {
197 | AssetManager assetManager = context.getAssets();
198 | BufferedInputStream inputStream;
199 | try {
200 | // Read data from assets.
201 | inputStream = new BufferedInputStream(assetManager.open(file));
202 | byte[] data = new byte[inputStream.available()];
203 | inputStream.read(data);
204 | inputStream.close();
205 | // Create copy file in storage.
206 | File outFile = new File(context.getFilesDir(), file);
207 | FileOutputStream os = new FileOutputStream(outFile);
208 | os.write(data);
209 | os.close();
210 | // Return a path to file which may be read in common way.
211 | return outFile.getAbsolutePath();
212 | } catch (IOException ex) {
213 | Log.i(TAG, "Failed to upload a file");
214 | }
215 | return "";
216 | }
217 |
218 |
219 |
220 | private List readLabels (String file, Context context)
221 | {
222 | AssetManager assetManager = context.getAssets();
223 | BufferedInputStream inputStream;
224 | List labelsArray = new ArrayList<>();
225 | try {
226 | // Read data from assets.
227 | inputStream = new BufferedInputStream(assetManager.open(file));
228 | byte[] data = new byte[inputStream.available()];
229 | inputStream.read(data);
230 | inputStream.close();
231 | // Create copy file in storage.
232 | File outFile = new File(context.getFilesDir(), file);
233 | FileOutputStream os = new FileOutputStream(outFile);
234 | os.write(data);
235 | os.close();
236 | Scanner fileScanner = new Scanner(new File(outFile.getAbsolutePath())).useDelimiter("\n");
237 | String label;
238 | while (fileScanner.hasNext()) {
239 | label = fileScanner.next();
240 | labelsArray.add(label);
241 | }
242 | fileScanner.close();
243 | } catch (IOException ex) {
244 | Log.i(TAG, "Failed to read labels!");
245 | }
246 | return labelsArray;
247 | }
248 |
249 |
250 |
251 | private Scalar randomColor() {
252 | Random random = new Random();
253 | int r = random.nextInt(255);
254 | int g = random.nextInt(255);
255 | int b = random.nextInt(255);
256 | return new Scalar(r,g,b);
257 | }
258 |
259 |
260 |
261 | private void save_mat(Mat mat)
262 | {
263 | String path = Environment.getExternalStorageDirectory().toString();
264 | OutputStream fOut = null;
265 | File file = new File(path, "screen.jpg"); // the File to save , append increasing numeric counter to prevent files from getting overwritten.
266 | try {
267 | Bitmap bmp = Bitmap.createBitmap(mat.width(),mat.height(), Bitmap.Config.ARGB_8888);
268 | Mat tmp = new Mat (mat.width(),mat.height(), CvType.CV_8UC1,new Scalar(4));
269 | Imgproc.cvtColor(mat, tmp, Imgproc.COLOR_RGB2BGRA);
270 | //Imgproc.cvtColor(seedsImage, tmp, Imgproc.COLOR_GRAY2RGBA, 4);
271 | Utils.matToBitmap(tmp, bmp);
272 | fOut = new FileOutputStream(file);
273 | bmp.compress(Bitmap.CompressFormat.JPEG, 85, fOut); // saving the Bitmap to a file compressed as a JPEG with 85% compression rate
274 | fOut.flush(); // Not really required
275 | fOut.close(); // do not forget to close the stream
276 | MediaStore.Images.Media.insertImage(getContentResolver(),file.getAbsolutePath(),file.getName(),file.getName());
277 | } catch (Exception e) {
278 | e.printStackTrace();
279 | }
280 |
281 | }
282 |
283 |
284 |
285 | @Override
286 | public void onDestroy() {
287 | super.onDestroy();
288 | if (mOpenCvCameraView != null)
289 | mOpenCvCameraView.disableView();
290 | }
291 | }
292 |
--------------------------------------------------------------------------------
/app/src/main/java/org/med/darknetandroid/WelcomeActivity.java:
--------------------------------------------------------------------------------
1 | package org.med.darknetandroid;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.content.Intent;
6 | import android.os.Bundle;
7 | import android.os.Handler;
8 |
9 | public class WelcomeActivity extends AppCompatActivity {
10 | private static int SPLASH_TIME = 3000;
11 |
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | setContentView(R.layout.activity_welcome);
16 | new Handler().postDelayed(new Runnable() {
17 | @Override
18 | public void run() {
19 | Intent welcome = new Intent(WelcomeActivity.this, CameraActivity.class);
20 | startActivity(welcome);
21 | finish();
22 | }
23 | },SPLASH_TIME);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matteomedioli/AndroidObjectDetection/1d38b178e1aae598d8556d288bd1659e9e8ae3ea/app/src/main/res/drawable/logo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/toolbar_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matteomedioli/AndroidObjectDetection/1d38b178e1aae598d8556d288bd1659e9e8ae3ea/app/src/main/res/drawable/toolbar_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/welcome.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matteomedioli/AndroidObjectDetection/1d38b178e1aae598d8556d288bd1659e9e8ae3ea/app/src/main/res/drawable/welcome.jpeg
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
22 |
23 |
24 |
30 |
31 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_welcome.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matteomedioli/AndroidObjectDetection/1d38b178e1aae598d8556d288bd1659e9e8ae3ea/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matteomedioli/AndroidObjectDetection/1d38b178e1aae598d8556d288bd1659e9e8ae3ea/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matteomedioli/AndroidObjectDetection/1d38b178e1aae598d8556d288bd1659e9e8ae3ea/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matteomedioli/AndroidObjectDetection/1d38b178e1aae598d8556d288bd1659e9e8ae3ea/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matteomedioli/AndroidObjectDetection/1d38b178e1aae598d8556d288bd1659e9e8ae3ea/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matteomedioli/AndroidObjectDetection/1d38b178e1aae598d8556d288bd1659e9e8ae3ea/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matteomedioli/AndroidObjectDetection/1d38b178e1aae598d8556d288bd1659e9e8ae3ea/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matteomedioli/AndroidObjectDetection/1d38b178e1aae598d8556d288bd1659e9e8ae3ea/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matteomedioli/AndroidObjectDetection/1d38b178e1aae598d8556d288bd1659e9e8ae3ea/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matteomedioli/AndroidObjectDetection/1d38b178e1aae598d8556d288bd1659e9e8ae3ea/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #4682B1
4 | #355974
5 | #912244
6 | #E22E65
7 | #55000000
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Object Detector
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/org/med/darknetandroid/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package org.med.darknetandroid;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | google()
6 | jcenter()
7 |
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.4.1'
11 |
12 | // NOTE: Do not place your application dependencies here; they belong
13 | // in the individual module build.gradle files
14 | }
15 | }
16 |
17 | allprojects {
18 | repositories {
19 | google()
20 | jcenter()
21 |
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
--------------------------------------------------------------------------------
/darknetandroid.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 |
21 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/matteomedioli/AndroidObjectDetection/1d38b178e1aae598d8556d288bd1659e9e8ae3ea/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Jul 09 10:26:18 CEST 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/local.properties:
--------------------------------------------------------------------------------
1 | ## This file must *NOT* be checked into Version Control Systems,
2 | # as it contains information specific to your local configuration.
3 | #
4 | # Location of the SDK. This is only used by Gradle.
5 | # For customization when using a Version Control System, please read the
6 | # header note.
7 | #Tue Jul 09 10:26:19 CEST 2019
8 | ndk.dir=/home/med/Android/Sdk/ndk-bundle
9 | sdk.dir=/home/med/Android/Sdk
10 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------