188 lines
9.5 KiB
Java
188 lines
9.5 KiB
Java
package com.rubenvandeven.emotionhero;
|
|
|
|
import android.database.Cursor;
|
|
import android.graphics.Bitmap;
|
|
import android.graphics.BitmapFactory;
|
|
import android.graphics.PointF;
|
|
import android.graphics.RectF;
|
|
import android.util.Base64;
|
|
|
|
import com.affectiva.android.affdex.sdk.detector.Face;
|
|
import com.google.gson.annotations.Expose;
|
|
|
|
import java.io.ByteArrayOutputStream;
|
|
import java.util.Arrays;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
|
|
/**
|
|
* Created by ruben on 02/09/16.
|
|
*/
|
|
|
|
public class Hit {
|
|
|
|
public long id;
|
|
|
|
public Scenario.Target target;
|
|
|
|
@Expose(serialize = false, deserialize = false)
|
|
public Game game;
|
|
|
|
public float score;
|
|
|
|
public Map<Emotion, Float> emotions = new HashMap<>(7);
|
|
|
|
public boolean glasses;
|
|
public String ethnicity;
|
|
public String age;
|
|
public String gender;
|
|
|
|
public Map<Expression, Float> expressions = new HashMap<>(21); // also includes measurements
|
|
|
|
public PointF[] points = new PointF[34];
|
|
|
|
public String remoteId;
|
|
|
|
public Bitmap frame;
|
|
|
|
/**
|
|
* Constructor for game moment
|
|
*/
|
|
public Hit(Scenario.Target target, Game game, Face face, float score, Bitmap frame) {
|
|
this.score = score;
|
|
this.target = target;
|
|
this.game = game;
|
|
for(Emotion emotion: Emotion.values()) {
|
|
emotions.put(emotion,emotion.getValueFromFace(face));
|
|
}
|
|
|
|
this.gender = face.appearance.getGender() == Face.GENDER.UNKNOWN ? "U" : (face.appearance.getGender() == Face.GENDER.MALE ? "M" : "F");
|
|
this.glasses = face.appearance.getGlasses() == Face.GLASSES.YES ? true : false;
|
|
this.ethnicity = face.appearance.getEthnicity().name();
|
|
this.age = face.appearance.getAge().name();
|
|
|
|
for(Expression exp: Expression.values()) {
|
|
this.expressions.put(exp, exp.getValueFromFace(face));
|
|
}
|
|
|
|
this.points = face.getFacePoints().clone();
|
|
|
|
this.frame = frame;
|
|
|
|
// this in a way is strange behaviour:
|
|
// preferably do the game.addHit after creating hit, and call hit.game = game from there.
|
|
game.addHit(this);
|
|
}
|
|
|
|
/**
|
|
* Constructor from database entity
|
|
*/
|
|
public Hit(Game game, Cursor c) {
|
|
this.id = c.getLong(c.getColumnIndex("id"));
|
|
this.score = c.getFloat(c.getColumnIndex("score"));
|
|
String rId = c.getString(c.getColumnIndex("remoteId"));
|
|
this.remoteId = (rId == null || rId.length() == 0) ? null : c.getString(c.getColumnIndex("remoteId"));
|
|
this.target = game.scenario.getTargetByIndex(c.getInt(c.getColumnIndex("target_index")));
|
|
|
|
this.glasses = c.getInt(c.getColumnIndex("glasses")) == 1;
|
|
this.ethnicity = c.getString(c.getColumnIndex("ethnicity"));
|
|
this.age = c.getString(c.getColumnIndex("age"));
|
|
this.gender = c.getString(c.getColumnIndex("gender"));
|
|
|
|
this.emotions.put(Emotion.ANGER, c.getFloat(c.getColumnIndex("anger")));
|
|
this.emotions.put(Emotion.CONTEMPT, c.getFloat(c.getColumnIndex("contempt")));
|
|
this.emotions.put(Emotion.DISGUST, c.getFloat(c.getColumnIndex("disgust")));
|
|
this.emotions.put(Emotion.FEAR, c.getFloat(c.getColumnIndex("fear")));
|
|
this.emotions.put(Emotion.JOY, c.getFloat(c.getColumnIndex("joy")));
|
|
this.emotions.put(Emotion.SADNESS, c.getFloat(c.getColumnIndex("sadness")));
|
|
this.emotions.put(Emotion.SURPRISE, c.getFloat(c.getColumnIndex("surprise")));
|
|
|
|
for(Expression exp: Expression.values()) {
|
|
this.expressions.put(exp, c.getFloat( c.getColumnIndex( exp.getDbName() )));
|
|
}
|
|
|
|
this.points[0] = new PointF(c.getFloat(c.getColumnIndex("point_0x")), c.getFloat(c.getColumnIndex("point_0y")));
|
|
this.points[1] = new PointF(c.getFloat(c.getColumnIndex("point_1x")), c.getFloat(c.getColumnIndex("point_1y")));
|
|
this.points[2] = new PointF(c.getFloat(c.getColumnIndex("point_2x")), c.getFloat(c.getColumnIndex("point_2y")));
|
|
this.points[3] = new PointF(c.getFloat(c.getColumnIndex("point_3x")), c.getFloat(c.getColumnIndex("point_3y")));
|
|
this.points[4] = new PointF(c.getFloat(c.getColumnIndex("point_4x")), c.getFloat(c.getColumnIndex("point_4y")));
|
|
this.points[5] = new PointF(c.getFloat(c.getColumnIndex("point_5x")), c.getFloat(c.getColumnIndex("point_5y")));
|
|
this.points[6] = new PointF(c.getFloat(c.getColumnIndex("point_6x")), c.getFloat(c.getColumnIndex("point_6y")));
|
|
this.points[7] = new PointF(c.getFloat(c.getColumnIndex("point_7x")), c.getFloat(c.getColumnIndex("point_7y")));
|
|
this.points[8] = new PointF(c.getFloat(c.getColumnIndex("point_8x")), c.getFloat(c.getColumnIndex("point_8y")));
|
|
this.points[9] = new PointF(c.getFloat(c.getColumnIndex("point_9x")), c.getFloat(c.getColumnIndex("point_9y")));
|
|
this.points[10] = new PointF(c.getFloat(c.getColumnIndex("point_10x")), c.getFloat(c.getColumnIndex("point_10y")));
|
|
this.points[11] = new PointF(c.getFloat(c.getColumnIndex("point_11x")), c.getFloat(c.getColumnIndex("point_11y")));
|
|
this.points[12] = new PointF(c.getFloat(c.getColumnIndex("point_12x")), c.getFloat(c.getColumnIndex("point_12y")));
|
|
this.points[13] = new PointF(c.getFloat(c.getColumnIndex("point_13x")), c.getFloat(c.getColumnIndex("point_13y")));
|
|
this.points[14] = new PointF(c.getFloat(c.getColumnIndex("point_14x")), c.getFloat(c.getColumnIndex("point_14y")));
|
|
this.points[15] = new PointF(c.getFloat(c.getColumnIndex("point_15x")), c.getFloat(c.getColumnIndex("point_15y")));
|
|
this.points[16] = new PointF(c.getFloat(c.getColumnIndex("point_16x")), c.getFloat(c.getColumnIndex("point_16y")));
|
|
this.points[17] = new PointF(c.getFloat(c.getColumnIndex("point_17x")), c.getFloat(c.getColumnIndex("point_17y")));
|
|
this.points[18] = new PointF(c.getFloat(c.getColumnIndex("point_18x")), c.getFloat(c.getColumnIndex("point_18y")));
|
|
this.points[19] = new PointF(c.getFloat(c.getColumnIndex("point_19x")), c.getFloat(c.getColumnIndex("point_19y")));
|
|
this.points[20] = new PointF(c.getFloat(c.getColumnIndex("point_20x")), c.getFloat(c.getColumnIndex("point_20y")));
|
|
this.points[21] = new PointF(c.getFloat(c.getColumnIndex("point_21x")), c.getFloat(c.getColumnIndex("point_21y")));
|
|
this.points[22] = new PointF(c.getFloat(c.getColumnIndex("point_22x")), c.getFloat(c.getColumnIndex("point_22y")));
|
|
this.points[23] = new PointF(c.getFloat(c.getColumnIndex("point_23x")), c.getFloat(c.getColumnIndex("point_23y")));
|
|
this.points[24] = new PointF(c.getFloat(c.getColumnIndex("point_24x")), c.getFloat(c.getColumnIndex("point_24y")));
|
|
this.points[25] = new PointF(c.getFloat(c.getColumnIndex("point_25x")), c.getFloat(c.getColumnIndex("point_25y")));
|
|
this.points[26] = new PointF(c.getFloat(c.getColumnIndex("point_26x")), c.getFloat(c.getColumnIndex("point_26y")));
|
|
this.points[27] = new PointF(c.getFloat(c.getColumnIndex("point_27x")), c.getFloat(c.getColumnIndex("point_27y")));
|
|
this.points[28] = new PointF(c.getFloat(c.getColumnIndex("point_28x")), c.getFloat(c.getColumnIndex("point_28y")));
|
|
this.points[29] = new PointF(c.getFloat(c.getColumnIndex("point_29x")), c.getFloat(c.getColumnIndex("point_29y")));
|
|
this.points[30] = new PointF(c.getFloat(c.getColumnIndex("point_30x")), c.getFloat(c.getColumnIndex("point_30y")));
|
|
this.points[31] = new PointF(c.getFloat(c.getColumnIndex("point_31x")), c.getFloat(c.getColumnIndex("point_31y")));
|
|
this.points[32] = new PointF(c.getFloat(c.getColumnIndex("point_32x")), c.getFloat(c.getColumnIndex("point_32y")));
|
|
this.points[33] = new PointF(c.getFloat(c.getColumnIndex("point_33x")), c.getFloat(c.getColumnIndex("point_33y")));
|
|
|
|
byte[] image = c.getBlob(c.getColumnIndex("image"));
|
|
if(image != null)
|
|
{
|
|
frame = BitmapFactory.decodeByteArray(image, 0, image.length);
|
|
}
|
|
|
|
game.addHit(this);
|
|
}
|
|
|
|
public static RectF getBoundingboxForPoints(PointF[] points) {
|
|
// a bit of a hack to be as quick as possible
|
|
// we know which point is where on the face, however, the face might be tilted:
|
|
float[] minXes = {points[0].x,points[1].x,points[5].x};
|
|
float[] maxXes = {points[4].x,points[3].x,points[10].x};
|
|
float[] maxYs = {points[1].y,points[2].y,points[3].y};
|
|
float[] minYs = {points[5].y,points[6].y,points[7].y,points[8].y,points[9].y,points[10].y};
|
|
|
|
Arrays.sort(minXes);
|
|
Arrays.sort(maxXes);
|
|
Arrays.sort(maxYs);
|
|
Arrays.sort(minYs);
|
|
|
|
return new RectF(minXes[0], minYs[0], maxXes[maxXes.length-1], maxYs[maxYs.length-1]);
|
|
}
|
|
|
|
// to store in db
|
|
public static String bitmapToBase64(Bitmap bitmap) {
|
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
|
// bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
|
|
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, byteArrayOutputStream);
|
|
byte[] byteArray = byteArrayOutputStream .toByteArray();
|
|
return Base64.encodeToString(byteArray, Base64.DEFAULT);
|
|
}
|
|
|
|
// to retreive from db
|
|
public static Bitmap base64ToBitmap(String b64) {
|
|
byte[] imageAsBytes = Base64.decode(b64.getBytes(), Base64.DEFAULT);
|
|
return BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length);
|
|
}
|
|
|
|
public byte[] getFrameAsByteArray() {
|
|
if(frame == null)
|
|
return null;
|
|
|
|
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
|
frame.compress(Bitmap.CompressFormat.JPEG, 90, stream);
|
|
return stream.toByteArray();
|
|
}
|
|
}
|