Code cleanup and refactoring of some classes.

parent cf363454
......@@ -34,7 +34,7 @@
</activity>
<!-- Take photo intent (Register) -->
<activity android:name=".intents.IntentTransferingFeatures"
<activity android:name=".intents.IntentTransferFeatures"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="com.auriclon.features" />
......@@ -43,7 +43,7 @@
</activity>
<!-- Private API -->
<!-- Call by IntentTransferingFeatures (Follow-up) -->
<!-- Call by IntentTransferFeatures (Follow-up) -->
<activity android:name=".activities.SelectFollowupActivity"
android:screenOrientation="portrait">
<intent-filter>
......@@ -51,7 +51,7 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<!-- Call by IntentTransferingFeatures, IntentSearchFeatures (Follow-up/Register) -->
<!-- Call by IntentTransferFeatures, IntentSearchFeatures (Follow-up/Register) -->
<activity android:name=".activities.SIFTActivity"
android:screenOrientation="portrait">
<intent-filter>
......
package com.aluxoft.earrecognition;
import com.aluxoft.earrecognition.common.EarData;
import com.aluxoft.earrecognition.common.PatientHashMap;
import com.aluxoft.earrecognition.common.EarFeature;
import com.aluxoft.earrecognition.common.EarIdList;
import com.aluxoft.earrecognition.common.TopMatchesList;
import com.aluxoft.earrecognition.utils.OpenCvUtils;
import org.opencv.core.Mat;
......@@ -16,13 +16,13 @@ import org.opencv.highgui.Highgui;
*/
public class EarIdentifier {
private EarData database;
private PatientHashMap database;
public EarIdentifier(EarData _database) {
public EarIdentifier(PatientHashMap _database) {
this.database = _database;
}
public void setDatabase(EarData _database) {
public void setDatabase(PatientHashMap _database) {
this.database = _database;
}
......@@ -31,7 +31,7 @@ public class EarIdentifier {
* @param feature The result of the identification.
* @return
*/
public EarIdList identify(EarFeature feature) {
public TopMatchesList identify(EarFeature feature) {
return null;
}
......
/*
Copyright by Boston University, 2016
Authors: Josejulio Martínez, Daniel Kornhauser
Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
*/
package com.aluxoft.earrecognition.activities;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import com.aluxoft.earrecognition.EarIdentifier;
import com.aluxoft.earrecognition.R;
import com.aluxoft.earrecognition.loader.EarDataLoaderCommcare;
import com.aluxoft.earrecognition.utils.ImageUtils;
import com.crashlytics.android.Crashlytics;
import io.fabric.sdk.android.Fabric;
import java.io.File;
import java.io.IOException;
/**
* Activity where we capture ear for recognition.
......
/*
Copyright by Boston University, 2016
Authors: Josejulio Martínez, Daniel Kornhauser
Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
*/
package com.aluxoft.earrecognition.activities;
import android.app.Activity;
......@@ -7,19 +12,16 @@ import android.os.Bundle;
import com.aluxoft.earrecognition.EarIdentifier;
import com.aluxoft.earrecognition.R;
import com.aluxoft.earrecognition.common.EarData;
import com.aluxoft.earrecognition.common.PatientHashMap;
import com.aluxoft.earrecognition.common.EarFeature;
import com.aluxoft.earrecognition.common.EarIdList;
import com.aluxoft.earrecognition.common.TopMatchesList;
import com.aluxoft.earrecognition.common.NameDistance;
import com.aluxoft.earrecognition.common.Person;
import com.aluxoft.earrecognition.loader.EarDataLoaderCommcare;
import com.aluxoft.earrecognition.loader.PatientLoaderCommcare;
import com.aluxoft.earrecognition.utils.FileCache;
import com.google.gson.Gson;
import java.io.File;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
......@@ -45,9 +47,9 @@ public class SIFTActivity extends Activity {
loading.setCancelable(false);
loading.setProgressStyle(ProgressDialog.STYLE_SPINNER);
Task.callInBackground(new Callable<EarIdList>() {
Task.callInBackground(new Callable<TopMatchesList>() {
@Override
public EarIdList call() throws Exception {
public TopMatchesList call() throws Exception {
// Sift
EarIdentifier identifier = new EarIdentifier(null);
Intent intent = SIFTActivity.this.getIntent();
......@@ -69,13 +71,13 @@ public class SIFTActivity extends Activity {
imageFile.delete();
// Compares the current features with the database.
EarData data = new EarDataLoaderCommcare().load(SIFTActivity.this);
PatientHashMap data = new PatientLoaderCommcare().load(SIFTActivity.this);
data.computeDistance(earFeature);
ArrayList<NameDistance> distances = new ArrayList<>(data.getPersons().values());
ArrayList<NameDistance> distances = new ArrayList<>(data.values());
Collections.sort(distances);
EarIdList result = new EarIdList();
TopMatchesList result = new TopMatchesList();
List<NameDistance> topN = distances.subList(0, Math.min(kTopN, distances.size()));
result.setTop(topN);
......@@ -84,9 +86,9 @@ public class SIFTActivity extends Activity {
return result;
}
}).continueWith(new Continuation<EarIdList, Object>() {
}).continueWith(new Continuation<TopMatchesList, Object>() {
@Override
public Object then(Task<EarIdList> task) throws Exception {
public Object then(Task<TopMatchesList> task) throws Exception {
Intent intent = new Intent("com.auriclon.activity_select_user");
intent.putExtra("list", new Gson().toJson(task.getResult()));
setResult(0, intent);
......
/*
Copyright by Boston University, 2016
Authors: Josejulio Martínez, Daniel Kornhauser
Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
*/
package com.aluxoft.earrecognition.activities;
import android.app.Activity;
......@@ -10,7 +15,7 @@ import android.widget.Button;
import android.widget.ListView;
import com.aluxoft.earrecognition.R;
import com.aluxoft.earrecognition.common.EarIdList;
import com.aluxoft.earrecognition.common.TopMatchesList;
import com.aluxoft.earrecognition.common.NameDistance;
import com.google.gson.Gson;
......@@ -22,12 +27,12 @@ import java.util.UUID;
*/
public class SelectFollowupActivity extends Activity {
public EarIdList earIdList = null;
public TopMatchesList topMatchesList = null;
private static final int COMMCARE_REGISTER = 1;
private static final int COMMCARE_FOLLOW_UP = 2;
//private EarIdList earIdList;
//private TopMatchesList topMatchesList;
@Override
protected void onCreate(Bundle savedInstanceState) {
......@@ -35,13 +40,13 @@ public class SelectFollowupActivity extends Activity {
setContentView(R.layout.activity_select_user);
String list = this.getIntent().getStringExtra("list");
this.earIdList = new Gson().fromJson(list, EarIdList.class);
this.topMatchesList = new Gson().fromJson(list, TopMatchesList.class);
Button registerButton = (Button) findViewById(R.id.register_commcare);
ArrayAdapter<NameDistance> arrayAdapter = new ArrayAdapter<NameDistance>(
this,
android.R.layout.simple_list_item_1,
this.earIdList.getTop()
this.topMatchesList.getTop()
);
ListView topNListView = (ListView)findViewById(R.id.topNListView);
......@@ -52,7 +57,7 @@ public class SelectFollowupActivity extends Activity {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent();
intent.putExtra("case_id", earIdList.getTop().get(position).person.getCaseId());
intent.putExtra("case_id", topMatchesList.getTop().get(position).patient.getCaseId());
SelectFollowupActivity.this.setResult(Activity.RESULT_OK, intent);
finish();
}
......
/*
Copyright by Boston University, 2016
Authors: Josejulio Martínez, Daniel Kornhauser
Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
*/
package com.aluxoft.earrecognition.common;
import com.google.gson.Gson;
......@@ -11,8 +16,7 @@ import org.opencv.features2d.DescriptorMatcher;
import java.util.ArrayList;
/**
* Represents Ear Features
*
* Contains ear features and handles its own (de)serialization.
*/
public class EarFeature {
......
/*
Copyright by Boston University, 2016
Authors: Josejulio Martínez, Daniel Kornhauser
Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
*/
package com.aluxoft.earrecognition.common;
/**
* Created by josejuliomartinez on 14/10/15.
* Tuple for storing Patient and distance relative to a feature.
*/
public class NameDistance implements Comparable<NameDistance> {
public double distance = 0;
public Person person = null;
public NameDistance() {
}
public Patient patient = null;
public NameDistance(double distance, Person person) {
this.set(distance, person);
public NameDistance(double distance, Patient patient) {
this.set(distance, patient);
}
public void set(double distance, Person person) {
public void set(double distance, Patient patient) {
this.distance = distance;
this.person = person;
this.patient = patient;
}
@Override
......@@ -33,6 +34,6 @@ public class NameDistance implements Comparable<NameDistance> {
@Override
public String toString() {
return this.person.getName();
return this.patient.getName();
}
}
\ No newline at end of file
/*
Copyright by Boston University, 2016
Authors: Josejulio Martínez, Daniel Kornhauser
Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
*/
package com.aluxoft.earrecognition.common;
import java.util.ArrayList;
/**
* Created by josejuliomartinez on 07/10/15.
* Patient data.
* Populated by PatientLoaderCommcare in PatientHashMap.
*/
public class Person {
public class Patient {
private String caseId;
private String name;
......
/*
Copyright by Boston University, 2016
Authors: Josejulio Martínez, Daniel Kornhauser
Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
*/
package com.aluxoft.earrecognition.common;
import java.util.HashMap;
/**
* Created by josejuliomartinez on 06/10/15.
* The database of all the ears.
* Hashmap to store patients with their NameDistance.
* Populated by PatientLoaderCommcare.
*/
public class EarData {
private HashMap<String, NameDistance> persons = new HashMap<String, NameDistance>();
public void addPerson(Person person) {
this.persons.put(person.getCaseId(), new NameDistance(0.0, person));
}
public class PatientHashMap extends HashMap<String, NameDistance> {
public HashMap<String, NameDistance> getPersons() {
return this.persons;
public void addPatient(Patient patient) {
this.put(patient.getCaseId(), new NameDistance(0.0, patient));
}
public void computeDistance(EarFeature feature) {
for (String caseId : this.persons.keySet()) {
NameDistance tuple = this.persons.get(caseId);
for (String caseId : this.keySet()) {
NameDistance tuple = this.get(caseId);
double minDistance = Double.MAX_VALUE;
for (EarFeature feature2 : tuple.person.getFeatures()) {
for (EarFeature feature2 : tuple.patient.getFeatures()) {
minDistance = Math.min(feature.distance(feature2), minDistance);
}
tuple.distance = minDistance;
......
/*
Copyright by Boston University, 2016
Authors: Josejulio Martínez, Daniel Kornhauser
Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
*/
package com.aluxoft.earrecognition.common;
import java.util.List;
/**
* Represents top 10 Ear ID matches.
*
*/
public class EarIdList {
public class TopMatchesList {
// Store EarFeatures
// Store Top-x
......
......@@ -19,8 +19,8 @@ import android.widget.Toast;
import com.aluxoft.earrecognition.EarIdentifier;
import com.aluxoft.earrecognition.R;
import com.aluxoft.earrecognition.common.EarIdList;
import com.aluxoft.earrecognition.loader.EarDataLoaderCommcare;
import com.aluxoft.earrecognition.common.TopMatchesList;
import com.aluxoft.earrecognition.loader.PatientLoaderCommcare;
import com.aluxoft.earrecognition.utils.FileCache;
import com.aluxoft.earrecognition.utils.ImageUtils;
import com.google.gson.Gson;
......@@ -37,7 +37,7 @@ import java.util.UUID;
*
* Takes the photo, sends to SIFT activity and returns.
*/
public class IntentTransferingFeatures extends Activity {
public class IntentTransferFeatures extends Activity {
public static final int KEY_REQUEST_IMAGE = 1;
public static final int KEY_SIFT_ACTIVITY_LOADER = 2;
......@@ -66,9 +66,9 @@ public class IntentTransferingFeatures extends Activity {
@Override
public void onClick(View v) {
if (!EarDataLoaderCommcare.checkConnection(IntentTransferingFeatures.this)) {
if (!PatientLoaderCommcare.checkConnection(IntentTransferFeatures.this)) {
if (loginInCommCareToast == null || loginInCommCareToast.getView().getWindowVisibility() != View.VISIBLE) {
loginInCommCareToast = Toast.makeText(IntentTransferingFeatures.this,
loginInCommCareToast = Toast.makeText(IntentTransferFeatures.this,
"Please login in CommCare application to proceed.",
Toast.LENGTH_LONG);
loginInCommCareToast.show();
......@@ -87,7 +87,7 @@ public class IntentTransferingFeatures extends Activity {
try {
startActivityForResult(i, KEY_REQUEST_IMAGE);
} catch (ActivityNotFoundException e) {
Toast.makeText(IntentTransferingFeatures.this, "No Camera", Toast.LENGTH_SHORT).show();
Toast.makeText(IntentTransferFeatures.this, "No Camera", Toast.LENGTH_SHORT).show();
}
}
});
......@@ -114,14 +114,14 @@ public class IntentTransferingFeatures extends Activity {
"odk_intent_data",
FileUtils.readFileToString(
FileCache
.getFile(IntentTransferingFeatures.this.getApplicationContext(),
.getFile(IntentTransferFeatures.this.getApplicationContext(),
FileCache.FileCacheType.Features)
)
);
IntentTransferingFeatures.this.setResult(Activity.RESULT_OK, returningIntent);
IntentTransferFeatures.this.setResult(Activity.RESULT_OK, returningIntent);
finish();
} catch (Exception e) {
Toast.makeText(IntentTransferingFeatures.this,
Toast.makeText(IntentTransferFeatures.this,
"An error occurred when loading the features.", Toast.LENGTH_LONG);
cachePictureButton.setEnabled(false);
}
......@@ -130,7 +130,7 @@ public class IntentTransferingFeatures extends Activity {
}
if(this.getLastNonConfigurationInstance() != null) {
location = ((IntentTransferingFeatures)this.getLastNonConfigurationInstance()).location;
location = ((IntentTransferFeatures)this.getLastNonConfigurationInstance()).location;
}
if(savedInstanceState != null) {
......@@ -156,7 +156,7 @@ public class IntentTransferingFeatures extends Activity {
// Fetches features from SIFT activity to return to CommCare
_showTransferringMessage();
String list = data.getStringExtra("list");
EarIdList earIdList = new Gson().fromJson(list, EarIdList.class);
TopMatchesList topMatchesList = new Gson().fromJson(list, TopMatchesList.class);
Intent returningIntent = new Intent(getIntent());
Bundle responses = new Bundle();
......@@ -165,15 +165,15 @@ public class IntentTransferingFeatures extends Activity {
returningIntent.putExtra(
"odk_intent_data",
earIdList.getCurrentFeature().serializeFeatures()
topMatchesList.getCurrentFeature().serializeFeatures()
);
IntentTransferingFeatures.this.setResult(Activity.RESULT_OK, returningIntent);
IntentTransferFeatures.this.setResult(Activity.RESULT_OK, returningIntent);
finish();
}
}
private void _showTransferringMessage() {
loading = ProgressDialog.show(IntentTransferingFeatures.this,
loading = ProgressDialog.show(IntentTransferFeatures.this,
"Transferring", "Please wait while transferring the features...");
loading.setCancelable(false);
loading.setProgressStyle(ProgressDialog.STYLE_SPINNER);
......
package com.aluxoft.earrecognition.loader;
import android.app.Activity;
import com.aluxoft.earrecognition.common.EarData;
/**
* Loads Case Id data from CommCare
*
*/
abstract public class EarDataLoader {
public abstract EarData load(Activity current);
/**
* Updates the database (only implemented if we can update the database)
* @param database
*/
public void update(EarData database) {
}
}
/*
Copyright by Boston University, 2016
Authors: Josejulio Martínez, Daniel Kornhauser
Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
*/
package com.aluxoft.earrecognition.loader;
import android.app.Activity;
import android.database.Cursor;
import android.net.Uri;
import com.aluxoft.earrecognition.common.EarData;
import com.aluxoft.earrecognition.common.PatientHashMap;
import com.aluxoft.earrecognition.common.EarFeature;
import com.aluxoft.earrecognition.common.Person;
import com.aluxoft.earrecognition.common.Patient;
/**
* Created by josejuliomartinez on 13/10/15.
*/
public class EarDataLoaderCommcare extends EarDataLoader {
public class PatientLoaderCommcare {
public static boolean checkConnection(Activity current) {
Cursor c = current.managedQuery(Uri.parse("content://org.commcare.dalvik.case/casedb/case"), null, null, null, null);
return c != null;
}
@Override
public EarData load(Activity current) {
public PatientHashMap load(Activity current) {
EarData earData = new EarData();
PatientHashMap patientHashMap = new PatientHashMap();
Cursor c = current.managedQuery(Uri.parse("content://org.commcare.dalvik.case/casedb/case"), null, null, null, null);
if (c == null) {
// Throw an exception (Unable to connect to commcare)
return earData;
return patientHashMap;
}
String caseId;
......@@ -59,14 +60,14 @@ public class EarDataLoaderCommcare extends EarDataLoader {
if (/*gender == null || */features == null) {
continue;
}
Person person = new Person();
person.setCaseId(caseId);
person.setName(name);
person.setGender(gender);
person.addFeature(new EarFeature(features));
earData.addPerson(person);
Patient patient = new Patient();
patient.setCaseId(caseId);
patient.setName(name);
patient.setGender(gender);
patient.addFeature(new EarFeature(features));
patientHashMap.addPatient(patient);
}
return earData;
return patientHashMap;
}
}
/*
Copyright by Boston University, 2016
Authors: Josejulio Martínez, Daniel Kornhauser
Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
*/
package com.aluxoft.earrecognition.utils;
import android.app.Application;
import android.content.Context;
import android.os.Environment;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.channels.FileChannel;
/**
* Created by josejuliomartinez on 25/11/15.
*/
public class FileCache extends File {
private static final long invalidationThreshold;
......@@ -32,7 +28,7 @@ public class FileCache extends File {
private String filename;
private FileCacheType(String filename) {
FileCacheType(String filename) {
this.filename = filename;
}
}
......@@ -72,7 +68,4 @@ public class FileCache extends File {
}
}
}
/*
Copyright by Boston University, 2016
Authors: Josejulio Martínez, Daniel Kornhauser
Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
*/
package com.aluxoft.earrecognition.utils;
import android.os.Environment;
......@@ -7,9 +12,6 @@ import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Created by josejuliomartinez on 08/10/15.
*/
public class ImageUtils {
public static File createTempImageFile() throws IOException {
......
/*
Copyright by Boston University, 2016
Authors: Josejulio Martínez, Daniel Kornhauser
Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
*/
package com.aluxoft.earrecognition.utils;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
/**
* Created by josejuliomartinez on 08/10/15.
*/
public class OpenCvUtils {
public static void resizeMat(Mat image, double maxWidth, double maxHeight) {
......
/**
* Created by josejuliomartinez on 24/09/15.
*/
package com.aluxoft.test;
public class TestConstants {
// ----- For testing purposes ----------------------------------------
static final String image1 = "/storage/emulated/0/DCIM/Camera/000_down_ear.jpg";
static final String image2 = "/storage/emulated/0/DCIM/Camera/001_front_ear.jpg";
static final String image3 = "/storage/emulated/0/DCIM/Camera/000_front_ear.jpg";
static final String image4 = "/storage/emulated/0/DCIM/Camera/test_1.png";
static final String image5 = "/storage/emulated/0/DCIM/Camera/test_3.png";
static final String image6 = "/storage/emulated/0/DCIM/Camera/test_2.png";
static final String image_patty_01 = "/storage/emulated/0/DCIM/Camera/PATTY_01.jpg";
static final String image_patty_02 = "/storage/emulated/0/DCIM/Camera/PATTY_02.jpg";
static final String image_elena_01 = "/storage/emulated/0/DCIM/Camera/ELENA_01.jpg";
static final String image_elena_02 = "/storage/emulated/0/DCIM/Camera/ELENA_02.jpg";
// ---------------------------------------------------------------------
}
I Entry points:
---------------
A IntentSearchFeatures:
Called by CommCare to identify ear during followup
1 EarCaptureActivity
Camera to capture ear image or choose last taken photo.
2 SIFTActivity
Receives images from EarCaptureActivity
Computes EarFeature of image and retrieves features with PatientLoaderCommCare
For every Patient in PatientHashMap calculates the Distance with the EarFeature
Sends TopMatchesList to next activity
3 SelectFollowupActivity
Receives and displays TopMatchesList for selection of patient.
Returns selected match or register instruction to CommCare
B IntentTransferFeatures:
Called by CommCare to store features during registration
1 EarCaptureActivity
Camera to capture ear image or choose last taken photo.
2 SIFTActivity
Computes features of image and return them to CommCare
II Utils:
--------
FileCache
Handles temporary files for images and features.
ImageUtils
Handles camera image location and name
OpenCvUtils
Resizes matrix to speed up features
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment