New features: Added the Top-N as a simple_list.

Extracted NamedDistance class from EarData.
Fixes: Problem with serializing an OpenCV Mat.
parent 924e850c
......@@ -10,6 +10,7 @@ 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.NameDistance;
import com.aluxoft.earrecognition.common.Person;
import com.aluxoft.earrecognition.loader.EarDataLoaderCommcare;
import com.google.gson.Gson;
......@@ -25,11 +26,13 @@ import bolts.Continuation;
import bolts.Task;
/**
* Computes SIFT & finds top 10 matches
* Computes SIFT & finds top-n matches
* TODO: Get other users features, compare SIFT features, etc...
*/
public class SIFTActivity extends Activity {
final int kTopN = 7;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......@@ -56,12 +59,12 @@ public class SIFTActivity extends Activity {
EarData data = new EarDataLoaderCommcare().load(SIFTActivity.this);
data.computeDistance(earFeature);
ArrayList<EarData.NameDistance> distances = new ArrayList<>(data.getPersons().values());
ArrayList<NameDistance> distances = new ArrayList<>(data.getPersons().values());
Collections.sort(distances);
EarIdList result = new EarIdList();
List<EarData.NameDistance> top10 = distances.subList(0, Math.min(10, distances.size()));
result.setTop(top10);
List<NameDistance> topN = distances.subList(0, Math.min(kTopN, distances.size()));
result.setTop(topN);
// Pass results to next activity.
result.setCurrentFeature(earFeature);
......
......@@ -4,10 +4,14 @@ import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import com.aluxoft.earrecognition.R;
import com.aluxoft.earrecognition.common.EarData;
import com.aluxoft.earrecognition.common.EarIdList;
import com.aluxoft.earrecognition.common.NameDistance;
import com.google.gson.Gson;
/**
......@@ -33,6 +37,15 @@ public class SelectUserActivity extends Activity {
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()
);
ListView topNListView = (ListView)findViewById(R.id.topNListView);
topNListView.setAdapter(arrayAdapter);
registerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
......
......@@ -31,35 +31,5 @@ public class EarData {
}
}
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;
......@@ -21,7 +18,8 @@ public class EarFeature {
private static DescriptorMatcher matcher;
private Mat features;
private String features;
private transient Mat _features = null;
static {
System.loadLibrary("opencv_java");
......@@ -29,20 +27,30 @@ public class EarFeature {
matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE);
}
public Mat getFeatures() {
public String getFeatures() {
return features;
}
public void setFeatures(Mat features) {
public void setFeatures(Mat _features) {
this._features = _features;
this.features = this.serializeFeatures();
}
public void setFeatures(String features) {
this.features = features;
this._features = null;
}
public EarFeature(Mat features) {
public EarFeature(String features) {
this.setFeatures(features);
}
public EarFeature(Mat _features) {
this.setFeatures(_features);
}
public String serializeFeatures() {
Mat mFeatures = this.getFeatures();
Mat mFeatures = this._getFeatures();
ArrayList<ArrayList<Integer>> features = new ArrayList<>();
for (int i=0;i<mFeatures.rows();++i) {
......@@ -57,8 +65,10 @@ public class EarFeature {
}
public double distance(EarFeature feature2) {
assert this._getFeatures().type() == feature2._getFeatures().type();
MatOfDMatch matches = new MatOfDMatch();
matcher.match(this.getFeatures(), feature2.getFeatures(), matches);
matcher.match(this._getFeatures(), feature2._getFeatures(), matches);
DMatch[] aMatches = matches.toArray();
double distance = 0;
......@@ -69,26 +79,32 @@ public class EarFeature {
return distance;
}
public static EarFeature unserialize(String featuresString) {
public Mat 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);
mFeatures.create(features.size(), kFeatureSize, CvType.CV_32F);
int buffer[] = new int[1];
float buffer[] = new float[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();
buffer[0] = feature.get(j).floatValue();
mFeatures.put(i, j, buffer);
}
}
EarFeature earFeature = new EarFeature(mFeatures);
return earFeature;
return mFeatures;
}
private Mat _getFeatures() {
if (this._features == null && this.features != null) {
this._features = this.unserialize(this.features);
}
return this._features;
}
}
......@@ -11,7 +11,7 @@ public class EarIdList {
// Store EarFeatures
// Store Top-x
private EarFeature currentFeature;
private List<EarData.NameDistance> top;
private List<NameDistance> top;
public EarFeature getCurrentFeature() {
return currentFeature;
......@@ -21,11 +21,11 @@ public class EarIdList {
this.currentFeature = currentFeature;
}
public List<EarData.NameDistance> getTop() {
public List<NameDistance> getTop() {
return top;
}
public void setTop(List<EarData.NameDistance> top) {
public void setTop(List<NameDistance> top) {
this.top = top;
}
......
package com.aluxoft.earrecognition.common;
/**
* Created by josejuliomartinez on 14/10/15.
*/
public 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;
}
}
@Override
public String toString() {
return this.person.getName();
}
}
\ No newline at end of file
......@@ -56,7 +56,7 @@ public class EarDataLoaderCommcare extends EarDataLoader {
person.setCaseId(caseId);
person.setName(name);
person.setGender(gender);
person.addFeature(EarFeature.unserialize(features));
person.addFeature(new EarFeature(features));
earData.addPerson(person);
}
......
......@@ -19,7 +19,7 @@
<ListView
android:layout_width="match_parent"
android:layout_height="453dp"
android:id="@+id/listView"
android:id="@+id/topNListView"
android:layout_gravity="center_horizontal"
android:choiceMode="singleChoice" />
......
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