diff --git a/android/app/build.gradle b/android/app/build.gradle
index 09b66e1..e1e3182 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -31,4 +31,5 @@ dependencies {
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.android.support:cardview-v7:26.1.0'
implementation 'com.android.support:recyclerview-v7:26.1.0'
+ implementation 'com.ibm.watson.developer_cloud:java-sdk:6.9.0'
}
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index edc85c5..a6231df 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -3,6 +3,7 @@
package="com.krokogator.photoeat">
+
classifications;
+ ArrayAdapter adapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.photo_previev);
+ setContentView(R.layout.activity_photopreview);
+ this.listView = findViewById(R.id.listView);
String imagePath = (String) getIntent().getExtras().get("imagePath");
ImageView preview = findViewById(R.id.photo_preview);
preview.setImageBitmap(getPic(imagePath));
+
+ classifications = new ArrayList<>();
+ adapter = new ArrayAdapter(getApplicationContext(), android.R.layout.simple_spinner_item, classifications);
+ listView.setAdapter(adapter);
+
+ File file = new File(imagePath);
+ new ClassifyImage().execute(file);
+
}
private Bitmap getPic(String picPath) {
@@ -38,7 +60,7 @@ public class PhotoPreviewActivity extends AppCompatActivity {
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
- int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
+ int scaleFactor = Math.min(photoW / targetW, photoH / targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
@@ -51,23 +73,21 @@ public class PhotoPreviewActivity extends AppCompatActivity {
return bitmap;
}
- private Bitmap getCorrectlyRotated(String imagePath, Bitmap bitmap){
+ private Bitmap getCorrectlyRotated(String imagePath, Bitmap bitmap) {
// Rotate Image if Needed
- try
- {
+ try {
// Determine Orientation
ExifInterface exif = new ExifInterface(imagePath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
// Determine Rotation
int rotation = 0;
- if (orientation == 6) rotation = 90;
- else if (orientation == 3) rotation = 180;
- else if (orientation == 8) rotation = 270;
+ if (orientation == 6) rotation = 90;
+ else if (orientation == 3) rotation = 180;
+ else if (orientation == 8) rotation = 270;
// Rotate Image if Necessary
- if (rotation != 0)
- {
+ if (rotation != 0) {
// Create Matrix
Matrix matrix = new Matrix();
matrix.postRotate(rotation);
@@ -80,12 +100,44 @@ public class PhotoPreviewActivity extends AppCompatActivity {
bitmap = rotated;
rotated = null;
}
- }
- catch (Exception e)
- {
+ } catch (Exception e) {
// TODO: Log Error Messages Here
}
return bitmap;
}
+
+
+ private class ClassifyImage extends AsyncTask {
+ protected CustomFoodClassification doInBackground(File... files) {
+ WatsonService service = null;
+
+ try {
+ service = new WatsonService(0.2f);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ CustomFoodClassification customFoodClassification = null;
+ try {
+ customFoodClassification = service.getCustomFoodClassification(files[0]);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+
+ // Escape early if cancel() is called
+ if (isCancelled()) return null;
+
+ return customFoodClassification;
+ }
+
+ protected void onPostExecute(CustomFoodClassification result) {
+ Log.i("watson.result", result.toString());
+ for(String imageClass : result.getClassifications().keySet()){
+ Float classValue = result.getClassifications().get(imageClass);
+ classifications.add(imageClass + " : " + classValue);
+ }
+ adapter.notifyDataSetChanged();
+ }
+ }
}
diff --git a/android/app/src/main/java/com/krokogator/photoeat/service/CustomFoodClassification.java b/android/app/src/main/java/com/krokogator/photoeat/service/CustomFoodClassification.java
new file mode 100644
index 0000000..9e54673
--- /dev/null
+++ b/android/app/src/main/java/com/krokogator/photoeat/service/CustomFoodClassification.java
@@ -0,0 +1,28 @@
+package com.krokogator.photoeat.service;
+
+import java.util.Map;
+
+public class CustomFoodClassification {
+ private String imageName;
+ private Map classifications;
+
+ public CustomFoodClassification(String imageName, Map classifications){
+ this.imageName = imageName;
+ this.classifications = classifications;
+ }
+
+ @Override
+ public String toString() {
+ return "ImageName: " + imageName + '\n' +
+ ", classifications=" + classifications +
+ '}';
+ }
+
+ public String getImageName() {
+ return imageName;
+ }
+
+ public Map getClassifications() {
+ return classifications;
+ }
+}
diff --git a/android/app/src/main/java/com/krokogator/photoeat/service/WatsonService.java b/android/app/src/main/java/com/krokogator/photoeat/service/WatsonService.java
new file mode 100644
index 0000000..6e53dfe
--- /dev/null
+++ b/android/app/src/main/java/com/krokogator/photoeat/service/WatsonService.java
@@ -0,0 +1,68 @@
+package com.krokogator.photoeat.service;
+
+import android.os.AsyncTask;
+import android.util.Log;
+
+import com.ibm.watson.developer_cloud.service.security.IamOptions;
+import com.ibm.watson.developer_cloud.visual_recognition.v3.VisualRecognition;
+import com.ibm.watson.developer_cloud.visual_recognition.v3.model.ClassResult;
+import com.ibm.watson.developer_cloud.visual_recognition.v3.model.ClassifiedImage;
+import com.ibm.watson.developer_cloud.visual_recognition.v3.model.ClassifiedImages;
+import com.ibm.watson.developer_cloud.visual_recognition.v3.model.ClassifierResult;
+import com.ibm.watson.developer_cloud.visual_recognition.v3.model.Classifiers;
+import com.ibm.watson.developer_cloud.visual_recognition.v3.model.ClassifyOptions;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class WatsonService {
+ private Float threshold;
+ private VisualRecognition service;
+
+ private WatsonService(){
+ IamOptions options = new IamOptions.Builder()
+ .apiKey("ispGc_Nr0g_33bc4OUvwcT666gpwYIGqmJKcvrzGiqbL")
+ .build();
+
+ service = new VisualRecognition("2018-03-19", options);
+ }
+
+ public WatsonService(Float threshold) throws Exception {
+ this();
+ if (threshold < 0 || threshold > 1) throw new Exception("Invalid threshold, allowed value between 0 and 1");
+ this.threshold = threshold;
+ }
+
+ private ClassifiedImages getClassification(File file) throws FileNotFoundException {
+ ClassifyOptions classifyOptions = new ClassifyOptions.Builder()
+ .imagesFile(file)
+ .threshold(threshold)
+ .classifierIds(Arrays.asList("food"))
+ .build();
+
+ return service.classify(classifyOptions).execute();
+ }
+
+
+ public CustomFoodClassification getCustomFoodClassification(File file) throws FileNotFoundException {
+ String fileName = "";
+ Map classifications = new HashMap<>();
+
+ List classifiedImages = getClassification(file).getImages();
+ for(ClassifiedImage image : classifiedImages){
+ fileName = image.getImage();
+ for(ClassifierResult classifierResult : image.getClassifiers()){
+ for(ClassResult classResult : classifierResult.getClasses()){
+ classifications.put(classResult.getClassName(), classResult.getScore());
+ }
+ }
+ }
+
+ return new CustomFoodClassification(fileName, classifications);
+ }
+}
+
diff --git a/android/app/src/main/res/layout/photo_previev.xml b/android/app/src/main/res/layout/activity_photopreview.xml
similarity index 60%
rename from android/app/src/main/res/layout/photo_previev.xml
rename to android/app/src/main/res/layout/activity_photopreview.xml
index f2aff29..55c7757 100644
--- a/android/app/src/main/res/layout/photo_previev.xml
+++ b/android/app/src/main/res/layout/activity_photopreview.xml
@@ -10,13 +10,19 @@
android:id="@+id/photo_preview"
android:layout_width="0dp"
android:layout_height="0dp"
- android:layout_marginStart="32dp"
- android:layout_marginTop="32dp"
- android:layout_marginEnd="32dp"
- android:layout_marginBottom="32dp"
- app:layout_constraintBottom_toBottomOf="parent"
+ android:layout_marginStart="64dp"
+ android:layout_marginEnd="64dp"
+ android:contentDescription="Photo preview"
+ app:layout_constraintDimensionRatio="h,1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="@tools:sample/backgrounds/scenic" />
+
+
+
\ No newline at end of file