From c6d28f64b7b404f23a8c4fd3b6f4beaf48c47dd3 Mon Sep 17 00:00:00 2001 From: lingarajsankaravelu Date: Sun, 11 Oct 2020 21:28:14 +0530 Subject: [PATCH 1/3] '#54' --- .idea/codeStyles/Project.xml | 15 +- app/build.gradle | 8 +- .../com/arkadip/whatsthere/Classifier.java | 57 ------ .../java/com/arkadip/whatsthere/Classifier.kt | 54 +++++ .../com/arkadip/whatsthere/LogicActivity.java | 185 ------------------ .../com/arkadip/whatsthere/LogicActivity.kt | 156 +++++++++++++++ .../com/arkadip/whatsthere/MainActivity.java | 81 -------- .../com/arkadip/whatsthere/MainActivity.kt | 78 ++++++++ .../whatsthere/{Utils.java => Utils.kt} | 73 +++---- app/src/main/res/values/strings.xml | 1 + app/src/main/res/values/styles.xml | 5 + build.gradle | 3 +- 12 files changed, 332 insertions(+), 384 deletions(-) delete mode 100644 app/src/main/java/com/arkadip/whatsthere/Classifier.java create mode 100644 app/src/main/java/com/arkadip/whatsthere/Classifier.kt delete mode 100644 app/src/main/java/com/arkadip/whatsthere/LogicActivity.java create mode 100644 app/src/main/java/com/arkadip/whatsthere/LogicActivity.kt delete mode 100644 app/src/main/java/com/arkadip/whatsthere/MainActivity.java create mode 100644 app/src/main/java/com/arkadip/whatsthere/MainActivity.kt rename app/src/main/java/com/arkadip/whatsthere/{Utils.java => Utils.kt} (95%) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 0d15693..663459a 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -3,18 +3,9 @@ - diff --git a/app/build.gradle b/app/build.gradle index 3b893bb..173c072 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,4 +1,6 @@ apply plugin: 'com.android.application' +apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-android' android { compileSdkVersion 30 @@ -42,9 +44,13 @@ dependencies { implementation 'androidx.camera:camera-core:1.0.0-beta10' implementation 'androidx.camera:camera-extensions:1.0.0-alpha17' implementation 'androidx.camera:camera-lifecycle:1.0.0-beta10' - implementation 'androidx.camera:camera-view:1.0.0-alpha15' + implementation 'androidx.camera:camera-view:1.0.0-alpha17' implementation 'org.pytorch:pytorch_android:1.6.0' implementation 'org.pytorch:pytorch_android_torchvision:1.6.0' + + //kotlin dependencies + implementation "androidx.core:core-ktx:1.3.2" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" } repositories { mavenCentral() diff --git a/app/src/main/java/com/arkadip/whatsthere/Classifier.java b/app/src/main/java/com/arkadip/whatsthere/Classifier.java deleted file mode 100644 index 0db121b..0000000 --- a/app/src/main/java/com/arkadip/whatsthere/Classifier.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2020 Arkadip Bhattacharya - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.arkadip.whatsthere; - -import android.media.Image; - -import org.pytorch.IValue; -import org.pytorch.Module; -import org.pytorch.Tensor; -import org.pytorch.torchvision.TensorImageUtils; - -class Classifier { - private Module model; - - Classifier(String modelPath) { - model = Module.load(modelPath); - } - - private Tensor preprocessor(Image image, int rotation) { - return TensorImageUtils.imageYUV420CenterCropToFloat32Tensor(image, rotation, 224, - 224, TensorImageUtils.TORCHVISION_NORM_MEAN_RGB, TensorImageUtils.TORCHVISION_NORM_STD_RGB); - } - - private int argMax(float[] inputs) { - int maxIndex = -1; - float maxvalue = 0.0f; - for (int i = 0; i < inputs.length; i++) { - if (inputs[i] > maxvalue) { - maxIndex = i; - maxvalue = inputs[i]; - } - } - return maxIndex; - } - - int predict(Image image, int rotation) { - Tensor tensor = preprocessor(image, rotation); - Tensor output = model.forward(IValue.from(tensor)).toTensor(); - float[] scores = output.getDataAsFloatArray(); - return argMax(scores); - } -} - diff --git a/app/src/main/java/com/arkadip/whatsthere/Classifier.kt b/app/src/main/java/com/arkadip/whatsthere/Classifier.kt new file mode 100644 index 0000000..0f9a8eb --- /dev/null +++ b/app/src/main/java/com/arkadip/whatsthere/Classifier.kt @@ -0,0 +1,54 @@ +/* + * Copyright 2020 Arkadip Bhattacharya + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.arkadip.whatsthere + +import android.media.Image +import org.pytorch.IValue +import org.pytorch.Module +import org.pytorch.Tensor +import org.pytorch.torchvision.TensorImageUtils + +class Classifier constructor(modelPath:String?) { + private val model:Module = Module.load(modelPath) + + private fun preprocessor(image: Image, rotation:Int):Tensor { + return TensorImageUtils.imageYUV420CenterCropToFloat32Tensor(image, rotation, 224, + 224, TensorImageUtils.TORCHVISION_NORM_MEAN_RGB, TensorImageUtils.TORCHVISION_NORM_STD_RGB) + } + + private fun argMax(inputs:FloatArray):Int { + var maxIndex:Int = -1 + var maxValue = 0.0f + inputs.forEachIndexed { i, input -> + if (input > maxValue) { + maxIndex = i + maxValue = input + } + + } + return maxIndex + } + + fun predict(image: Image, rotation: Int):Int { + + val tensor = preprocessor(image,rotation) + val output = model.forward(IValue.from(tensor)).toTensor() + val scores: FloatArray = output.dataAsFloatArray + return argMax(scores) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/arkadip/whatsthere/LogicActivity.java b/app/src/main/java/com/arkadip/whatsthere/LogicActivity.java deleted file mode 100644 index e0c13c8..0000000 --- a/app/src/main/java/com/arkadip/whatsthere/LogicActivity.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2020 Arkadip Bhattacharya - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.arkadip.whatsthere; - -import android.annotation.SuppressLint; -import android.os.Bundle; -import android.util.DisplayMetrics; -import android.util.Log; -import android.util.Size; -import android.widget.TextView; -import android.widget.ToggleButton; - -import androidx.appcompat.app.AppCompatActivity; -import androidx.camera.core.AspectRatio; -import androidx.camera.core.Camera; -import androidx.camera.core.CameraSelector; -import androidx.camera.core.ImageAnalysis; -import androidx.camera.core.Preview; -import androidx.camera.core.TorchState; -import androidx.camera.lifecycle.ProcessCameraProvider; -import androidx.camera.view.PreviewView; -import androidx.core.content.ContextCompat; - -import com.google.common.util.concurrent.ListenableFuture; - -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -public class LogicActivity extends AppCompatActivity { - - private PreviewView previewView; - private TextView textView; - private ToggleButton toggleButton; - - private ExecutorService cameraExecutor; - private Classifier classifier; - - private ProcessCameraProvider cameraProvider; - private ListenableFuture cameraProviderListenableFuture; - private Camera camera; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_logic); - - cameraExecutor = Executors.newSingleThreadExecutor(); - - previewView = findViewById(R.id.preview_view); - textView = findViewById(R.id.textView); - toggleButton = findViewById(R.id.flashToggle); - - toggleButton.setChecked(false); - - classifier = new Classifier(Utils.assetFilePath(this, "mobilenet-v2.pt")); - - previewView.post(this::setupCamera); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - cameraExecutor.shutdown(); - } - - private void setupCamera() { - cameraProviderListenableFuture = ProcessCameraProvider.getInstance(this); - cameraProviderListenableFuture.addListener(() -> { - try { - cameraProvider = cameraProviderListenableFuture.get(); - } catch (ExecutionException | InterruptedException e) { - e.printStackTrace(); - } - - bindCameraUseCases(); - }, ContextCompat.getMainExecutor(this)); - } - - @SuppressLint({"UnsafeExperimentalUsageError", "Assert"}) - private void bindCameraUseCases() { - DisplayMetrics displayMetrics = new DisplayMetrics(); - previewView.getDisplay().getRealMetrics(displayMetrics); - Log.d("DISPLAY", "Screen metrics: " + displayMetrics.widthPixels - + " x " + displayMetrics.heightPixels); - - int aspectRatio = aspectRatio(displayMetrics.widthPixels, displayMetrics.heightPixels); - Log.d("DISPLAY", "Preview aspect ratio: " + aspectRatio); - - int rotation = previewView.getDisplay().getRotation(); - - //camera selector - CameraSelector cameraSelector = new CameraSelector.Builder() - .requireLensFacing(CameraSelector.LENS_FACING_BACK) - .build(); - - //Preview - Preview preview = new Preview.Builder() - .setTargetAspectRatio(aspectRatio) - .setTargetRotation(rotation) - .build(); - - //Image Analysis - ImageAnalysis imageAnalysis = new ImageAnalysis.Builder() - .setTargetResolution(new Size(224, 224)) - //.setTargetAspectRatio(aspectRatio) - .setTargetRotation(rotation) - .build(); - - imageAnalysis.setAnalyzer(cameraExecutor, image -> { - int r = image.getImageInfo().getRotationDegrees(); - int value = classifier.predict(image.getImage(), r); - Log.d("OUTPUT", String.valueOf(value)); - String out = Utils.IMAGENET_CLASSES[value]; - runOnUiThread(() -> textView.setText(out)); - - image.close(); - }); - - // Must unbind the use-cases before rebinding them - cameraProvider.unbindAll(); - - camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalysis); - preview.setSurfaceProvider(previewView.createSurfaceProvider()); - - toggleFlash(); - } - - - private void toggleFlash() { - toggleButton.setOnClickListener(v -> { - try { - if (camera.getCameraInfo().hasFlashUnit()) { - boolean flashOn = ((ToggleButton) v).isChecked(); - int torchState = camera.getCameraInfo().getTorchState().getValue(); - if (flashOn) { - if (torchState != TorchState.ON) { - camera.getCameraControl().enableTorch(true); - } - } else { - if (torchState != TorchState.OFF) { - camera.getCameraControl().enableTorch(false); - } - } - } - } catch (NullPointerException e) { - e.printStackTrace(); - } - }); - } - - /** - * Detecting the most suitable ratio for dimensions provided in @params by counting absolute - * of preview ratio to one of the provided values. - * - * @param width - preview width - * @param height - preview height - * @return suitable aspect ratio - */ - private int aspectRatio(int width, int height) { - double RATIO_4_3_VALUE = 4.0 / 3.0; - double RATIO_16_9_VALUE = 16.0 / 9.0; - - double previewRatio = (double) Math.max(width, height) / Math.min(width, height); - if (Math.abs(previewRatio - RATIO_4_3_VALUE) <= Math.abs(previewRatio - RATIO_16_9_VALUE)) { - return AspectRatio.RATIO_4_3; - } else { - return AspectRatio.RATIO_16_9; - } - } -} diff --git a/app/src/main/java/com/arkadip/whatsthere/LogicActivity.kt b/app/src/main/java/com/arkadip/whatsthere/LogicActivity.kt new file mode 100644 index 0000000..59b4441 --- /dev/null +++ b/app/src/main/java/com/arkadip/whatsthere/LogicActivity.kt @@ -0,0 +1,156 @@ +/* + * Copyright 2020 Arkadip Bhattacharya + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package com.arkadip.whatsthere + +import android.annotation.SuppressLint +import android.os.Bundle +import android.util.DisplayMetrics +import android.util.Log +import android.util.Size +import androidx.appcompat.app.AppCompatActivity +import androidx.camera.core.* +import androidx.camera.lifecycle.ProcessCameraProvider +import androidx.core.content.ContextCompat +import com.google.common.util.concurrent.ListenableFuture +import kotlinx.android.synthetic.main.activity_logic.* +import java.util.concurrent.ExecutionException +import java.util.concurrent.ExecutorService +import java.util.concurrent.Executors +import kotlin.math.abs + +class LogicActivity:AppCompatActivity() { + lateinit var cameraProvider:ProcessCameraProvider + lateinit var cameraExecutor:ExecutorService + lateinit var classifier: Classifier + lateinit var cameraProviderListenableFuture:ListenableFuture + lateinit var camera:Camera + private var hasFlashUnit:Boolean = true + + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_logic) + init() + } + + private fun init() { + flashToggle.setOnCheckedChangeListener { buttonView, isChecked -> toggleFlash(isChecked) } + cameraExecutor = Executors.newSingleThreadExecutor() + classifier = Classifier(Utils.assetFilePath(this,"mobilenet-v2.pt")) + preview_view.post(this::setUpCamera) + + } + + private fun toggleFlash(enableFlash: Boolean) { + if (!hasFlashUnit) { return} + camera.cameraControl.enableTorch(enableFlash) + } + + private fun setUpCamera() { + cameraProviderListenableFuture = ProcessCameraProvider.getInstance(this) + cameraProviderListenableFuture.addListener(Runnable { + try { + cameraProvider = cameraProviderListenableFuture.get() + } catch (e: ExecutionException) { + e.printStackTrace() + } catch (e: InterruptedException) { + e.printStackTrace() + } + bindCameraUseCases() + }, ContextCompat.getMainExecutor(this)) + + + } + + @SuppressLint("UnsafeExperimentalUsageError") + private fun bindCameraUseCases() { + val displayMetrics = DisplayMetrics() + preview_view.display.getRealMetrics(displayMetrics) + Log.d("DISPLAY", "Screen metrics: " + displayMetrics.widthPixels + + " x " + displayMetrics.heightPixels) + val aspectRatio = aspectRatio(displayMetrics.widthPixels, displayMetrics.heightPixels) + Log.d("DISPLAY", "Preview aspect ratio: $aspectRatio") + val rotation = preview_view.display.rotation + + //camera selector + val cameraSelector = CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build() + + //preview + val preview = Preview.Builder().apply { + setTargetAspectRatio(aspectRatio) + setTargetRotation(rotation) + }.build() + + //Image Analysis + val imageAnalysis = ImageAnalysis.Builder().apply { + setTargetResolution(Size(224,224)) + setTargetRotation(rotation) + }.build() + + + + + imageAnalysis.setAnalyzer(cameraExecutor, ImageAnalysis.Analyzer { image: ImageProxy -> + val r = image.imageInfo.rotationDegrees + val value = classifier.predict(image.image!!, r) + Log.d("OUTPUT", value.toString()) + val out = Utils.IMAGENET_CLASSES[value] + runOnUiThread { textView.text = out } + image.close() + }) + + // Must unbind the use-cases before rebinding them + cameraProvider.unbindAll() + + camera = cameraProvider.bindToLifecycle(this, cameraSelector,preview,imageAnalysis) + .also { hasFlashUnit = it.cameraInfo.hasFlashUnit() } + preview.setSurfaceProvider(preview_view.surfaceProvider) + + + + } + + /** + * Detecting the most suitable ratio for dimensions provided in @params by counting absolute + * of preview ratio to one of the provided values. + * + * @param width - preview width + * @param height - preview height + * @return suitable aspect ratio + */ + private fun aspectRatio(width:Int, height:Int):Int { + val RATIO_4_3_VALUE = 4.0 / 3.0 + val RATIO_16_9_VALUE = 16.0 / 9.0 + val previewRatio: Double = Math.max(width, height).toDouble() / Math.min(width, height) + if (abs(previewRatio-RATIO_4_3_VALUE) <= abs(previewRatio - RATIO_16_9_VALUE)) { + return AspectRatio.RATIO_4_3 + } + else { + return AspectRatio.RATIO_16_9 + } + + } + + override fun onDestroy() { + cameraExecutor.shutdown() + super.onDestroy() + } + + + +} \ No newline at end of file diff --git a/app/src/main/java/com/arkadip/whatsthere/MainActivity.java b/app/src/main/java/com/arkadip/whatsthere/MainActivity.java deleted file mode 100644 index 8d65835..0000000 --- a/app/src/main/java/com/arkadip/whatsthere/MainActivity.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2020 Arkadip Bhattacharya - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.arkadip.whatsthere; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import androidx.core.app.ActivityCompat; - -import android.Manifest; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.os.Bundle; -import android.os.Handler; -import android.util.Log; -import android.view.WindowManager; - -public class MainActivity extends AppCompatActivity { - - private String[] PERMISSIONS = { - Manifest.permission.CAMERA, - }; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, - WindowManager.LayoutParams.FLAG_FULLSCREEN); - setContentView(R.layout.splash_main); - - new Handler().postDelayed(() -> { - if (!hasPermissions(MainActivity.this, PERMISSIONS)) { - int PERMISSION_ALL = 1; - ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS, PERMISSION_ALL); - } else { - openActivity(); - } - }, 1000); - } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - Log.d("PERMISSION", "GIVEN"); - openActivity(); - } - - private void openActivity(){ - Intent i = new Intent(MainActivity.this, LogicActivity.class); - startActivity(i); - finish(); - } - - private boolean hasPermissions(Context context, String... permissions) { - if (context != null && permissions != null) { - for (String permission : permissions) { - if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) { - return false; - } - } - } - else{ - return false; - } - return true; - } -} diff --git a/app/src/main/java/com/arkadip/whatsthere/MainActivity.kt b/app/src/main/java/com/arkadip/whatsthere/MainActivity.kt new file mode 100644 index 0000000..1b964f6 --- /dev/null +++ b/app/src/main/java/com/arkadip/whatsthere/MainActivity.kt @@ -0,0 +1,78 @@ +package com.arkadip.whatsthere + +import android.content.Intent +import android.content.pm.PackageManager +import android.os.Build +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import androidx.core.app.ActivityCompat + +class MainActivity:AppCompatActivity() { + private val permissions = arrayOf(android.Manifest.permission.CAMERA) + private val permissionsRequestCode = 103 + private val delayInMilliSeconds:Long = 1000 + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.splash_main) + Handler(Looper.getMainLooper()).postDelayed({ + if (hasPermissions()){ + openActivity() + } + else { + ActivityCompat.requestPermissions(this,permissions,permissionsRequestCode) + } + + + },delayInMilliSeconds) + } + + private fun openActivity() { + startActivity(Intent(this,LogicActivity::class.java)) + finish() + + } + + + override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + if (requestCode==permissionsRequestCode){ + var isPermitted = true + for (result in grantResults){ + if (result!=PackageManager.PERMISSION_GRANTED){ + isPermitted = false + break + } + } + if (isPermitted) { + openActivity() + } + else { + Toast.makeText(this,this.getString(R.string.error_msg_permssion_required),Toast.LENGTH_LONG).show() + } + + } + + } + + private fun hasPermissions():Boolean{ + return if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.M) { + var permissionsGranted = true + for(permission in permissions) { + if (ActivityCompat.checkSelfPermission(this, permission) !=PackageManager.PERMISSION_GRANTED) { + permissionsGranted = false + break + } + } + permissionsGranted + } + else { + true + } + + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/arkadip/whatsthere/Utils.java b/app/src/main/java/com/arkadip/whatsthere/Utils.kt similarity index 95% rename from app/src/main/java/com/arkadip/whatsthere/Utils.java rename to app/src/main/java/com/arkadip/whatsthere/Utils.kt index 0e17096..0270c54 100644 --- a/app/src/main/java/com/arkadip/whatsthere/Utils.java +++ b/app/src/main/java/com/arkadip/whatsthere/Utils.kt @@ -1,33 +1,14 @@ -/* - * Copyright 2020 Arkadip Bhattacharya - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +package com.arkadip.whatsthere -package com.arkadip.whatsthere; +import android.content.Context +import android.util.Log +import java.io.File +import java.io.FileOutputStream +import java.io.IOException -import android.content.Context; -import android.util.Log; +object Utils { -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -class Utils { - - static String[] IMAGENET_CLASSES = new String[]{ + var IMAGENET_CLASSES = arrayOf( "tench, Tinca tinca", "goldfish, Carassius auratus", "great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias", "tiger shark, Galeocerdo cuvieri", "hammerhead, hammerhead shark", @@ -1001,27 +982,25 @@ class Utils { "bolete", "ear, spike, capitulum", "toilet tissue, toilet paper, bathroom tissue" - }; - - static String assetFilePath(Context context, String assetName) { - File file = new File(context.getFilesDir(), assetName); + ) - try (InputStream is = context.getAssets().open(assetName)) { - try (OutputStream os = new FileOutputStream(file)) { - byte[] buffer = new byte[4 * 1024]; - int read; - while ((read = is.read(buffer)) != -1) { - os.write(buffer, 0, read); - } - os.flush(); - } catch (IOException e) { - e.printStackTrace(); + fun assetFilePath(context:Context, assetName:String):String? { + val file = File(context.filesDir, assetName) + try { + val inStream = context.assets.open(assetName) + val outStream = FileOutputStream(file) + val buffer = ByteArray(4 * 1024) + var read = 0 + while (inStream.read(buffer).also { read = it }!=-1){ + outStream.write(buffer,0,read) } - return file.getAbsolutePath(); - } catch (IOException e) { - Log.e("PYTORCH", "Error process asset " + assetName + " to file path"); + outStream.flush() + return file.absolutePath } - return null; - } -} + catch (e:IOException) { + Log.e("PYTORCH", "Error process asset $assetName to file path") + } + return null + } +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6c15bcf..2bbda83 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -4,4 +4,5 @@ W H A T S T H E R E By Arkadip + Please provide required permission to cotinue! diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 408721b..8a5d9fb 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -2,9 +2,14 @@ diff --git a/build.gradle b/build.gradle index c824cbc..4fc38a0 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - + ext.kotlin_version = '1.3.72' repositories { google() jcenter() @@ -9,6 +9,7 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:4.0.2' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong From eeb2953cf0b8cf320c838131ee98f7a3f7caf446 Mon Sep 17 00:00:00 2001 From: lingarajsankaravelu Date: Sun, 11 Oct 2020 21:31:18 +0530 Subject: [PATCH 2/3] '#54' --- .../whatsthere/ExampleInstrumentedTest.java | 27 ------------------- .../whatsthere/ExampleInstrumentedTest.kt | 22 +++++++++++++++ .../arkadip/whatsthere/ExampleUnitTest.java | 17 ------------ .../com/arkadip/whatsthere/ExampleUnitTest.kt | 16 +++++++++++ 4 files changed, 38 insertions(+), 44 deletions(-) delete mode 100644 app/src/androidTest/java/com/arkadip/whatsthere/ExampleInstrumentedTest.java create mode 100644 app/src/androidTest/java/com/arkadip/whatsthere/ExampleInstrumentedTest.kt delete mode 100644 app/src/test/java/com/arkadip/whatsthere/ExampleUnitTest.java create mode 100644 app/src/test/java/com/arkadip/whatsthere/ExampleUnitTest.kt diff --git a/app/src/androidTest/java/com/arkadip/whatsthere/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/arkadip/whatsthere/ExampleInstrumentedTest.java deleted file mode 100644 index 7e1cfac..0000000 --- a/app/src/androidTest/java/com/arkadip/whatsthere/ExampleInstrumentedTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.arkadip.whatsthere; - -import android.content.Context; - -import androidx.test.platform.app.InstrumentationRegistry; -import androidx.test.ext.junit.runners.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.getInstrumentation().getTargetContext(); - - assertEquals("com.arkadip.whatsthere", appContext.getPackageName()); - } -} diff --git a/app/src/androidTest/java/com/arkadip/whatsthere/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/arkadip/whatsthere/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..37c180b --- /dev/null +++ b/app/src/androidTest/java/com/arkadip/whatsthere/ExampleInstrumentedTest.kt @@ -0,0 +1,22 @@ +package com.arkadip.whatsthere + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.platform.app.InstrumentationRegistry +import org.junit.Assert +import org.junit.Test +import org.junit.runner.RunWith + +/** + * Instrumented test, which will execute on an Android device. + * + * @see [Testing documentation](http://d.android.com/tools/testing) + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + Assert.assertEquals("com.arkadip.whatsthere", appContext.packageName) + } +} \ No newline at end of file diff --git a/app/src/test/java/com/arkadip/whatsthere/ExampleUnitTest.java b/app/src/test/java/com/arkadip/whatsthere/ExampleUnitTest.java deleted file mode 100644 index e1322ea..0000000 --- a/app/src/test/java/com/arkadip/whatsthere/ExampleUnitTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.arkadip.whatsthere; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file diff --git a/app/src/test/java/com/arkadip/whatsthere/ExampleUnitTest.kt b/app/src/test/java/com/arkadip/whatsthere/ExampleUnitTest.kt new file mode 100644 index 0000000..2755121 --- /dev/null +++ b/app/src/test/java/com/arkadip/whatsthere/ExampleUnitTest.kt @@ -0,0 +1,16 @@ +package com.arkadip.whatsthere + +import org.junit.Assert +import org.junit.Test + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see [Testing documentation](http://d.android.com/tools/testing) + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + Assert.assertEquals(4, 2 + 2.toLong()) + } +} \ No newline at end of file From 344dc18aaa6bed4721391cf717763bb08c7817a1 Mon Sep 17 00:00:00 2001 From: lingarajsankaravelu Date: Sun, 11 Oct 2020 22:35:03 +0530 Subject: [PATCH 3/3] updated readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 72c2a0d..4a460c6 100644 --- a/README.md +++ b/README.md @@ -35,11 +35,11 @@ The App is created on top of `Deep Learning` and `Aritificial Neural Networks`. [![Android](https://forthebadge.com/images/badges/built-for-android.svg)]() [![PyTorch](https://img.shields.io/badge/Powered%20By-PyTorch-orange?style=for-the-badge&logo=pytorch)]() -[![JAVA](https://forthebadge.com/images/badges/made-with-java.svg)]() +[![KOTLIN](https://img.shields.io/badge/Made%20with-Kotlin-blue?style=for-the-badge&logo=kotlin)]() - The App is created for and only for **`Android`**, `2 minutes of silence for other platforms` - To power-up the Deepest Neural Network, the App uses **`PyTorch`** -- Written in *`Shuddh`* **`JAVA`** +- Written in *`Shuddh`* **`KOTLIN`** - Uses [**`CameraX`**](https://developer.android.com/training/camerax) to Capture frames ## Neural Network