New features: Downloading cases and features, calculate distances and sort, populate top-10 list.

parent cc9972b1
......@@ -7,11 +7,18 @@ 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.EarFeature;
import com.aluxoft.earrecognition.common.EarIdList;
import com.aluxoft.earrecognition.common.Person;
import com.aluxoft.earrecognition.loader.EarDataLoaderCommcare;
import com.google.gson.Gson;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import bolts.Continuation;
......@@ -46,9 +53,15 @@ public class SIFTActivity extends Activity {
new File(imagePath).delete();
// Compares the current features with the database.
EarIdList result = new EarIdList();
EarData data = new EarDataLoaderCommcare().load(SIFTActivity.this);
data.computeDistance(earFeature);
ArrayList<EarData.NameDistance> distances = new ArrayList<>(data.getPersons().values());
Collections.sort(distances);
// Generate the top-x.
EarIdList result = new EarIdList();
List<EarData.NameDistance> top10 = distances.subList(0, Math.min(10, distances.size()));
result.setTop(top10);
// Pass results to next activity.
result.setCurrentFeature(earFeature);
......
package com.aluxoft.earrecognition.common;
import com.aluxoft.earrecognition.unused.Person;
import java.util.HashMap;
/**
......@@ -10,11 +8,58 @@ import java.util.HashMap;
*/
public class EarData {
private HashMap<String, Person> persons = new HashMap<String, Person>();
private HashMap<String, NameDistance> persons = new HashMap<String, NameDistance>();
public void addPerson(Person person) {
this.persons.put(person.getIdentifier(), person);
this.persons.put(person.getCaseId(), new NameDistance(0.0, person));
}
public HashMap<String, NameDistance> getPersons() {
return this.persons;
}
public void computeDistance(EarFeature feature) {
for (String caseId : this.persons.keySet()) {
NameDistance tuple = this.persons.get(caseId);
double minDistance = Double.MAX_VALUE;
for (EarFeature feature2 : tuple.person.getFeatures()) {
minDistance = Math.min(feature.distance(feature2), minDistance);
}
tuple.distance = minDistance;
}
}
public static class NameDistance implements Comparable<NameDistance> {
public double distance = 0;
public Person person = null;
public NameDistance() {
}
public NameDistance(double distance, Person person) {
this.set(distance, person);
}
public void set(double distance, Person person) {
this.distance = distance;
this.person = person;
}
@Override
public int compareTo(NameDistance nameDistance) {
if (this.distance < nameDistance.distance) {
return -1;
} else if (this.distance == nameDistance.distance) {
return 0;
} else {
return 1;
}
}
}
}
package com.aluxoft.earrecognition.common;
import com.aluxoft.earrecognition.activities.SIFTActivity;
import com.aluxoft.earrecognition.utils.OpenCvUtils;
import com.google.gson.Gson;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Core;
import org.opencv.core.MatOfDMatch;
import org.opencv.features2d.DMatch;
import org.opencv.features2d.DescriptorMatcher;
import java.util.ArrayList;
......@@ -12,8 +19,16 @@ import java.util.ArrayList;
*/
public class EarFeature {
private static DescriptorMatcher matcher;
private Mat features;
static {
System.loadLibrary("opencv_java");
System.loadLibrary("nonfree");
matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE);
}
public Mat getFeatures() {
return features;
}
......@@ -41,4 +56,39 @@ public class EarFeature {
return gson.toJson(features);
}
public double distance(EarFeature feature2) {
MatOfDMatch matches = new MatOfDMatch();
matcher.match(this.getFeatures(), feature2.getFeatures(), matches);
DMatch[] aMatches = matches.toArray();
double distance = 0;
for (int i=0;i<aMatches.length;++i) {
distance += aMatches[i].distance;
}
return distance;
}
public static EarFeature unserialize(String featuresString) {
final int kFeatureSize = 128;
Gson gson = new Gson();
ArrayList< ArrayList<Double> > features = new ArrayList<>();
features = gson.fromJson(featuresString, features.getClass());
Mat mFeatures = new Mat();
mFeatures.create(features.size(), kFeatureSize, CvType.CV_32S);
int buffer[] = new int[1];
for (int i=0;i<features.size();++i) {
ArrayList<Double> feature = features.get(i);
for (int j=0;j<feature.size();++j) {
buffer[0] = feature.get(j).intValue();
mFeatures.put(i, j, buffer);
}
}
EarFeature earFeature = new EarFeature(mFeatures);
return earFeature;
}
}
package com.aluxoft.earrecognition.common;
import java.util.List;
/**
* Represents top 10 Ear ID matches.
*
......@@ -9,6 +11,7 @@ public class EarIdList {
// Store EarFeatures
// Store Top-x
private EarFeature currentFeature;
private List<EarData.NameDistance> top;
public EarFeature getCurrentFeature() {
return currentFeature;
......@@ -18,4 +21,12 @@ public class EarIdList {
this.currentFeature = currentFeature;
}
public List<EarData.NameDistance> getTop() {
return top;
}
public void setTop(List<EarData.NameDistance> top) {
this.top = top;
}
}
package com.aluxoft.earrecognition.unused;
import com.aluxoft.earrecognition.common.EarFeature;
package com.aluxoft.earrecognition.common;
import java.util.ArrayList;
......@@ -9,16 +7,18 @@ import java.util.ArrayList;
*/
public class Person {
private String identifier;
private String caseId;
private String name;
private String gender;
private ArrayList<EarFeature> features = new ArrayList<EarFeature>();
public String getIdentifier() {
return identifier;
public String getCaseId() {
return caseId;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
public void setCaseId(String caseId) {
this.caseId = caseId;
}
public String getName() {
......@@ -29,7 +29,20 @@ public class Person {
this.name = name;
}
public String getGender() {
return this.gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public void addFeature(EarFeature feature) {
this.features.add(feature);
}
public ArrayList<EarFeature> getFeatures() {
return this.features;
}
}
......@@ -5,6 +5,8 @@ import android.database.Cursor;
import android.net.Uri;
import com.aluxoft.earrecognition.common.EarData;
import com.aluxoft.earrecognition.common.EarFeature;
import com.aluxoft.earrecognition.common.Person;
/**
* Created by josejuliomartinez on 13/10/15.
......@@ -14,28 +16,50 @@ public class EarDataLoaderCommcare extends EarDataLoader {
@Override
public EarData load(Activity current) {
EarData data = new EarData();
EarData earData = new EarData();
Cursor c = current.managedQuery(Uri.parse("content://org.commcare.dalvik.case/casedb/case"), null, null, null, null);
if (c == null) {
return data;
// Throw an exception (Unable to connect to commcare)
return earData;
}
String caseId;
String name;
String gender;
String features;
while (c.moveToNext()) {
String caseId = c.getString(c.getColumnIndex("case_id"));
caseId = c.getString(c.getColumnIndex("case_id"));
name = c.getString(c.getColumnIndex("case_name"));
gender = null;
features = null;
Uri uri = Uri.parse("content://org.commcare.dalvik.case/casedb/data/" + caseId);
Cursor caseCursor = current.managedQuery(uri, null, null, null, null);
if (caseCursor == null) {
continue;
}
while (caseCursor.moveToNext()) {
String gender = caseCursor.getString(caseCursor.getColumnIndex("gender"));
String features = caseCursor.getString(caseCursor.getColumnIndex("features"));
// Agregar el gender, caseid y features a data
String datumId = caseCursor.getString(caseCursor.getColumnIndex("datum_id"));
if (datumId.equals("gender")) {
gender = caseCursor.getString(caseCursor.getColumnIndex("value"));
} else if (datumId.equals("features")) {
features = caseCursor.getString(caseCursor.getColumnIndex("value"));
}
}
if (gender == null || features == null) {
continue;
}
Person person = new Person();
person.setCaseId(caseId);
person.setName(name);
person.setGender(gender);
person.addFeature(EarFeature.unserialize(features));
earData.addPerson(person);
}
return data;
return earData;
}
}
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