diff --git a/.gitignore b/.gitignore index dc42d53..5edb4ee 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,10 @@ -*.iml -.gradle -/local.properties -/.idea/libraries -/.idea/modules.xml -/.idea/workspace.xml -.DS_Store -/build -/captures -.externalNativeBuild +*.iml +.gradle +/local.properties +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +.DS_Store +/build +/captures +.externalNativeBuild diff --git a/.idea/assetWizardSettings.xml b/.idea/assetWizardSettings.xml new file mode 100644 index 0000000..aff33aa --- /dev/null +++ b/.idea/assetWizardSettings.xml @@ -0,0 +1,335 @@ + + + + + + \ No newline at end of file diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index 1e096bd..938eaeb 100644 Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 4635fa6..db291c6 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -1,131 +1,131 @@ - - - - - - - - - -
- - - - xmlns:android - - ^$ - - - -
-
- - - - xmlns:.* - - ^$ - - - BY_NAME - -
-
- - - - .*:id - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:name - - http://schemas.android.com/apk/res/android - - - -
-
- - - - name - - ^$ - - - -
-
- - - - style - - ^$ - - - -
-
- - - - .* - - ^$ - - - BY_NAME - -
-
- - - - .* - - http://schemas.android.com/apk/res/android - - - ANDROID_ATTRIBUTE_ORDER - -
-
- - - - .* - - .* - - - BY_NAME - -
-
-
-
-
+ + + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
\ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..fb7f4a8 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index d1543e7..82a769a 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -1,21 +1,21 @@ - - - - - - + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 4ddb49f..021ee89 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,48 +1,63 @@ - - - - - - - - - - - + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/render.experimental.xml b/.idea/render.experimental.xml new file mode 100644 index 0000000..8ec256a --- /dev/null +++ b/.idea/render.experimental.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml deleted file mode 100644 index 9b770a6..0000000 --- a/.idea/runConfigurations.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/shelf/Uncommitted_changes_before_Update_at_1_21_2021_11_16_PM_[Default_Changelist]/shelved.patch b/.idea/shelf/Uncommitted_changes_before_Update_at_1_21_2021_11_16_PM_[Default_Changelist]/shelved.patch new file mode 100644 index 0000000..09f6242 --- /dev/null +++ b/.idea/shelf/Uncommitted_changes_before_Update_at_1_21_2021_11_16_PM_[Default_Changelist]/shelved.patch @@ -0,0 +1,17 @@ +Index: .idea/gradle.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP +<+>\r\n\r\n \r\n \r\n \r\n \r\n +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- .idea/gradle.xml (revision eaeef7439ade40336448f7ffd4d9ba0394b6a91b) ++++ .idea/gradle.xml (date 1611267296385) +@@ -15,6 +15,7 @@ + + + + diff --git a/.idea/shelf/Uncommitted_changes_before_Update_at_1_21_2021_11_16_PM__Default_Changelist_.xml b/.idea/shelf/Uncommitted_changes_before_Update_at_1_21_2021_11_16_PM__Default_Changelist_.xml new file mode 100644 index 0000000..f965422 --- /dev/null +++ b/.idea/shelf/Uncommitted_changes_before_Update_at_1_21_2021_11_16_PM__Default_Changelist_.xml @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore index 3543521..796b96d 100644 --- a/app/.gitignore +++ b/app/.gitignore @@ -1 +1 @@ -/build +/build diff --git a/app/build.gradle b/app/build.gradle index 39c9a41..76a3638 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,65 +1,80 @@ -apply plugin: 'com.android.application' - -apply plugin: 'com.google.gms.google-services' - -android { - compileSdkVersion 30 - defaultConfig { - applicationId "jtheiner.drawingclassification" - minSdkVersion 24 - targetSdkVersion 30 - versionCode 1 - versionName "1.0" - testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' - ndk{ - moduleName "gltf-lib" - abiFilters "armeabi", "armeabi-v7a", "x86" - } - } - // Sceneform libraries use language constructs from Java 8. - // Add these compile options if targeting minSdkVersion < 26. - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } - - aaptOptions { - noCompress "tflite" - noCompress "lite" - } -} - -repositories { - maven { - url 'https://google.bintray.com/tensorflow' - } - google() -} - - - -dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'androidx.appcompat:appcompat:1.2.0' - implementation 'com.google.android.material:material:1.2.1' - implementation 'androidx.constraintlayout:constraintlayout:2.0.1' - - testImplementation 'junit:junit:4.13' - androidTestImplementation 'androidx.test.ext:junit:1.1.2' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' - - implementation 'org.tensorflow:tensorflow-lite:+' - - implementation 'com.google.firebase:firebase-analytics:17.5.0' - implementation 'com.google.firebase:firebase-storage:19.2.0' - - implementation project(':engine') - -} - +apply plugin: 'com.android.application' + +apply plugin: 'com.google.gms.google-services' + + + +android { + signingConfigs { + release { + storeFile file(RELEASE_STORE_FILE) + storePassword RELEASE_STORE_PASSWORD + keyAlias RELEASE_KEY_ALIAS + keyPassword RELEASE_KEY_PASSWORD + + // Optional, specify signing versions used + v1SigningEnabled true + v2SigningEnabled true + } + } + compileSdkVersion 30 + buildToolsVersion "30.0.3" + defaultConfig { + applicationId "com.s23d" + minSdkVersion 24 + targetSdkVersion 30 + versionCode 3 + versionName "Native Penguine" + testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' + ndk{ + debugSymbolLevel 'FULL' + moduleName "gltf-lib" + abiFilters "armeabi", "armeabi-v7a", "arm64-v8a" + } + } + // Sceneform libraries use language constructs from Java 8. + // Add these compile options if targeting minSdkVersion < 26. + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + + aaptOptions { + noCompress "tflite" + noCompress "lite" + } +} + +repositories { + maven { + url 'https://google.bintray.com/tensorflow' + } + google() +} + + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'androidx.appcompat:appcompat:1.3.1' + implementation 'com.google.android.material:material:1.4.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.0' + + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' + + implementation 'org.tensorflow:tensorflow-lite:2.6.0' + + implementation 'com.google.firebase:firebase-analytics:19.0.1' + implementation 'com.google.firebase:firebase-storage:20.0.0' + + implementation project(':engine') + +} + diff --git a/app/google-services.json b/app/google-services.json index 7ea3f13..692e296 100644 --- a/app/google-services.json +++ b/app/google-services.json @@ -8,12 +8,20 @@ "client": [ { "client_info": { - "mobilesdk_app_id": "1:638820007020:android:7e3f8e4975da7d0d22ac49", + "mobilesdk_app_id": "1:638820007020:android:f952229e1a6f0c0222ac49", "android_client_info": { - "package_name": "jtheiner.drawingclassification" + "package_name": "com.s23d" } }, "oauth_client": [ + { + "client_id": "638820007020-6390r5c5puann0kpmsu47vmlmbt6hr7c.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.s23d", + "certificate_hash": "f1d0259d2233678e9bcf8ef6289e64bc1244d23c" + } + }, { "client_id": "638820007020-02cnvq12smju4lkbvhg6036d65f9tqah.apps.googleusercontent.com", "client_type": 3 diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 6e7ffa9..f1b4245 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,21 +1,21 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/app/release/app-release.apk b/app/release/app-release.apk new file mode 100644 index 0000000..34a2648 Binary files /dev/null and b/app/release/app-release.apk differ diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json new file mode 100644 index 0000000..4b68d98 --- /dev/null +++ b/app/release/output-metadata.json @@ -0,0 +1,18 @@ +{ + "version": 2, + "artifactType": { + "type": "APK", + "kind": "Directory" + }, + "applicationId": "com.s23d", + "variantName": "processReleaseResources", + "elements": [ + { + "type": "SINGLE", + "filters": [], + "versionCode": 1, + "versionName": "1.0", + "outputFile": "app-release.apk" + } + ] +} \ No newline at end of file diff --git a/app/src/androidTest/java/jtheiner/drawingclassification/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/s23d/ExampleInstrumentedTest.java similarity index 53% rename from app/src/androidTest/java/jtheiner/drawingclassification/ExampleInstrumentedTest.java rename to app/src/androidTest/java/com/s23d/ExampleInstrumentedTest.java index 4382ccf..3660a74 100644 --- a/app/src/androidTest/java/jtheiner/drawingclassification/ExampleInstrumentedTest.java +++ b/app/src/androidTest/java/com/s23d/ExampleInstrumentedTest.java @@ -1,26 +1,27 @@ -package jtheiner.drawingclassification; - -import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import static org.junit.Assert.*; - -/** - * Instrumented test, which will execute on an Android device. - * - * @see Testing documentation - */ -@RunWith(AndroidJUnit4.class) -public class ExampleInstrumentedTest { - @Test - public void useAppContext() { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); - - assertEquals("jtheiner.drawingclassification", appContext.getPackageName()); - } -} +package com.s23d; + +import android.content.Context; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertEquals; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.s23d", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6371aeb..aa2ca26 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,27 +1,31 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/10/labels.csv b/app/src/main/assets/10/labels.csv index eff1ceb..350f3d8 100644 --- a/app/src/main/assets/10/labels.csv +++ b/app/src/main/assets/10/labels.csv @@ -1,10 +1,10 @@ -0,sailboat -1,pliers -2,see saw -3,garden hose -4,cactus -5,eyeglasses -6,nose -7,stairs -8,envelope -9,bucket +0,sailboat +1,pliers +2,see saw +3,garden hose +4,cactus +5,eyeglasses +6,nose +7,stairs +8,envelope +9,bucket diff --git a/app/src/main/assets/100/labels.csv b/app/src/main/assets/100/labels.csv index 1e6f8c1..52f035c 100644 --- a/app/src/main/assets/100/labels.csv +++ b/app/src/main/assets/100/labels.csv @@ -1,100 +1,100 @@ -0,sailboat -1,pliers -2,see saw -3,garden hose -4,cactus -5,eyeglasses -6,nose -7,stairs -8,envelope -9,bucket -10,fireplace -11,swing set -12,lantern -13,banana -14,spreadsheet -15,elephant -16,fish -17,helicopter -18,axe -19,cell phone -20,hammer -21,string bean -22,donut -23,star -24,radio -25,cat -26,diamond -27,frog -28,broom -29,coffee cup -30,speedboat -31,paper clip -32,bicycle -33,map -34,baseball -35,tennis racquet -36,line -37,dishwasher -38,paintbrush -39,fork -40,teddy-bear -41,The Mona Lisa -42,clarinet -43,flamingo -44,couch -45,rainbow -46,bed -47,lipstick -48,parrot -49,ladder -50,syringe -51,violin -52,megaphone -53,car -54,cookie -55,rollerskates -56,anvil -57,goatee -58,teapot -59,octagon -60,hospital -61,bridge -62,leg -63,skull -64,ear -65,mushroom -66,chandelier -67,pool -68,crown -69,apple -70,golf club -71,potato -72,calendar -73,book -74,trombone -75,stove -76,scorpion -77,blackberry -78,circle -79,sheep -80,sandwich -81,bird -82,bowtie -83,wine bottle -84,postcard -85,power outlet -86,chair -87,hedgehog -88,pants -89,bread -90,microwave -91,t-shirt -92,rabbit -93,guitar -94,dog -95,bulldozer -96,bus -97,light bulb -98,computer -99,hexagon +0,sailboat +1,pliers +2,see saw +3,garden hose +4,cactus +5,eyeglasses +6,nose +7,stairs +8,envelope +9,bucket +10,fireplace +11,swing set +12,lantern +13,banana +14,spreadsheet +15,elephant +16,fish +17,helicopter +18,axe +19,cell phone +20,hammer +21,string bean +22,donut +23,star +24,radio +25,cat +26,diamond +27,frog +28,broom +29,coffee cup +30,speedboat +31,paper clip +32,bicycle +33,map +34,baseball +35,tennis racquet +36,line +37,dishwasher +38,paintbrush +39,fork +40,teddy-bear +41,The Mona Lisa +42,clarinet +43,flamingo +44,couch +45,rainbow +46,bed +47,lipstick +48,parrot +49,ladder +50,syringe +51,violin +52,megaphone +53,car +54,cookie +55,rollerskates +56,anvil +57,goatee +58,teapot +59,octagon +60,hospital +61,bridge +62,leg +63,skull +64,ear +65,mushroom +66,chandelier +67,pool +68,crown +69,apple +70,golf club +71,potato +72,calendar +73,book +74,trombone +75,stove +76,scorpion +77,blackberry +78,circle +79,sheep +80,sandwich +81,bird +82,bowtie +83,wine bottle +84,postcard +85,power outlet +86,chair +87,hedgehog +88,pants +89,bread +90,microwave +91,t-shirt +92,rabbit +93,guitar +94,dog +95,bulldozer +96,bus +97,light bulb +98,computer +99,hexagon diff --git a/app/src/main/assets/345/labels.csv b/app/src/main/assets/345/labels.csv index c39b4a5..a071aa0 100644 --- a/app/src/main/assets/345/labels.csv +++ b/app/src/main/assets/345/labels.csv @@ -1,345 +1,345 @@ -0,sailboat -1,pliers -2,see saw -3,garden hose -4,cactus -5,eyeglasses -6,nose -7,stairs -8,envelope -9,bucket -10,fireplace -11,swing set -12,lantern -13,banana -14,spreadsheet -15,elephant -16,fish -17,helicopter -18,axe -19,cell phone -20,hammer -21,string bean -22,donut -23,star -24,radio -25,cat -26,diamond -27,frog -28,broom -29,coffee cup -30,speedboat -31,paper clip -32,bicycle -33,map -34,baseball -35,tennis racquet -36,line -37,dishwasher -38,paintbrush -39,fork -40,teddy-bear -41,The Mona Lisa -42,clarinet -43,flamingo -44,couch -45,rainbow -46,bed -47,lipstick -48,parrot -49,ladder -50,syringe -51,violin -52,megaphone -53,car -54,cookie -55,rollerskates -56,anvil -57,goatee -58,teapot -59,octagon -60,hospital -61,bridge -62,leg -63,skull -64,ear -65,mushroom -66,chandelier -67,pool -68,crown -69,apple -70,golf club -71,potato -72,calendar -73,book -74,trombone -75,stove -76,scorpion -77,blackberry -78,circle -79,sheep -80,sandwich -81,bird -82,bowtie -83,wine bottle -84,postcard -85,power outlet -86,chair -87,hedgehog -88,pants -89,bread -90,microwave -91,t-shirt -92,rabbit -93,guitar -94,dog -95,bulldozer -96,bus -97,light bulb -98,computer -99,hexagon -100,beach -101,skateboard -102,barn -103,jail -104,waterslide -105,cooler -106,traffic light -107,hand -108,harp -109,moon -110,toe -111,vase -112,cello -113,remote control -114,truck -115,microphone -116,underwear -117,rifle -118,drill -119,square -120,knee -121,giraffe -122,snail -123,camouflage -124,table -125,alarm clock -126,camel -127,shorts -128,lighthouse -129,suitcase -130,bottlecap -131,tractor -132,carrot -133,hockey puck -134,dumbbell -135,shoe -136,The Great Wall of China -137,campfire -138,foot -139,flip flops -140,monkey -141,helmet -142,bandage -143,bench -144,stethoscope -145,grass -146,mermaid -147,laptop -148,hot air balloon -149,floor lamp -150,cow -151,dolphin -152,asparagus -153,motorbike -154,skyscraper -155,strawberry -156,umbrella -157,brain -158,mouth -159,zebra -160,jacket -161,triangle -162,hurricane -163,bracelet -164,pineapple -165,rake -166,steak -167,baseball bat -168,arm -169,popsicle -170,flying saucer -171,mouse -172,horse -173,crab -174,piano -175,river -176,castle -177,compass -178,binoculars -179,ceiling fan -180,airplane -181,scissors -182,garden -183,bush -184,bathtub -185,clock -186,drums -187,lobster -188,flower -189,diving board -190,toothbrush -191,saw -192,sea turtle -193,squiggle -194,tooth -195,mountain -196,sword -197,aircraft carrier -198,necklace -199,cup -200,wine glass -201,lighter -202,elbow -203,blueberry -204,snowman -205,broccoli -206,sun -207,television -208,sock -209,pig -210,key -211,parachute -212,hot tub -213,shark -214,washing machine -215,hat -216,windmill -217,frying pan -218,fire hydrant -219,toothpaste -220,belt -221,beard -222,rhinoceros -223,headphones -224,matches -225,knife -226,snorkel -227,feather -228,duck -229,pond -230,paint can -231,firetruck -232,angel -233,bear -234,passport -235,cake -236,telephone -237,mosquito -238,hamburger -239,pencil -240,peas -241,ant -242,eye -243,mailbox -244,grapes -245,canoe -246,pillow -247,The Eiffel Tower -248,sink -249,backpack -250,octopus -251,finger -252,snowflake -253,tent -254,nail -255,submarine -256,wheel -257,church -258,toilet -259,purse -260,penguin -261,bee -262,streetlight -263,van -264,boomerang -265,train -266,peanut -267,stop sign -268,basket -269,wristwatch -270,ice cream -271,pizza -272,crocodile -273,lollipop -274,hockey stick -275,soccer ball -276,dragon -277,camera -278,cannon -279,zigzag -280,spoon -281,pickup truck -282,ocean -283,bat -284,stitches -285,shovel -286,palm tree -287,mug -288,hot dog -289,fan -290,sweater -291,cruise ship -292,cloud -293,whale -294,police car -295,saxophone -296,squirrel -297,smiley face -298,owl -299,house -300,school bus -301,yoga -302,spider -303,flashlight -304,tree -305,swan -306,panda -307,ambulance -308,calculator -309,pear -310,trumpet -311,lightning -312,animal migration -313,dresser -314,basketball -315,birthday cake -316,leaf -317,oven -318,house plant -319,keyboard -320,eraser -321,sleeping bag -322,moustache -323,door -324,hourglass -325,crayon -326,stereo -327,fence -328,roller coaster -329,onion -330,marker -331,tiger -332,screwdriver -333,watermelon -334,lion -335,butterfly -336,toaster -337,raccoon -338,picture frame -339,candle -340,face -341,kangaroo -342,snake -343,tornado -344,rain +0,sailboat +1,pliers +2,see saw +3,garden hose +4,cactus +5,eyeglasses +6,nose +7,stairs +8,envelope +9,bucket +10,fireplace +11,swing set +12,lantern +13,banana +14,spreadsheet +15,elephant +16,fish +17,helicopter +18,axe +19,cell phone +20,hammer +21,string bean +22,donut +23,star +24,radio +25,cat +26,diamond +27,frog +28,broom +29,coffee cup +30,speedboat +31,paper clip +32,bicycle +33,map +34,baseball +35,tennis racquet +36,line +37,dishwasher +38,paintbrush +39,fork +40,teddy-bear +41,The Mona Lisa +42,clarinet +43,flamingo +44,couch +45,rainbow +46,bed +47,lipstick +48,parrot +49,ladder +50,syringe +51,violin +52,megaphone +53,car +54,cookie +55,rollerskates +56,anvil +57,goatee +58,teapot +59,octagon +60,hospital +61,bridge +62,leg +63,skull +64,ear +65,mushroom +66,chandelier +67,pool +68,crown +69,apple +70,golf club +71,potato +72,calendar +73,book +74,trombone +75,stove +76,scorpion +77,blackberry +78,circle +79,sheep +80,sandwich +81,bird +82,bowtie +83,wine bottle +84,postcard +85,power outlet +86,chair +87,hedgehog +88,pants +89,bread +90,microwave +91,t-shirt +92,rabbit +93,guitar +94,dog +95,bulldozer +96,bus +97,light bulb +98,computer +99,hexagon +100,beach +101,skateboard +102,barn +103,jail +104,waterslide +105,cooler +106,traffic light +107,hand +108,harp +109,moon +110,toe +111,vase +112,cello +113,remote control +114,truck +115,microphone +116,underwear +117,rifle +118,drill +119,square +120,knee +121,giraffe +122,snail +123,camouflage +124,table +125,alarm clock +126,camel +127,shorts +128,lighthouse +129,suitcase +130,bottlecap +131,tractor +132,carrot +133,hockey puck +134,dumbbell +135,shoe +136,The Great Wall of China +137,campfire +138,foot +139,flip flops +140,monkey +141,helmet +142,bandage +143,bench +144,stethoscope +145,grass +146,mermaid +147,laptop +148,hot air balloon +149,floor lamp +150,cow +151,dolphin +152,asparagus +153,motorbike +154,skyscraper +155,strawberry +156,umbrella +157,brain +158,mouth +159,zebra +160,jacket +161,triangle +162,hurricane +163,bracelet +164,pineapple +165,rake +166,steak +167,baseball bat +168,arm +169,popsicle +170,flying saucer +171,mouse +172,horse +173,crab +174,piano +175,river +176,castle +177,compass +178,binoculars +179,ceiling fan +180,airplane +181,scissors +182,garden +183,bush +184,bathtub +185,clock +186,drums +187,lobster +188,flower +189,diving board +190,toothbrush +191,saw +192,sea turtle +193,squiggle +194,tooth +195,mountain +196,sword +197,aircraft carrier +198,necklace +199,cup +200,wine glass +201,lighter +202,elbow +203,blueberry +204,snowman +205,broccoli +206,sun +207,television +208,sock +209,pig +210,key +211,parachute +212,hot tub +213,shark +214,washing machine +215,hat +216,windmill +217,frying pan +218,fire hydrant +219,toothpaste +220,belt +221,beard +222,rhinoceros +223,headphones +224,matches +225,knife +226,snorkel +227,feather +228,duck +229,pond +230,paint can +231,firetruck +232,angel +233,bear +234,passport +235,cake +236,telephone +237,mosquito +238,hamburger +239,pencil +240,peas +241,ant +242,eye +243,mailbox +244,grapes +245,canoe +246,pillow +247,The Eiffel Tower +248,sink +249,backpack +250,octopus +251,finger +252,snowflake +253,tent +254,nail +255,submarine +256,wheel +257,church +258,toilet +259,purse +260,penguin +261,bee +262,streetlight +263,van +264,boomerang +265,train +266,peanut +267,stop sign +268,basket +269,wristwatch +270,ice cream +271,pizza +272,crocodile +273,lollipop +274,hockey stick +275,soccer ball +276,dragon +277,camera +278,cannon +279,zigzag +280,spoon +281,pickup truck +282,ocean +283,bat +284,stitches +285,shovel +286,palm tree +287,mug +288,hot dog +289,fan +290,sweater +291,cruise ship +292,cloud +293,whale +294,police car +295,saxophone +296,squirrel +297,smiley face +298,owl +299,house +300,school bus +301,yoga +302,spider +303,flashlight +304,tree +305,swan +306,panda +307,ambulance +308,calculator +309,pear +310,trumpet +311,lightning +312,animal migration +313,dresser +314,basketball +315,birthday cake +316,leaf +317,oven +318,house plant +319,keyboard +320,eraser +321,sleeping bag +322,moustache +323,door +324,hourglass +325,crayon +326,stereo +327,fence +328,roller coaster +329,onion +330,marker +331,tiger +332,screwdriver +333,watermelon +334,lion +335,butterfly +336,toaster +337,raccoon +338,picture frame +339,candle +340,face +341,kangaroo +342,snake +343,tornado +344,rain diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..4d616c0 Binary files /dev/null and b/app/src/main/ic_launcher-playstore.png differ diff --git a/app/src/main/java/jtheiner/drawingclassification/MainActivity.java b/app/src/main/java/com/s23d/MainActivity.java similarity index 63% rename from app/src/main/java/jtheiner/drawingclassification/MainActivity.java rename to app/src/main/java/com/s23d/MainActivity.java index 07406a8..ddb8717 100644 --- a/app/src/main/java/jtheiner/drawingclassification/MainActivity.java +++ b/app/src/main/java/com/s23d/MainActivity.java @@ -1,9 +1,8 @@ -package jtheiner.drawingclassification; +package com.s23d; import android.app.Dialog; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Color; @@ -18,29 +17,23 @@ import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; -import android.widget.Toast; -import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; -import com.google.android.gms.tasks.OnFailureListener; -import com.google.android.gms.tasks.OnSuccessListener; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.firebase.FirebaseApp; -import com.google.firebase.storage.FileDownloadTask; import com.google.firebase.storage.FirebaseStorage; import com.google.firebase.storage.StorageReference; - -import org.andresoviedo.util.android.ContentUtils; +import com.s23d.classification.ImageClassifier; +import com.s23d.classification.Result; +import com.s23d.view.ModelActivity; import java.io.File; import java.io.IOException; +import java.util.Locale; import java.util.Random; -import jtheiner.drawingclassification.classification.ImageClassifier; -import jtheiner.drawingclassification.classification.Result; -import jtheiner.drawingclassification.view.ModelActivity; - public class MainActivity extends AppCompatActivity { @@ -58,22 +51,17 @@ public class MainActivity extends AppCompatActivity { private boolean isConnected; private MaterialAlertDialogBuilder builder; + private MaterialAlertDialogBuilder progressBuilder; + private AlertDialog dialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - //Init Firebase FirebaseApp.initializeApp(this); - - paintView = findViewById(R.id.paintView); - paintView.init(); // initial drawing view - textViewResult = findViewById(R.id.txt_result_label); - textViewDraw = findViewById(R.id.txt_draw_label); - - storage = FirebaseStorage.getInstance(); + doInit(); // instantiate classifier try { @@ -92,19 +80,13 @@ protected void onCreate(Bundle savedInstanceState) { builder = new MaterialAlertDialogBuilder(this, R.style.RoundShapeTheme) .setTitle("No Internet") - .setMessage("You are currently offline\nCheck you internet to continue") - .setNegativeButton("Ignore", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - dialogInterface.dismiss(); - } - }) - .setPositiveButton("Ok", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - dialogInterface.dismiss(); - } - }); + .setMessage("You are currently offline\nCheck you internet try again") + .setNegativeButton("Ignore", (dialogInterface, i) -> dialogInterface.dismiss()) + .setPositiveButton("Ok", (dialogInterface, i) -> dialogInterface.dismiss()); + + progressBuilder = new MaterialAlertDialogBuilder(this, R.style.RoundShapeTheme) + .setView(R.layout.progress); + dialog = progressBuilder.create(); this.mainView = this.findViewById(R.id.activity_main).getRootView(); @@ -112,9 +94,18 @@ public void onClick(DialogInterface dialogInterface, int i) { } + private void doInit() { + paintView = findViewById(R.id.paintView); + paintView.init(); // initial drawing view + textViewResult = findViewById(R.id.txt_result_label); + textViewDraw = findViewById(R.id.txt_draw_label); + storage = FirebaseStorage.getInstance(); + } + + public void onClearClick(View view) { Log.i("MainActivity", "Clear sketch event triggers"); - paintView.clear(); + clearView(); //clear view and let try again } public void onDetectClick(View view) { @@ -131,49 +122,50 @@ public void onDetectClick(View view) { textViewResult.setText(""); for (int index : result.getTopK()) { textViewResult.setText( - String.format("%s\n%s (%s%%)", textViewResult.getText(), classifier.getLabel(index), String.format("%.02f", classifier.getProbability(index) * 100)) + String.format("%s\n%s (%s%%)", textViewResult.getText(), classifier.getLabel(index), + String.format(Locale.getDefault(), "%.02f", classifier.getProbability(index) * 100)) ); - if ((classifier.getProbability(index) * 100) > 50) { - Toast.makeText(this, "Loading 3D Model for " + classifier.getLabel(index), Toast.LENGTH_SHORT).show(); - downloadFile(classifier.getLabel(index).toLowerCase()); - } } int expectedIndex = classifier.getExpectedIndex(); if (result.getTopK().contains(expectedIndex)) { mainView.setBackgroundColor(Color.rgb(78, 175, 36)); + load3DObjectWhenClassificationIsCorrect(expectedIndex); } else { mainView.setBackgroundColor(Color.rgb(204, 0, 0)); + dialog.dismiss(); } } + private void load3DObjectWhenClassificationIsCorrect(int index) { + if ((classifier.getProbability(index) * 100) > 50) { + downloadAndRender3DObject(classifier.getLabel(index).toLowerCase()); + } + } + public void onNextClick(View view) { resetView(); } - private void downloadFile(String fileName) { + private void downloadAndRender3DObject(String fileName) { if (isConnected) { + dialog.show(); modelRef = storage.getReference().child(fileName + ".obj"); final File localFile = new File(getCacheDir(), fileName + ".obj"); - modelRef.getFile(localFile).addOnSuccessListener(new OnSuccessListener() { - @Override - public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) { - Log.i("Renderer ", ";local tem file created created " + localFile.toString()); - Log.i("Renderer ", ";local tem file dir" + localFile.getAbsolutePath()); - Intent intent = new Intent(MainActivity.this.getApplicationContext(), ModelActivity.class); - ContentUtils.setCurrentDir(localFile.getParentFile()); - Log.i("Renderer ", ";local tem file dir: file://" + localFile.getAbsolutePath()); - intent.putExtra("uri", "file://" + localFile.getPath()); - intent.putExtra("immersiveMode", "true"); - MainActivity.this.startActivity(intent); - } - }).addOnFailureListener(new OnFailureListener() { - @Override - public void onFailure(@NonNull Exception exception) { - Log.i("Renderer ", ";local tem file not created created " + exception.toString()); - } + modelRef.getFile(localFile).addOnSuccessListener(taskSnapshot -> { + Log.i("Renderer ", ";local tem file created created " + localFile.toString()); + Log.i("Renderer ", ";local tem file dir" + localFile.getAbsolutePath()); + Intent intent = new Intent(MainActivity.this.getApplicationContext(), ModelActivity.class); + // ContentUtils.setCurrentDir(localFile.getParentFile()); + Log.i("Renderer ", ";local tem file dir: file://" + localFile.getAbsolutePath()); + intent.putExtra("uri", "file://" + localFile.getPath()); + intent.putExtra("immersiveMode", "true"); + MainActivity.this.startActivity(intent); + }).addOnFailureListener(exception -> { + Log.i("Renderer ", ";local tem file not created created " + exception.toString()); + dialog.dismiss(); }); } else builder.show(); @@ -184,7 +176,7 @@ private void showImage(Bitmap bitmap) { Dialog builder = new Dialog(this); builder.requestWindowFeature(Window.FEATURE_NO_TITLE); builder.getWindow().setBackgroundDrawable( - new ColorDrawable(Color.TRANSPARENT)); + new ColorDrawable(android.graphics.Color.TRANSPARENT)); builder.setOnDismissListener(dialogInterface -> { }); @@ -200,9 +192,22 @@ private void resetView() { mainView.setBackgroundColor(Color.WHITE); paintView.clear(); textViewResult.setText(""); - // get a random label and set as expected class classifier.setExpectedIndex(new Random().nextInt(classifier.getNumberOfClasses())); - textViewDraw.setText("Draw ... " + classifier.getLabel(classifier.getExpectedIndex())); + textViewDraw.setText(String.format("Draw ... %s", classifier.getLabel(classifier.getExpectedIndex()))); + } + + + private void clearView() { + paintView.clear(); + textViewResult.setText(""); + } + + @Override + protected void onResume() { + super.onResume(); + if (dialog.isShowing()) { + dialog.dismiss(); + } } } \ No newline at end of file diff --git a/app/src/main/java/jtheiner/drawingclassification/PaintView.java b/app/src/main/java/com/s23d/PaintView.java similarity index 87% rename from app/src/main/java/jtheiner/drawingclassification/PaintView.java rename to app/src/main/java/com/s23d/PaintView.java index 7a71e7d..35c022a 100644 --- a/app/src/main/java/jtheiner/drawingclassification/PaintView.java +++ b/app/src/main/java/com/s23d/PaintView.java @@ -1,154 +1,152 @@ -package jtheiner.drawingclassification; - - - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Path; -import android.util.AttributeSet; -import android.view.MotionEvent; -import android.view.View; - - -import java.util.ArrayList; - -import jtheiner.drawingclassification.classification.ImageClassifier; - - -/** - * Custom view class to draw sketches using bitmaps - */ -public class PaintView extends View { - - - public static int BRUSH_SIZE = 50; - public static final int DEFAULT_COLOR = Color.WHITE; - public static final int DEFAULT_BG_COLOR = Color.BLACK; - private static final float TOUCH_TOLERANCE = 4; - - // original size of PaintView - public int WIDTH; - public int HEIGHT; - - private float mX, mY; - private Path mPath; - private Paint mPaint; - private ArrayList paths = new ArrayList<>(); - private Bitmap mBitmap; - private Canvas mCanvas; - private Paint mBitmapPaint = new Paint(Paint.DITHER_FLAG); - - public PaintView(Context context) { - this(context, null); - } - - public PaintView(Context context, AttributeSet attrs) { - super(context, attrs); - mPaint = new Paint(); - mPaint.setAntiAlias(true); - mPaint.setDither(true); - mPaint.setColor(DEFAULT_COLOR); - mPaint.setStyle(Paint.Style.STROKE); - mPaint.setStrokeJoin(Paint.Join.ROUND); - mPaint.setStrokeCap(Paint.Cap.ROUND); - mPaint.setXfermode(null); - mPaint.setAlpha(0xff); - } - - public void init() { - this.WIDTH = this.getLayoutParams().width; - this.HEIGHT = this.getLayoutParams().height; - mBitmap = Bitmap.createBitmap(WIDTH, HEIGHT , Bitmap.Config.ARGB_8888); - mCanvas = new Canvas(mBitmap); - } - - public void clear() { - paths.clear(); - invalidate(); - } - - @Override - protected void onDraw(Canvas canvas) { - canvas.save(); - mCanvas.drawColor(DEFAULT_BG_COLOR); - - for (PenPath fp : paths) { - mPaint.setColor(fp.color); - mPaint.setStrokeWidth(fp.strokeWidth); - mPaint.setMaskFilter(null); - mCanvas.drawPath(fp.path, mPaint); - } - - canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); - canvas.restore(); - } - - private void touchStart(float x, float y) { - mPath = new Path(); - PenPath fp = new PenPath(DEFAULT_COLOR, BRUSH_SIZE, mPath); - paths.add(fp); - mPath.reset(); - mPath.moveTo(x, y); - mX = x; - mY = y; - } - - private void touchMove(float x, float y) { - float dx = Math.abs(x - mX); - float dy = Math.abs(y - mY); - - if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { - mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2); - mX = x; - mY = y; - } - } - - private void touchUp() { - mPath.lineTo(mX, mY); - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - float x = event.getX(); - float y = event.getY(); - - switch(event.getAction()) { - case MotionEvent.ACTION_DOWN : - touchStart(x, y); - invalidate(); - break; - case MotionEvent.ACTION_MOVE : - touchMove(x, y); - invalidate(); - break; - case MotionEvent.ACTION_UP : - touchUp(); - invalidate(); - break; - } - - return true; - } - - public Bitmap getmBitmap() { - return this.mBitmap; - } - - // scale given bitmap by a factor and return a new bitmap - public Bitmap scaleBitmap(int scaleFactor, Bitmap bitmap) { - return Bitmap.createScaledBitmap(bitmap, (int)(bitmap.getWidth()*scaleFactor), (int)(bitmap.getHeight()*scaleFactor), true); - } - - // scale original bitmap down to network size (28x28) - public Bitmap getNormalizedBitmap() { - float scaleFactor = ImageClassifier.DIM_IMG_SIZE_HEIGHT / (float) mBitmap.getHeight(); - // todo: cut empty space around sketch - return Bitmap.createScaledBitmap(mBitmap, (int)(mBitmap.getWidth()*scaleFactor), (int)(mBitmap.getHeight()*scaleFactor), true); - - } - +package com.s23d; + + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Path; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; + +import com.s23d.classification.ImageClassifier; + +import java.util.ArrayList; + + +/** + * Custom view class to draw sketches using bitmaps + */ +public class PaintView extends View { + + + public static int BRUSH_SIZE = 50; + public static final int DEFAULT_COLOR = Color.WHITE; + public static final int DEFAULT_BG_COLOR = Color.BLACK; + private static final float TOUCH_TOLERANCE = 4; + + // original size of PaintView + public int WIDTH; + public int HEIGHT; + + private float mX, mY; + private Path mPath; + private final Paint mPaint; + private final ArrayList paths = new ArrayList<>(); + private Bitmap mBitmap; + private Canvas mCanvas; + private final Paint mBitmapPaint = new Paint(Paint.DITHER_FLAG); + + public PaintView(Context context) { + this(context, null); + } + + public PaintView(Context context, AttributeSet attrs) { + super(context, attrs); + mPaint = new Paint(); + mPaint.setAntiAlias(true); + mPaint.setDither(true); + mPaint.setColor(DEFAULT_COLOR); + mPaint.setStyle(Paint.Style.STROKE); + mPaint.setStrokeJoin(Paint.Join.ROUND); + mPaint.setStrokeCap(Paint.Cap.ROUND); + mPaint.setXfermode(null); + mPaint.setAlpha(0xff); + } + + public void init() { + this.WIDTH = this.getLayoutParams().width; + this.HEIGHT = this.getLayoutParams().height; + mBitmap = Bitmap.createBitmap(WIDTH, HEIGHT , Bitmap.Config.ARGB_8888); + mCanvas = new Canvas(mBitmap); + } + + public void clear() { + paths.clear(); + invalidate(); + } + + @Override + protected void onDraw(Canvas canvas) { + canvas.save(); + mCanvas.drawColor(DEFAULT_BG_COLOR); + + for (PenPath fp : paths) { + mPaint.setColor(fp.color); + mPaint.setStrokeWidth(fp.strokeWidth); + mPaint.setMaskFilter(null); + mCanvas.drawPath(fp.path, mPaint); + } + + canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); + canvas.restore(); + } + + private void touchStart(float x, float y) { + mPath = new Path(); + PenPath fp = new PenPath(DEFAULT_COLOR, BRUSH_SIZE, mPath); + paths.add(fp); + mPath.reset(); + mPath.moveTo(x, y); + mX = x; + mY = y; + } + + private void touchMove(float x, float y) { + float dx = Math.abs(x - mX); + float dy = Math.abs(y - mY); + + if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { + mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2); + mX = x; + mY = y; + } + } + + private void touchUp() { + mPath.lineTo(mX, mY); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + float x = event.getX(); + float y = event.getY(); + + switch(event.getAction()) { + case MotionEvent.ACTION_DOWN : + touchStart(x, y); + invalidate(); + break; + case MotionEvent.ACTION_MOVE : + touchMove(x, y); + invalidate(); + break; + case MotionEvent.ACTION_UP : + touchUp(); + invalidate(); + break; + } + + return true; + } + + public Bitmap getmBitmap() { + return this.mBitmap; + } + + // scale given bitmap by a factor and return a new bitmap + public Bitmap scaleBitmap(int scaleFactor, Bitmap bitmap) { + return Bitmap.createScaledBitmap(bitmap, bitmap.getWidth() * scaleFactor, bitmap.getHeight() * scaleFactor, true); + } + + // scale original bitmap down to network size (28x28) + public Bitmap getNormalizedBitmap() { + float scaleFactor = ImageClassifier.DIM_IMG_SIZE_HEIGHT / (float) mBitmap.getHeight(); + // todo: cut empty space around sketch + return Bitmap.createScaledBitmap(mBitmap, (int)(mBitmap.getWidth()*scaleFactor), (int)(mBitmap.getHeight()*scaleFactor), true); + + } + } \ No newline at end of file diff --git a/app/src/main/java/jtheiner/drawingclassification/PenPath.java b/app/src/main/java/com/s23d/PenPath.java similarity index 84% rename from app/src/main/java/jtheiner/drawingclassification/PenPath.java rename to app/src/main/java/com/s23d/PenPath.java index 6d94f5d..802bd15 100644 --- a/app/src/main/java/jtheiner/drawingclassification/PenPath.java +++ b/app/src/main/java/com/s23d/PenPath.java @@ -1,16 +1,16 @@ -package jtheiner.drawingclassification; - -import android.graphics.Path; - -public class PenPath { - - public int color; - public int strokeWidth; - public Path path; - - public PenPath(int color, int strokeWidth, Path path) { - this.color = color; - this.strokeWidth = strokeWidth; - this.path = path; - } +package com.s23d; + +import android.graphics.Path; + +public class PenPath { + + public int color; + public int strokeWidth; + public Path path; + + public PenPath(int color, int strokeWidth, Path path) { + this.color = color; + this.strokeWidth = strokeWidth; + this.path = path; + } } \ No newline at end of file diff --git a/app/src/main/java/jtheiner/drawingclassification/classification/ImageClassifier.java b/app/src/main/java/com/s23d/classification/ImageClassifier.java similarity index 86% rename from app/src/main/java/jtheiner/drawingclassification/classification/ImageClassifier.java rename to app/src/main/java/com/s23d/classification/ImageClassifier.java index 5b64cf4..deba4f5 100644 --- a/app/src/main/java/jtheiner/drawingclassification/classification/ImageClassifier.java +++ b/app/src/main/java/com/s23d/classification/ImageClassifier.java @@ -1,97 +1,98 @@ -package jtheiner.drawingclassification.classification; - -import android.app.Activity; -import android.graphics.Bitmap; -import android.util.Log; - -import org.tensorflow.lite.Interpreter; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.MappedByteBuffer; -import java.util.ArrayList; - - - -public class ImageClassifier { - - private static final String MODEL_FILE = "10/model10.tflite"; - private static final String LABELS_FILE = "10/labels.csv"; - - private static final int DIM_BATCH_SIZE = 1; - public static final int DIM_IMG_SIZE_HEIGHT = 28; - public static final int DIM_IMG_SIZE_WIDTH = 28; - private static final int DIM_PIXEL_SIZE = 1; - - private ArrayList labels; // list of all labels - private ByteBuffer imgData = null; // models input format - private Interpreter tflite; // the model - private int[] imagePixels = new int[DIM_IMG_SIZE_HEIGHT * DIM_IMG_SIZE_WIDTH]; - private final float[][] result; // depending on models architecture (possible multiple output) - - private int expectedIndex; // random label index which is to be drawn - - public ImageClassifier(Activity activity) throws IOException { - - // load model - MappedByteBuffer modelBuffered = ModelInput.loadModelFile(activity, MODEL_FILE); - Log.i("ImageClassifier", "" + modelBuffered.isLoaded()); - this.tflite = new Interpreter(modelBuffered); - - // load labels - this.labels = ModelInput.readLabels(activity, LABELS_FILE); - this.result = new float[1][labels.size()]; - - // allocate memory for model input - this.imgData = ByteBuffer.allocateDirect(4 * DIM_BATCH_SIZE * DIM_IMG_SIZE_HEIGHT * DIM_IMG_SIZE_WIDTH * DIM_PIXEL_SIZE); - this.imgData.order(ByteOrder.nativeOrder()); - - Log.i("ImageClassifier", "Successfully created a Tensorflow Lite sketch classifier."); - } - - public Result classify(Bitmap bitmap) { - convertBitmapToByteBuffer(bitmap); // flatten bitmap to byte array - tflite.run(imgData, result); // classify task - return new Result(result[0], labels); // create the result - } - - private void convertBitmapToByteBuffer(Bitmap bitmap) { - if (imgData == null) { - return; - } - imgData.rewind(); - - bitmap.getPixels(imagePixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight()); - - int pixel = 0; - for (int i = 0; i < DIM_IMG_SIZE_WIDTH; ++i) { - for (int j = 0; j < DIM_IMG_SIZE_HEIGHT; ++j) { - final int color = imagePixels[pixel++]; - imgData.putFloat((((color >> 16) & 0xFF) + ((color >> 8) & 0xFF) + (color & 0xFF)) / 3.0f / 255.0f); - } - } - } - - - public void setExpectedIndex(int index) { - this.expectedIndex = index; - } - - - public int getExpectedIndex() { - return expectedIndex; - } - - public float getProbability(int index) { - return result[0][index]; - } - - public String getLabel(int index) { - return labels.get(index); - } - - public int getNumberOfClasses() { - return labels.size(); - } -} +package com.s23d.classification; + +import android.graphics.Bitmap; +import android.util.Log; + +import androidx.appcompat.app.AppCompatActivity; + +import org.tensorflow.lite.Interpreter; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.MappedByteBuffer; +import java.util.ArrayList; + + + +public class ImageClassifier { + + private static final String MODEL_FILE = "10/model10.tflite"; + private static final String LABELS_FILE = "10/labels.csv"; + + private static final int DIM_BATCH_SIZE = 1; + public static final int DIM_IMG_SIZE_HEIGHT = 28; + public static final int DIM_IMG_SIZE_WIDTH = 28; + private static final int DIM_PIXEL_SIZE = 1; + + private final ArrayList labels; // list of all labels + private ByteBuffer imgData = null; // models input format + private final Interpreter tflite; // the model + private final int[] imagePixels = new int[DIM_IMG_SIZE_HEIGHT * DIM_IMG_SIZE_WIDTH]; + private final float[][] result; // depending on models architecture (possible multiple output) + + private int expectedIndex; // random label index which is to be drawn + + public ImageClassifier(AppCompatActivity activity) throws IOException { + + // load model + MappedByteBuffer modelBuffered = ModelInput.loadModelFile(activity, MODEL_FILE); + Log.i("ImageClassifier", "" + modelBuffered.isLoaded()); + this.tflite = new Interpreter(modelBuffered); + + // load labels + this.labels = ModelInput.readLabels(activity, LABELS_FILE); + this.result = new float[1][labels.size()]; + + // allocate memory for model input + this.imgData = ByteBuffer.allocateDirect(4 * DIM_BATCH_SIZE * DIM_IMG_SIZE_HEIGHT * DIM_IMG_SIZE_WIDTH * DIM_PIXEL_SIZE); + this.imgData.order(ByteOrder.nativeOrder()); + + Log.i("ImageClassifier", "Successfully created a Tensorflow Lite sketch classifier."); + } + + public Result classify(Bitmap bitmap) { + convertBitmapToByteBuffer(bitmap); // flatten bitmap to byte array + tflite.run(imgData, result); // classify task + return new Result(result[0], labels); // create the result + } + + private void convertBitmapToByteBuffer(Bitmap bitmap) { + if (imgData == null) { + return; + } + imgData.rewind(); + + bitmap.getPixels(imagePixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight()); + + int pixel = 0; + for (int i = 0; i < DIM_IMG_SIZE_WIDTH; ++i) { + for (int j = 0; j < DIM_IMG_SIZE_HEIGHT; ++j) { + final int color = imagePixels[pixel++]; + imgData.putFloat((((color >> 16) & 0xFF) + ((color >> 8) & 0xFF) + (color & 0xFF)) / 3.0f / 255.0f); + } + } + } + + + public void setExpectedIndex(int index) { + this.expectedIndex = index; + } + + + public int getExpectedIndex() { + return expectedIndex; + } + + public float getProbability(int index) { + return result[0][index]; + } + + public String getLabel(int index) { + return labels.get(index); + } + + public int getNumberOfClasses() { + return labels.size(); + } +} diff --git a/app/src/main/java/jtheiner/drawingclassification/classification/ModelInput.java b/app/src/main/java/com/s23d/classification/ModelInput.java similarity index 82% rename from app/src/main/java/jtheiner/drawingclassification/classification/ModelInput.java rename to app/src/main/java/com/s23d/classification/ModelInput.java index 5b4d5a9..0a8d45f 100644 --- a/app/src/main/java/jtheiner/drawingclassification/classification/ModelInput.java +++ b/app/src/main/java/com/s23d/classification/ModelInput.java @@ -1,58 +1,59 @@ -package jtheiner.drawingclassification.classification; - -import android.app.Activity; -import android.content.res.AssetFileDescriptor; -import android.content.res.AssetManager; - -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.MappedByteBuffer; -import java.nio.channels.FileChannel; -import java.util.ArrayList; - - -/** - * Helper class to read TensorFlow model and labels from file - */ -abstract class ModelInput { - - /* - * Reads the compressed model as MappedByteBuffer from file. - * - */ - public static MappedByteBuffer loadModelFile(Activity activity, String modelFile) throws IOException { - AssetManager assetManager = activity.getAssets(); - AssetFileDescriptor fileDescriptor = assetManager.openFd(modelFile); - FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor()); - FileChannel fileChannel = inputStream.getChannel(); - long startOffset = fileDescriptor.getStartOffset(); - long declaredLength = fileDescriptor.getDeclaredLength(); - return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength); - } - - /* - * Read labels from file to an array list of labels. - * This list represents the mapping from index position to label. - * - */ - public static ArrayList readLabels(Activity activity, String labelsFile) { - AssetManager assetManager = activity.getAssets(); - ArrayList result = new ArrayList<>(); - try { - InputStream is = assetManager.open(labelsFile); - BufferedReader br = new BufferedReader(new InputStreamReader(is)); - String line; - while ((line = br.readLine()) != null) { - String[] splitted = line.split(","); - result.add(splitted[1]); - } - - return result; - } catch (IOException ex) { - throw new IllegalStateException("Cannot read labels from " + labelsFile + " " + ex); - } - } -} +package com.s23d.classification; + +import android.content.res.AssetFileDescriptor; +import android.content.res.AssetManager; + +import androidx.appcompat.app.AppCompatActivity; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.util.ArrayList; + + +/** + * Helper class to read TensorFlow model and labels from file + */ +abstract class ModelInput { + + /* + * Reads the compressed model as MappedByteBuffer from file. + * + */ + public static MappedByteBuffer loadModelFile(AppCompatActivity activity, String modelFile) throws IOException { + AssetManager assetManager = activity.getAssets(); + AssetFileDescriptor fileDescriptor = assetManager.openFd(modelFile); + FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor()); + FileChannel fileChannel = inputStream.getChannel(); + long startOffset = fileDescriptor.getStartOffset(); + long declaredLength = fileDescriptor.getDeclaredLength(); + return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength); + } + + /* + * Read labels from file to an array list of labels. + * This list represents the mapping from index position to label. + * + */ + public static ArrayList readLabels(AppCompatActivity activity, String labelsFile) { + AssetManager assetManager = activity.getAssets(); + ArrayList result = new ArrayList<>(); + try { + InputStream is = assetManager.open(labelsFile); + BufferedReader br = new BufferedReader(new InputStreamReader(is)); + String line; + while ((line = br.readLine()) != null) { + String[] splitted = line.split(","); + result.add(splitted[1]); + } + + return result; + } catch (IOException ex) { + throw new IllegalStateException("Cannot read labels from " + labelsFile + " " + ex); + } + } +} diff --git a/app/src/main/java/jtheiner/drawingclassification/classification/Result.java b/app/src/main/java/com/s23d/classification/Result.java similarity index 85% rename from app/src/main/java/jtheiner/drawingclassification/classification/Result.java rename to app/src/main/java/com/s23d/classification/Result.java index 7587fc4..9de80e1 100644 --- a/app/src/main/java/jtheiner/drawingclassification/classification/Result.java +++ b/app/src/main/java/com/s23d/classification/Result.java @@ -1,79 +1,77 @@ -package jtheiner.drawingclassification.classification; - -import android.util.ArrayMap; -import android.util.Log; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -/** - * Readable representation of the models output vector. - * Contains label, label position in result vector and probability. - */ -public class Result { - private String label; - private int labelPosition; - private float probability; - private List topK; // contains the index - - public Result(float[] result, ArrayList labels) { - this.labelPosition = argmax(result); // set index position - this.probability = result[labelPosition]; // set probability - this.label = labels.get(labelPosition); // search for label - this.topK = getTopkLabels(3, result); - - } - - // find the index with the maximum probability - private int argmax(float[] result) { - float maxProb = 0.0f; - int maxIndex = -1; - for (int i = 0; i < result.length; i++) { - if (result[i] > maxProb) { - maxProb = result[i]; - maxIndex = i; - } - } - if (maxIndex == -1) { - Log.e("Result class", "argmax found no maximum"); - } - return maxIndex; - } - - - // returns the top k labels with probability - private List getTopkLabels(int k, float[] result) { - List topK = new LinkedList<>(); - for (int kk = 0; kk < k; kk++) { - float maxProb = 0.0f; - int maxIndex = -1; - for (int i = 0; i < result.length; i++) { - if (!topK.contains(i)) { - if (result[i] > maxProb) { - maxProb = result[i]; - maxIndex = i; - } - } - } - topK.add(maxIndex); - } - - return topK; - } - - public String getLabel() { return this.label; } - - public float getProbbability() { - return this.probability; - } - - public List getTopK() { - return this.topK; - } - - public int getLabelPosition() { - return this.labelPosition; - } -} +package com.s23d.classification; + +import android.util.Log; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * Readable representation of the models output vector. + * Contains label, label position in result vector and probability. + */ +public class Result { + private final String label; + private final int labelPosition; + private final float probability; + private final List topK; // contains the index + + public Result(float[] result, ArrayList labels) { + this.labelPosition = argmax(result); // set index position + this.probability = result[labelPosition]; // set probability + this.label = labels.get(labelPosition); // search for label + this.topK = getTopkLabels(3, result); + + } + + // find the index with the maximum probability + private int argmax(float[] result) { + float maxProb = 0.0f; + int maxIndex = -1; + for (int i = 0; i < result.length; i++) { + if (result[i] > maxProb) { + maxProb = result[i]; + maxIndex = i; + } + } + if (maxIndex == -1) { + Log.e("Result class", "argmax found no maximum"); + } + return maxIndex; + } + + + // returns the top k labels with probability + private List getTopkLabels(int k, float[] result) { + List topK = new LinkedList<>(); + for (int kk = 0; kk < k; kk++) { + float maxProb = 0.0f; + int maxIndex = -1; + for (int i = 0; i < result.length; i++) { + if (!topK.contains(i)) { + if (result[i] > maxProb) { + maxProb = result[i]; + maxIndex = i; + } + } + } + topK.add(maxIndex); + } + + return topK; + } + + public String getLabel() { return this.label; } + + public float getProbbability() { + return this.probability; + } + + public List getTopK() { + return this.topK; + } + + public int getLabelPosition() { + return this.labelPosition; + } +} diff --git a/app/src/main/java/jtheiner/drawingclassification/controller/TouchController.java b/app/src/main/java/com/s23d/controller/TouchController.java similarity index 96% rename from app/src/main/java/jtheiner/drawingclassification/controller/TouchController.java rename to app/src/main/java/com/s23d/controller/TouchController.java index 5664a79..32d6c0a 100644 --- a/app/src/main/java/jtheiner/drawingclassification/controller/TouchController.java +++ b/app/src/main/java/com/s23d/controller/TouchController.java @@ -1,4 +1,4 @@ -package jtheiner.drawingclassification.controller; +package com.s23d.controller; import android.graphics.PointF; import android.opengl.Matrix; @@ -8,11 +8,11 @@ import android.view.View; import android.widget.ImageView; -import org.andresoviedo.android_3d_model_engine.model.Camera; +import com.s23d.demo.SceneLoader; +import com.s23d.view.ModelRenderer; +import com.s23d.view.ModelSurfaceView; -import jtheiner.drawingclassification.demo.SceneLoader; -import jtheiner.drawingclassification.view.ModelRenderer; -import jtheiner.drawingclassification.view.ModelSurfaceView; +import org.andresoviedo.android_3d_model_engine.model.Camera; public class TouchController { @@ -58,9 +58,9 @@ public class TouchController { private float previousY1; private float previousX2; private float previousY2; - private float[] previousVector = new float[4]; - private float[] vector = new float[4]; - private float[] rotationVector = new float[4]; + private final float[] previousVector = new float[4]; + private final float[] vector = new float[4]; + private final float[] rotationVector = new float[4]; private float previousRotationSquare; public TouchController(ModelSurfaceView view, ModelRenderer renderer) { @@ -305,12 +305,12 @@ class TouchScreen { private static final int DRAG = 1; private static final int ZOOM = 2; // these matrices will be used to move and zoom image - private android.graphics.Matrix matrix = new android.graphics.Matrix(); - private android.graphics.Matrix savedMatrix = new android.graphics.Matrix(); + private final android.graphics.Matrix matrix = new android.graphics.Matrix(); + private final android.graphics.Matrix savedMatrix = new android.graphics.Matrix(); private int mode = NONE; // remember some things for zooming - private PointF start = new PointF(); - private PointF mid = new PointF(); + private final PointF start = new PointF(); + private final PointF mid = new PointF(); private float oldDist = 1f; private float d = 0f; private float newRot = 0f; diff --git a/app/src/main/java/jtheiner/drawingclassification/demo/ExampleSceneLoader.java b/app/src/main/java/com/s23d/demo/ExampleSceneLoader.java similarity index 97% rename from app/src/main/java/jtheiner/drawingclassification/demo/ExampleSceneLoader.java rename to app/src/main/java/com/s23d/demo/ExampleSceneLoader.java index 5d9e352..2e20390 100644 --- a/app/src/main/java/jtheiner/drawingclassification/demo/ExampleSceneLoader.java +++ b/app/src/main/java/com/s23d/demo/ExampleSceneLoader.java @@ -1,4 +1,4 @@ -package jtheiner.drawingclassification.demo; +package com.s23d.demo; import android.annotation.SuppressLint; import android.app.ProgressDialog; @@ -7,6 +7,8 @@ import android.util.Log; import android.widget.Toast; +import com.s23d.view.ModelActivity; + import org.andresoviedo.android_3d_model_engine.model.Object3DData; import org.andresoviedo.android_3d_model_engine.services.Object3DBuilder; import org.andresoviedo.util.android.ContentUtils; @@ -16,8 +18,6 @@ import java.util.ArrayList; import java.util.List; -import jtheiner.drawingclassification.view.ModelActivity; - /** * This class loads a 3D scene as an example of what can be done with the app * @@ -35,8 +35,8 @@ public void init() { super.init(); new AsyncTask() { - ProgressDialog dialog = new ProgressDialog(parent); - List errors = new ArrayList<>(); + final ProgressDialog dialog = new ProgressDialog(parent); + final List errors = new ArrayList<>(); @Override protected void onPreExecute() { diff --git a/app/src/main/java/jtheiner/drawingclassification/demo/SceneLoader.java b/app/src/main/java/com/s23d/demo/SceneLoader.java similarity index 98% rename from app/src/main/java/jtheiner/drawingclassification/demo/SceneLoader.java rename to app/src/main/java/com/s23d/demo/SceneLoader.java index 65eee71..e8522de 100644 --- a/app/src/main/java/jtheiner/drawingclassification/demo/SceneLoader.java +++ b/app/src/main/java/com/s23d/demo/SceneLoader.java @@ -1,10 +1,13 @@ -package jtheiner.drawingclassification.demo; +package com.s23d.demo; import android.net.Uri; import android.os.SystemClock; import android.util.Log; import android.widget.Toast; +import com.s23d.view.ModelActivity; +import com.s23d.view.ModelRenderer; + import org.andresoviedo.android_3d_model_engine.animation.Animator; import org.andresoviedo.android_3d_model_engine.collision.CollisionDetection; import org.andresoviedo.android_3d_model_engine.model.Camera; @@ -24,9 +27,6 @@ import java.util.Arrays; import java.util.List; -import jtheiner.drawingclassification.view.ModelActivity; -import jtheiner.drawingclassification.view.ModelRenderer; - /** * This class loads a 3D scena as an example of what can be done with the app * @@ -37,7 +37,7 @@ public class SceneLoader implements LoaderTask.Callback { /** * Default model color: yellow */ - private static float[] DEFAULT_COLOR = {1.0f, 1.0f, 0, 1.0f}; + private static final float[] DEFAULT_COLOR = {1.0f, 1.0f, 0, 1.0f}; /** * Parent component */ @@ -81,7 +81,7 @@ public class SceneLoader implements LoaderTask.Callback { /** * Whether to draw face normals. Normally used to debug models */ - private boolean drawNormals = false; + private final boolean drawNormals = false; /** * Whether to draw using textures */ @@ -133,7 +133,7 @@ public class SceneLoader implements LoaderTask.Callback { /** * Animator */ - private Animator animator = new Animator(); + private final Animator animator = new Animator(); /** * Did the user touched the model for the first time? */ diff --git a/app/src/main/java/jtheiner/drawingclassification/view/ModelActivity.java b/app/src/main/java/com/s23d/view/ModelActivity.java similarity index 97% rename from app/src/main/java/jtheiner/drawingclassification/view/ModelActivity.java rename to app/src/main/java/com/s23d/view/ModelActivity.java index b6d2c1f..f367bb0 100644 --- a/app/src/main/java/jtheiner/drawingclassification/view/ModelActivity.java +++ b/app/src/main/java/com/s23d/view/ModelActivity.java @@ -1,4 +1,4 @@ -package jtheiner.drawingclassification.view; +package com.s23d.view; import android.annotation.TargetApi; import android.content.ContentResolver; @@ -18,13 +18,12 @@ import com.google.firebase.FirebaseApp; import com.google.firebase.storage.FirebaseStorage; import com.google.firebase.storage.StorageReference; +import com.s23d.demo.SceneLoader; import org.andresoviedo.util.android.ContentUtils; import java.io.IOException; -import jtheiner.drawingclassification.demo.SceneLoader; - /** * This activity represents the container for our 3D viewer. * @@ -50,7 +49,7 @@ public class ModelActivity extends AppCompatActivity { /** * Background GL clear color. Default is light gray */ - private float[] backgroundColor = new float[]{0f, 0f, 0f, 1.0f}; + private final float[] backgroundColor = new float[]{0f, 0f, 0f, 1.0f}; private ModelSurfaceView gLView; @@ -99,7 +98,7 @@ protected void onCreate(Bundle savedInstanceState) { // Create our 3D sceneario if (paramUri == null) { //scene = new ExampleSceneLoader(this); - Toast.makeText(this, "Unable to generate 3D model", Toast.LENGTH_SHORT).show(); + Toast.makeText(this, "Param is Null", Toast.LENGTH_SHORT).show(); } else { scene = new SceneLoader(this); } diff --git a/app/src/main/java/jtheiner/drawingclassification/view/ModelRenderer.java b/app/src/main/java/com/s23d/view/ModelRenderer.java similarity index 96% rename from app/src/main/java/jtheiner/drawingclassification/view/ModelRenderer.java rename to app/src/main/java/com/s23d/view/ModelRenderer.java index 392a716..123c811 100644 --- a/app/src/main/java/jtheiner/drawingclassification/view/ModelRenderer.java +++ b/app/src/main/java/com/s23d/view/ModelRenderer.java @@ -1,10 +1,12 @@ -package jtheiner.drawingclassification.view; +package com.s23d.view; import android.opengl.GLES20; import android.opengl.GLSurfaceView; import android.opengl.Matrix; import android.util.Log; +import com.s23d.demo.SceneLoader; + import org.andresoviedo.android_3d_model_engine.animation.Animator; import org.andresoviedo.android_3d_model_engine.drawer.DrawerFactory; import org.andresoviedo.android_3d_model_engine.model.AnimatedModel; @@ -23,8 +25,6 @@ import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; -import jtheiner.drawingclassification.demo.SceneLoader; - public class ModelRenderer implements GLSurfaceView.Renderer { private final static String TAG = ModelRenderer.class.getName(); @@ -35,7 +35,7 @@ public class ModelRenderer implements GLSurfaceView.Renderer { private static final float[] COLOR_RED = {1.0f, 0.0f, 0.0f, 1f}; private static final float[] COLOR_BLUE = {0.0f, 1.0f, 0.0f, 1f}; // stereoscopic variables - private static float EYE_DISTANCE = 0.64f; + private static final float EYE_DISTANCE = 0.64f; /** * 3D Axis (to show if needed) */ @@ -54,7 +54,7 @@ public class ModelRenderer implements GLSurfaceView.Renderer { private final float[] projectionMatrixRight = new float[16]; private final float[] viewProjectionMatrixRight = new float[16]; // 3D window (parent component) - private ModelSurfaceView main; + private final ModelSurfaceView main; // width of the screen private int width; // height of the screen @@ -62,20 +62,20 @@ public class ModelRenderer implements GLSurfaceView.Renderer { /** * Drawer factory to get right renderer/shader based on object attributes */ - private DrawerFactory drawer; + private final DrawerFactory drawer; // The wireframe associated shape (it should be made of lines only) - private Map wireframes = new HashMap<>(); + private final Map wireframes = new HashMap<>(); // The loaded textures - private Map textures = new HashMap<>(); + private final Map textures = new HashMap<>(); // The corresponding opengl bounding boxes and drawer - private Map boundingBoxes = new HashMap<>(); + private final Map boundingBoxes = new HashMap<>(); // The corresponding opengl bounding boxes - private Map normals = new HashMap<>(); - private Map skeleton = new HashMap<>(); + private final Map normals = new HashMap<>(); + private final Map skeleton = new HashMap<>(); /** * Whether the info of the model has been written to console log */ - private Map infoLogged = new HashMap<>(); + private final Map infoLogged = new HashMap<>(); /** * Switch to akternate drawing of right and left image */ @@ -84,7 +84,7 @@ public class ModelRenderer implements GLSurfaceView.Renderer { /** * Skeleton Animator */ - private Animator animator = new Animator(); + private final Animator animator = new Animator(); /** * Did the application explode? */ diff --git a/app/src/main/java/jtheiner/drawingclassification/view/ModelSurfaceView.java b/app/src/main/java/com/s23d/view/ModelSurfaceView.java similarity index 84% rename from app/src/main/java/jtheiner/drawingclassification/view/ModelSurfaceView.java rename to app/src/main/java/com/s23d/view/ModelSurfaceView.java index 79f9e80..5c06c29 100644 --- a/app/src/main/java/jtheiner/drawingclassification/view/ModelSurfaceView.java +++ b/app/src/main/java/com/s23d/view/ModelSurfaceView.java @@ -1,12 +1,11 @@ -package jtheiner.drawingclassification.view; +package com.s23d.view; import android.opengl.GLSurfaceView; import android.view.MotionEvent; -import java.io.IOException; - -import jtheiner.drawingclassification.controller.TouchController; +import com.s23d.controller.TouchController; +import java.io.IOException; /** * This is the actual opengl view. From here we can detect touch gestures for example @@ -15,9 +14,9 @@ */ public class ModelSurfaceView extends GLSurfaceView { - private ModelActivity parent; - private ModelRenderer mRenderer; - private TouchController touchHandler; + private final ModelActivity parent; + private final ModelRenderer mRenderer; + private final TouchController touchHandler; public ModelSurfaceView(ModelActivity parent) throws IllegalAccessException, IOException { super(parent); diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml index ddb26ad..c7bd21d 100644 --- a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -1,34 +1,34 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_dashboard_black_24dp.xml b/app/src/main/res/drawable/ic_dashboard_black_24dp.xml index b2a3195..ae6a446 100644 --- a/app/src/main/res/drawable/ic_dashboard_black_24dp.xml +++ b/app/src/main/res/drawable/ic_dashboard_black_24dp.xml @@ -1,9 +1,9 @@ - - - + + + diff --git a/app/src/main/res/drawable/ic_home_black_24dp.xml b/app/src/main/res/drawable/ic_home_black_24dp.xml index 78e078f..0c36320 100644 --- a/app/src/main/res/drawable/ic_home_black_24dp.xml +++ b/app/src/main/res/drawable/ic_home_black_24dp.xml @@ -1,9 +1,9 @@ - - - + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 3a37cf6..0000000 --- a/app/src/main/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable/ic_notifications_black_24dp.xml b/app/src/main/res/drawable/ic_notifications_black_24dp.xml index 1c487d3..0262382 100644 --- a/app/src/main/res/drawable/ic_notifications_black_24dp.xml +++ b/app/src/main/res/drawable/ic_notifications_black_24dp.xml @@ -1,9 +1,9 @@ - - - + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 86cab37..31754ec 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,67 +1,83 @@ - - - - - -