package it.acxent.face; import it.acxent.db.ApplParmFull; import it.acxent.db.DBAdapter; import it.acxent.db.ResParm; import it.acxent.db.WcString; import it.acxent.face.api.vision.GoogleVisionApi; import it.acxent.face.api.vision.GoogleVisionResult; import it.acxent.util.DoubleOperator; import it.acxent.util.StringTokenizer; import it.acxent.util.Vectumerator; import java.awt.image.BufferedImage; import java.io.File; import java.io.Serializable; import java.math.RoundingMode; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.imageio.ImageIO; import org.apache.commons.math3.geometry.Vector; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import org.json.JSONArray; import org.json.JSONObject; public class FotoFaceVision extends DBAdapter implements Serializable { private static final long serialVersionUID = 1683972032841L; private Face face; private long id_fotoFace; private long id_foto; private String jsonData; private Foto foto; private long faceTopVx; private long faceTopVy; private long faceBottomVx; private long faceBottomVy; private String featureVector1; private String featureVector2; private String fileName; private String label; private String labelDb; public FotoFaceVision(ApplParmFull newApplParmFull) { super(newApplParmFull); } public FotoFaceVision() {} public void setId_fotoFace(long newId_fotoFace) { this.id_fotoFace = newId_fotoFace; } public void setId_foto(long newId_foto) { this.id_foto = newId_foto; setFoto(null); } public void setJsonData(String newJsonData) { this.jsonData = newJsonData; } public final ResParm loadSelfieByGoogleVision(String fileName) { ResParm rp = new ResParm(); try { String GVA_KEY = getParm("GOOGLE_API_KEY_VISION").getTesto(); GoogleVisionApi gva = new GoogleVisionApi(GVA_KEY); GoogleVisionResult resF = gva.annotateFaces(fileName); if (resF.isOk()) { rp = loadSelfieByJson((JSONObject)resF.getResult()); } else { rp.setStatus(false); rp.setMsg(resF.getMsg()); } } catch (Exception e) { rp.setException(e); rp.setStatus(false); } return rp; } public final ResParm loadSelfieByJson(JSONObject jo) { ResParm rp = new ResParm(); StringBuilder msg = new StringBuilder(); JSONArray jaResponses = jo.getJSONArray("responses"); boolean visiTrovati = false; for (int i = 0; i < jaResponses.length(); i++) { JSONObject joResponse = jaResponses.getJSONObject(i); if (joResponse.has("faceAnnotations")) { visiTrovati = true; JSONArray jaFaceAnnotations = joResponse.getJSONArray("faceAnnotations"); if (jaFaceAnnotations.length() > 1) { rp.setStatus(false); rp.setMsg("Trovati duo o piu visi.."); } else { JSONObject joFaceAnnotation = jaFaceAnnotations.getJSONObject(0); JSONObject joFace = new JSONObject(); JSONObject joFdBoundingPoly = joFaceAnnotation.getJSONObject("fdBoundingPoly"); joFace.put("fdBoundingPoly", joFdBoundingPoly); JSONArray jaLandmarks = joFaceAnnotation.getJSONArray("landmarks"); joFace.put("landmarks", jaLandmarks); setJsonData(joFace.toString()); rp = _loadFotoFaceFromFaceJson(false); if (!rp.getStatus()) msg.append("Errore: impossibile caricare fotoface da json per il selfie: " + rp.getMsg()); } } } if (!visiTrovati) { rp.setStatus(false); rp.setMsg("Nessun viso trovato!!"); } return rp; } public long getId_fotoFace() { return this.id_fotoFace; } public long getId_foto() { return this.id_foto; } public String getJsonData() { return (this.jsonData == null) ? "" : this.jsonData.trim(); } public void setFoto(Foto newFoto) { this.foto = newFoto; } public Foto getFoto() { this.foto = (Foto)getSecondaryObject(this.foto, Foto.class, getId_foto()); return this.foto; } protected ResParm checkDeleteCascade() { return new ResParm(true); } protected void deleteCascade() {} public Vectumerator findByCR(FotoFaceCR CR, int pageNumber, int pageRows) { String s_Sql_Find = "select A.* from FOTO_FACE AS A"; String s_Sql_Order = ""; WcString wc = new WcString(); if (!CR.getSearchTxt().trim().isEmpty()) { StringTokenizer st = new StringTokenizer(CR.getSearchTxt().trim(), " "); StringBuffer txt = new StringBuffer("("); while (st.hasMoreTokens()) { String token = st.nextToken(); txt.append("(A.Cognome like '%" + token + "%' or A.Nome like '%" + token + "%')"); if (st.hasMoreTokens()) txt.append(" and "); } txt.append(")"); wc.addWc(txt.toString()); } try { PreparedStatement stmt = getConn().prepareStatement(s_Sql_Find + s_Sql_Find + wc.toString()); return findRows(stmt, pageNumber, pageRows); } catch (SQLException e) { removeCPConnection(); handleDebug(e); return AB_EMPTY_VECTUMERATOR; } } private ResParm _loadFotoFaceFromFaceJson(boolean salva) { ResParm rp = new ResParm(); if (getJsonData().isEmpty()) { rp.setStatus(false); rp.setMsg("Json data vuoto... non sono state trovate facce"); } else { this.face = new Face(); JSONObject joFace = new JSONObject(getJsonData()); JSONObject joFdBoundingPoly = joFace.getJSONObject("fdBoundingPoly"); JSONArray jaVertices = joFdBoundingPoly.getJSONArray("vertices"); JSONObject joTopLeft = jaVertices.getJSONObject(0); JSONObject joTopRigth = jaVertices.getJSONObject(1); JSONObject joBottomRigth = jaVertices.getJSONObject(2); JSONObject joBottomLeft = jaVertices.getJSONObject(3); try { this.face.setB_TOP_LEFT(new Point(joTopLeft.getLong("x"), joTopLeft.getLong("y"))); } catch (Exception e) { e.printStackTrace(); } try { this.face.setB_TOP_RIGHT(new Point(joTopRigth.getLong("x"), joTopRigth.getLong("y"))); } catch (Exception e) { e.printStackTrace(); } try { this.face.setB_BOTTOM_RIGHT(new Point(joBottomRigth.getLong("x"), joBottomRigth.getLong("y"))); } catch (Exception e) { e.printStackTrace(); } try { this.face.setB_BOTTOM_LEFT(new Point(joBottomLeft.getLong("x"), joBottomLeft.getLong("y"))); } catch (Exception e) { e.printStackTrace(); } JSONArray jaLandmarks = joFace.getJSONArray("landmarks"); for (int k = 0; k < jaLandmarks.length(); k++) { JSONObject joLandmark = jaLandmarks.getJSONObject(k); _fillFaceLandmark(this.face, joLandmark); } if (salva) { rp = save(); } else { rp.setStatus(true); rp.setMsg("Fotoface creato ma non salvato"); } } return rp; } public ResParm deleteFotoFaceByFoto(long l_id_foto) { if (getApFull() == null || l_id_foto == 0L) return new ResParm(false, "Errore!! Dati connessione db assenti"); return delete("delete from FOTO_FACE WHERE id_foto=" + l_id_foto); } public void findFirstByFoto(long l_id_foto) { String s_Sql_Find = "select A.* from FOTO_FACE AS A"; String s_Sql_Order = ""; WcString wc = new WcString(); wc.addWc("A.id_foto=" + l_id_foto); try { PreparedStatement stmt = getConn().prepareStatement(s_Sql_Find + s_Sql_Find + wc.toString()); findFirstRecord(stmt); } catch (SQLException e) { removeCPConnection(); handleDebug(e); } } private static final void _fillFaceLandmark(Face face, JSONObject joLandmark) { String type = joLandmark.getString("type"); JSONObject joPosition = joLandmark.getJSONObject("position"); Point currentPoint = new Point(joPosition.getLong("x"), joPosition.getLong("y"), joPosition.getLong("z")); if (type.equals("LEFT_EYE")) { face.setEL_C(currentPoint); } else if (type.equals("RIGHT_EYE")) { face.setER_C(currentPoint); } else if (type.equals("LEFT_OF_LEFT_EYEBROW")) { face.setEBL_L(currentPoint); } else if (type.equals("RIGHT_OF_LEFT_EYEBROW")) { face.setEBL_R(currentPoint); } else if (type.equals("LEFT_OF_RIGHT_EYEBROW")) { face.setEBR_L(currentPoint); } else if (type.equals("RIGHT_OF_RIGHT_EYEBROW")) { face.setEBR_R(currentPoint); } else if (type.equals("MIDPOINT_BETWEEN_EYES")) { face.setE_C(currentPoint); } else if (type.equals("NOSE_TIP")) { face.setN_T(currentPoint); } else if (type.equals("UPPER_LIP")) { face.setL_T(currentPoint); } else if (type.equals("LOWER_LIP")) { face.setL_B(currentPoint); } else if (type.equals("MOUTH_LEFT")) { face.setM_L(currentPoint); } else if (type.equals("MOUTH_RIGHT")) { face.setM_R(currentPoint); } else if (type.equals("MOUTH_CENTER")) { face.setM_C(currentPoint); } else if (type.equals("NOSE_BOTTOM_RIGHT")) { face.setN_RB(currentPoint); } else if (type.equals("NOSE_BOTTOM_LEFT")) { face.setN_LB(currentPoint); } else if (type.equals("NOSE_BOTTOM_CENTER")) { face.setN_CB(currentPoint); } else if (type.equals("LEFT_EYE_TOP_BOUNDARY")) { face.setEL_T(currentPoint); } else if (type.equals("LEFT_EYE_RIGHT_CORNER")) { face.setEL_R(currentPoint); } else if (type.equals("LEFT_EYE_BOTTOM_BOUNDARY")) { face.setEL_B(currentPoint); } else if (type.equals("LEFT_EYE_LEFT_CORNER")) { face.setEL_L(currentPoint); } else if (type.equals("RIGHT_EYE_TOP_BOUNDARY")) { face.setER_T(currentPoint); } else if (type.equals("RIGHT_EYE_RIGHT_CORNER")) { face.setER_R(currentPoint); } else if (type.equals("RIGHT_EYE_BOTTOM_BOUNDARY")) { face.setER_B(currentPoint); } else if (type.equals("RIGHT_EYE_LEFT_CORNER")) { face.setER_L(currentPoint); } else if (type.equals("LEFT_EYEBROW_UPPER_MIDPOINT")) { face.setEBL_M(currentPoint); } else if (type.equals("RIGHT_EYEBROW_UPPER_MIDPOINT")) { face.setEBR_M(currentPoint); } else if (type.equals("LEFT_EAR_TRAGION")) { face.setEA_L(currentPoint); } else if (type.equals("RIGHT_EAR_TRAGION")) { face.setEA_R(currentPoint); } else if (type.equals("FOREHEAD_GLABELLA")) { face.setFORH(currentPoint); } else if (type.equals("CHIN_GNATHION")) { face.setCH(currentPoint); } else if (type.equals("CHIN_LEFT_GONION")) { face.setCH_L(currentPoint); } else if (type.equals("CHIN_RIGHT_GONION")) { face.setCH_R(currentPoint); } else if (type.equals("LEFT_CHEEK_CENTER")) { face.setCK_L(currentPoint); } else if (type.equals("RIGHT_CHEEK_CENTER")) { face.setCK_R(currentPoint); } else { System.out.println("ERRORE!!! Face.fillFaceLandmark tipo non trovato: " + type); } } public double getCalcFaceIdx1() { DoubleOperator dop = new DoubleOperator(); dop.setScale(2, RoundingMode.UNNECESSARY); dop.add(Point.getDistanceNormF(getFace().getEA_L(), getFace().getM_C(), getFace().getScaleFactor())); dop.add(Point.getDistanceNormF(getFace().getEA_R(), getFace().getM_C(), getFace().getScaleFactor())); return dop.getResult(); } public double getCalcFaceIdx2() { DoubleOperator dop = new DoubleOperator(); dop.setScale(2, RoundingMode.UNNECESSARY); dop.add(Point.getDistanceNormF(getFace().getEA_R(), getFace().getN_T(), getFace().getScaleFactor())); dop.add(Point.getDistanceNormF(getFace().getEA_L(), getFace().getN_T(), getFace().getScaleFactor())); dop.add(Point.getDistanceNormF(getFace().getM_C(), getFace().getN_T(), getFace().getScaleFactor())); return dop.getResult(); } public double getCalcFaceIdx3() { DoubleOperator dop = new DoubleOperator(); dop.setScale(2, RoundingMode.UNNECESSARY); dop.add(Point.getDistanceNormF(getFace().getCK_L(), getFace().getCK_R(), getFace().getScaleFactor())); return dop.getResult(); } public double getCalcFaceIdx4() { DoubleOperator dop = new DoubleOperator(); dop.setScale(2, RoundingMode.UNNECESSARY); dop.add(Point.getDistanceNormF(getFace().getEA_R(), getFace().getN_T(), getFace().getScaleFactor())); dop.add(Point.getDistanceNormF(getFace().getEA_L(), getFace().getN_T(), getFace().getScaleFactor())); dop.add(Point.getDistanceNormF(getFace().getM_C(), getFace().getN_T(), getFace().getScaleFactor())); return dop.getResult(); } public double[] getFaceIdRange(double faceId, double percRange) { DoubleOperator scarto = new DoubleOperator(100.0F); scarto.setScale(2, RoundingMode.UNNECESSARY); scarto.subtract(percRange); scarto.multiply(faceId); scarto.divide(100.0F); DoubleOperator min = new DoubleOperator(faceId); min.subtract(scarto); DoubleOperator max = new DoubleOperator(faceId); max.add(scarto); double[] result = { min.getResult(), max.getResult() }; return result; } public ResParm save() { String l_labelDb = getLabelDb(); if (!getJsonData().isEmpty()) { _createFeatureVectorAll(); } else { println("FotoFace: save: " + getFoto().getFileName() + " NO json data on foto face " + getId_fotoFace()); } createFaceImage(false); ResParm rp = super.save(); if (rp.getStatus()) if (!getLabel().equals(l_labelDb)) rp.append(getFoto().updatePettoraliByFotoFace(true)); return rp; } public Face getFace() { if (this.face == null && !getJsonData().isEmpty()) _loadFotoFaceFromFaceJson(false); return this.face; } public void setFace(Face face) { this.face = face; } public ResParm _createFeatureVectorAll() { ResParm rp = new ResParm(); List featureVector = new ArrayList<>(); Double faceHeight = Point.getDistance(getFace().getFORH(), getFace().getM_C()); Double faceWidth = Point.getDistance(getFace().getEA_L(), getFace().getEA_R()); Double eyeDistance = Point.getDistance(getFace().getEL_C(), getFace().getER_C()); Double mouthLen = Point.getDistance(getFace().getM_L(), getFace().getM_R()); Double nooseLen = Point.getDistance(getFace().getE_C(), getFace().getN_CB()); List points = new ArrayList<>(); points.add(getFace().getEL_C()); points.add(getFace().getER_C()); points.add(getFace().getEA_L()); points.add(getFace().getEA_R()); points.add(getFace().getEBL_M()); points.add(getFace().getEBR_M()); points.add(getFace().getCK_L()); points.add(getFace().getCK_R()); points.add(getFace().getM_C()); points.add(getFace().getN_T()); points.add(getFace().getE_C()); points.add(getFace().getFORH()); List distances = new ArrayList<>(); for (int i = 0; i < points.size() - 1; i++) { Point p1 = points.get(i); for (int j = i + 1; j < points.size(); j++) { Point p2 = points.get(j); double distance = Point.getDistance(p1, p2); distances.add(Double.valueOf(distance)); } } double averageDistance = calculateAverageDistance(distances); featureVector.add(Double.valueOf(averageDistance)); Double eyeMouthDistance = Point.getDistance(getFace().getE_C(), getFace().getM_C()); featureVector.add(Double.valueOf(eyeMouthDistance / eyeDistance)); Double eyeNoseDistance = Point.getDistance(getFace().getE_C(), getFace().getN_T()); featureVector.add(Double.valueOf(eyeDistance / eyeNoseDistance)); Double eyeChinDistance = Point.getDistance(getFace().getE_C(), getFace().getCH()); Double eyeLipCHinDistance = Point.getDistance(getFace().getL_B(), getFace().getCH()); featureVector.add(Double.valueOf(eyeDistance / eyeLipCHinDistance)); Double eyeLipNooseDistance = Point.getDistance(getFace().getL_T(), getFace().getN_T()); featureVector.add(Double.valueOf(eyeDistance / eyeLipNooseDistance)); Double eyeEyebrowDistance = Point.getDistance(getFace().getEBL_M(), getFace().getEBR_M()); featureVector.add(Double.valueOf(eyeDistance / eyeEyebrowDistance)); Point midCheekPoint = new Point((getFace().getCK_L().getX() + getFace().getCK_R().getX()) / 2L, ( getFace().getCK_L().getY() + getFace().getCK_R().getY()) / 2L, ( getFace().getCK_L().getZ() + getFace().getCK_R().getZ()) / 2L); Double eyeCheekDistance = Point.getDistance(getFace().getE_C(), midCheekPoint); featureVector.add(Double.valueOf(eyeDistance / eyeCheekDistance)); featureVector.add(eyeDistance); featureVector.add(eyeEyebrowDistance); Double cheekDistance = Point.getDistance(getFace().getCK_L(), getFace().getCK_R()); featureVector.add(cheekDistance); Double mouthCornerDistance = Point.getDistance(getFace().getM_L(), getFace().getM_R()); featureVector.add(mouthCornerDistance); Double chinDistance = Point.getDistance(getFace().getCH_L(), getFace().getCH_R()); featureVector.add(chinDistance); featureVector.add(faceWidth); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getEL_C(), getFace().getE_C(), getFace().getM_C()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getEL_C(), getFace().getN_T(), getFace().getM_C()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getER_C(), getFace().getN_T(), getFace().getM_C()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getEBL_M(), getFace().getEL_C(), getFace().getN_T()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getEBR_M(), getFace().getER_C(), getFace().getN_T()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getEL_C(), getFace().getM_C(), getFace().getCH()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getER_C(), getFace().getM_C(), getFace().getCH()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getEBL_L(), getFace().getEBL_M(), getFace().getEBL_R()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getEBR_L(), getFace().getEBR_M(), getFace().getEBR_R()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getEA_R(), getFace().getN_T(), getFace().getM_C()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getEA_L(), getFace().getN_T(), getFace().getM_C()))); featureVector.add(Double.valueOf(eyeDistance / faceWidth)); Double noseLen = Point.getDistance(getFace().getE_C(), getFace().getN_CB()); featureVector.add(Double.valueOf(noseLen / faceHeight)); featureVector.add(Double.valueOf(mouthLen / faceWidth)); featureVector.add(Double.valueOf(eyeEyebrowDistance / faceWidth)); featureVector.add(Double.valueOf(cheekDistance / faceWidth)); normalizeFeatureVector(featureVector); StringBuilder sb = new StringBuilder(); for (Iterator iterator = featureVector.iterator(); iterator.hasNext(); ) { double element = iterator.next(); sb.append(element); sb.append(","); } setFeatureVector1(sb.toString().substring(1, sb.toString().length() - 1)); return rp; } public ResParm _createFeatureVectorTop() { ResParm rp = new ResParm(); if (getFace() == null) { rp.setStatus(false); rp.setMsg(getFoto().getFileName() + ": No json data..."); return rp; } List featureVector = new ArrayList<>(); List points = new ArrayList<>(); points.add(getFace().getEL_C()); points.add(getFace().getER_C()); points.add(getFace().getEA_L()); points.add(getFace().getEA_R()); points.add(getFace().getCK_L()); points.add(getFace().getCK_R()); points.add(getFace().getM_C()); points.add(getFace().getN_T()); List distances = new ArrayList<>(); for (int i = 0; i < points.size() - 1; i++) { Point p1 = points.get(i); for (int j = i + 1; j < points.size(); j++) { Point p2 = points.get(j); double distance = Point.getDistance(p1, p2); distances.add(Double.valueOf(distance)); } } double averageDistance = calculateAverageDistance(distances); featureVector.add(Double.valueOf(averageDistance)); Double eyeDistance = Point.getDistance(getFace().getEL_C(), getFace().getER_C()); featureVector.add(eyeDistance); Double eyeMouthDistance = Point.getDistance(getFace().getE_C(), getFace().getM_C()); featureVector.add(Double.valueOf(eyeMouthDistance / eyeDistance)); Double eyeNoseDistance = Point.getDistance(getFace().getE_C(), getFace().getN_T()); featureVector.add(Double.valueOf(eyeDistance / eyeNoseDistance)); Double eyeChinDistance = Point.getDistance(getFace().getE_C(), getFace().getCH()); Double eyeEyebrowDistance = Point.getDistance(getFace().getEBL_M(), getFace().getEBR_M()); Point midCheekPoint = new Point((getFace().getCK_L().getX() + getFace().getCK_R().getX()) / 2L, ( getFace().getCK_L().getY() + getFace().getCK_R().getY()) / 2L, ( getFace().getCK_L().getZ() + getFace().getCK_R().getZ()) / 2L); Double eyeCheekDistance = Point.getDistance(getFace().getE_C(), midCheekPoint); Double cheekDistance = Point.getDistance(getFace().getCK_L(), getFace().getCK_R()); featureVector.add(cheekDistance); Double mouthCornerDistance = Point.getDistance(getFace().getM_L(), getFace().getM_R()); Double chinDistance = Point.getDistance(getFace().getCH_L(), getFace().getCH_R()); featureVector.add(chinDistance); Double faceWidth = Point.getDistance(getFace().getEA_L(), getFace().getEA_R()); featureVector.add(faceWidth); Double faceHeight = Point.getDistance(getFace().getFORH(), getFace().getM_C()); featureVector.add(faceHeight); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getEL_C(), getFace().getN_T(), getFace().getM_C()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getER_C(), getFace().getN_T(), getFace().getM_C()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getEL_C(), getFace().getM_C(), getFace().getCH()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getER_C(), getFace().getM_C(), getFace().getCH()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getEA_R(), getFace().getM_C(), getFace().getCH()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getEA_L(), getFace().getM_C(), getFace().getCH()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getER_C(), getFace().getM_C(), getFace().getCH()))); featureVector.add(Double.valueOf(eyeDistance / faceWidth)); Double noseLen = Point.getDistance(getFace().getE_C(), getFace().getN_CB()); featureVector.add(Double.valueOf(noseLen / faceHeight)); Double mouthLen = Point.getDistance(getFace().getM_L(), getFace().getM_R()); featureVector.add(Double.valueOf(cheekDistance / faceWidth)); featureVector.add(Double.valueOf(faceHeight / faceWidth)); normalizeFeatureVector(featureVector); StringBuilder sb = new StringBuilder(); for (Iterator iterator = featureVector.iterator(); iterator.hasNext(); ) { double element = iterator.next(); sb.append(element); sb.append(","); } setFeatureVector1(sb.toString().substring(1, sb.toString().length() - 1)); return rp; } public static double calculateAngleDeg(Point p1, Point p2, Point p3) { Vector3D v1 = new Vector3D((double)p1.getX(), (double)p1.getY(), (double)p1.getZ()); Vector3D v2 = new Vector3D((double)p2.getX(), (double)p2.getY(), (double)p2.getZ()); Vector3D v3 = new Vector3D((double)p3.getX(), (double)p3.getY(), (double)p3.getZ()); Vector3D v12 = v2.subtract((Vector)v1); Vector3D v23 = v2.subtract((Vector)v3); double angRad = Vector3D.angle(v12, v23); return Math.toDegrees(angRad); } public static double calculateAverageDistance(List distances) { double sum = 0.0D; for (Iterator iterator = distances.iterator(); iterator.hasNext(); ) { double distance = iterator.next(); sum += distance; } return sum / (double)distances.size(); } public static void normalizeFeatureVector(List featureVector) { double norm = calculateEuclideanNorm(featureVector); for (int i = 0; i < featureVector.size(); i++) featureVector.set(i, Double.valueOf(featureVector.get(i) / norm)); } private static double calculateEuclideanNorm(List vector) { double sumOfSquares = 0.0D; for (Iterator iterator = vector.iterator(); iterator.hasNext(); ) { double value = iterator.next(); sumOfSquares += value * value; } return Math.sqrt(sumOfSquares); } public static double calculateDotProduct(List featureVector1, List featureVector2) { if (featureVector1.size() != featureVector2.size()) return -1.0D; double dotProduct = 0.0D; for (int i = 0; i < featureVector1.size(); i++) dotProduct += featureVector1.get(i) * featureVector2.get(i); return dotProduct; } public static double calculateEuclideanDistance(List featureVector1, List featureVector2) { if (featureVector1.size() != featureVector2.size()) { System.out.println("calculateEuclideanDistance: " + featureVector1.size() + " " + featureVector2.size()); return 99999.0D; } double sumOfSquares = 0.0D; for (int i = 0; i < featureVector1.size(); i++) { double diff = featureVector1.get(i) - featureVector2.get(i); sumOfSquares += diff * diff; } return Math.sqrt(sumOfSquares); } public long getFaceTopVx() { if (this.faceTopVx == 0L && getFace() != null) this.faceTopVx = getFace().getB_TOP_RIGHT().getX(); return this.faceTopVx; } public void setFaceTopVx(long faceTopVx) { this.faceTopVx = faceTopVx; } public long getFaceTopVy() { if (this.faceTopVy == 0L && getFace() != null) this.faceTopVy = getFace().getB_TOP_RIGHT().getY(); return this.faceTopVy; } public void setFaceTopVy(long faceTopVy) { this.faceTopVy = faceTopVy; } public long getFaceBottomVx() { if (this.faceBottomVx == 0L && getFace() != null) this.faceBottomVx = getFace().getB_BOTTOM_LEFT().getX(); return this.faceBottomVx; } public void setFaceBottomVx(long faceBottomVx) { this.faceBottomVx = faceBottomVx; } public long getFaceBottomVy() { if (this.faceBottomVy == 0L && getFace() != null) this.faceBottomVy = getFace().getB_BOTTOM_LEFT().getY(); return this.faceBottomVy; } public void setFaceBottomVy(long faceBottomVy) { this.faceBottomVy = faceBottomVy; } public String getFeatureVector1() { return (this.featureVector1 == null) ? "" : this.featureVector1.trim(); } public void setFeatureVector1(String featureVector1) { this.featureVector1 = featureVector1; } public String getFeatureVector2() { return (this.featureVector2 == null) ? "" : this.featureVector2.trim(); } public void setFeatureVector2(String featureVector2) { this.featureVector2 = featureVector2; } public Vectumerator findByFoto(long l_id_foto) { String s_Sql_Find = "select A.* from FOTO_FACE AS A"; String s_Sql_Order = " order by faceTopVx"; WcString wc = new WcString(); wc.addWc("A.id_foto=" + l_id_foto); try { PreparedStatement stmt = getConn().prepareStatement(s_Sql_Find + s_Sql_Find + wc.toString()); return findRows(stmt); } catch (SQLException e) { removeCPConnection(); handleDebug(e); return AB_EMPTY_VECTUMERATOR; } } public Vectumerator findByFotoConLabel(long l_id_foto) { String s_Sql_Find = "select A.* from FOTO_FACE AS A"; String s_Sql_Order = " order by faceTopVx"; WcString wc = new WcString(); wc.addWc("A.id_foto=" + l_id_foto); wc.addWc("(A.label is not null or A.label <>'')"); try { PreparedStatement stmt = getConn().prepareStatement(s_Sql_Find + s_Sql_Find + wc.toString()); return findRows(stmt); } catch (SQLException e) { removeCPConnection(); handleDebug(e); return AB_EMPTY_VECTUMERATOR; } } public List getFetureVetctor1list() { if (getFeatureVector1().isEmpty()) return null; StringTokenizer st = new StringTokenizer(getFeatureVector1(), ","); List res = new ArrayList<>(); while (st.hasMoreTokens()) { String token = st.nextToken(); res.add(Double.valueOf(Double.parseDouble(token))); } return res; } public ResParm _createFeatureVectorBottom() { ResParm rp = new ResParm(); if (getFace() == null) { rp.setStatus(false); rp.setMsg(getFoto().getFileName() + ": No json data..."); return rp; } List featureVector = new ArrayList<>(); List points = new ArrayList<>(); points.add(getFace().getEL_C()); points.add(getFace().getER_C()); points.add(getFace().getEA_L()); points.add(getFace().getEA_R()); points.add(getFace().getCK_L()); points.add(getFace().getCK_R()); points.add(getFace().getM_C()); points.add(getFace().getN_T()); List distances = new ArrayList<>(); for (int i = 0; i < points.size() - 1; i++) { Point p1 = points.get(i); for (int j = i + 1; j < points.size(); j++) { Point p2 = points.get(j); double distance = Point.getDistance(p1, p2); distances.add(Double.valueOf(distance)); } } double averageDistance = calculateAverageDistance(distances); featureVector.add(Double.valueOf(averageDistance)); Double eyeDistance = Point.getDistance(getFace().getEL_C(), getFace().getER_C()); featureVector.add(eyeDistance); Double eyeMouthDistance = Point.getDistance(getFace().getE_C(), getFace().getM_C()); featureVector.add(Double.valueOf(eyeMouthDistance / eyeDistance)); Double eyeNoseDistance = Point.getDistance(getFace().getE_C(), getFace().getN_T()); featureVector.add(Double.valueOf(eyeDistance / eyeNoseDistance)); Double eyeChinDistance = Point.getDistance(getFace().getE_C(), getFace().getCH()); Double eyeEyebrowDistance = Point.getDistance(getFace().getEBL_M(), getFace().getEBR_M()); Point midCheekPoint = new Point((getFace().getCK_L().getX() + getFace().getCK_R().getX()) / 2L, ( getFace().getCK_L().getY() + getFace().getCK_R().getY()) / 2L, ( getFace().getCK_L().getZ() + getFace().getCK_R().getZ()) / 2L); Double eyeCheekDistance = Point.getDistance(getFace().getE_C(), midCheekPoint); Double cheekDistance = Point.getDistance(getFace().getCK_L(), getFace().getCK_R()); featureVector.add(cheekDistance); Double mouthCornerDistance = Point.getDistance(getFace().getM_L(), getFace().getM_R()); Double chinDistance = Point.getDistance(getFace().getCH_L(), getFace().getCH_R()); featureVector.add(chinDistance); Double faceWidth = Point.getDistance(getFace().getEA_L(), getFace().getEA_R()); featureVector.add(faceWidth); Double faceHeight = Point.getDistance(getFace().getFORH(), getFace().getM_C()); featureVector.add(faceHeight); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getEL_C(), getFace().getN_T(), getFace().getM_C()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getER_C(), getFace().getN_T(), getFace().getM_C()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getEL_C(), getFace().getM_C(), getFace().getCH()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getER_C(), getFace().getM_C(), getFace().getCH()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getEA_R(), getFace().getM_C(), getFace().getCH()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getEA_L(), getFace().getM_C(), getFace().getCH()))); featureVector.add(Double.valueOf(calculateAngleDeg(getFace().getER_C(), getFace().getM_C(), getFace().getCH()))); featureVector.add(Double.valueOf(eyeDistance / faceWidth)); Double noseLen = Point.getDistance(getFace().getE_C(), getFace().getN_CB()); featureVector.add(Double.valueOf(noseLen / faceHeight)); Double mouthLen = Point.getDistance(getFace().getM_L(), getFace().getM_R()); featureVector.add(Double.valueOf(cheekDistance / faceWidth)); featureVector.add(Double.valueOf(faceHeight / faceWidth)); normalizeFeatureVector(featureVector); StringBuilder sb = new StringBuilder(); for (Iterator iterator = featureVector.iterator(); iterator.hasNext(); ) { double element = iterator.next(); sb.append(element); sb.append(","); } setFeatureVector1(sb.toString().substring(1, sb.toString().length() - 1)); return rp; } public String getFileName() { if (this.fileName == null || this.fileName.isEmpty()) this .fileName = getFoto().getFileNameReale() + " _" + getFoto().getFileNameReale() + "_tr-" + getId_fotoFace() + "-" + getFaceTopVx() + "_bl-" + getFaceTopVy() + "-" + getFaceBottomVx() + ".jpg"; return (this.fileName == null) ? "" : this.fileName.trim(); } public void setFileName(String fileName) { this.fileName = fileName; } public String getLabel() { return (this.label == null) ? "" : this.label.trim(); } public void setLabel(String label) { this.label = label; } public ResParm createFaceImage(boolean overwrite) { ResParm rp = new ResParm(); if (getId_fotoFace() > 0L && hasImageBounds()) try { File faceImg = new File(getFullFaceImgPath()); if (!faceImg.exists() || overwrite) { if (faceImg.exists()) faceImg.delete(); BufferedImage sourceImage = ImageIO.read(new File(getFoto().getFileNameFullPath())); int sourceWidth = sourceImage.getWidth(); int sourceHeight = sourceImage.getHeight(); int margin = 10; int faceTopRightX = (int)getFaceTopVx() + margin; int faceTopRightY = (int)getFaceTopVy() - margin; int faceBottomLeftX = (int)getFaceBottomVx() - margin; int faceBottomLeftY = (int)getFaceBottomVy() + margin; int faceTopLeftX = faceBottomLeftX; int faceTopLeftY = faceTopRightY; int faceBottomRightX = faceTopRightX; int faceBottomRightY = faceBottomLeftY; int faceWidth = faceBottomRightX - faceTopLeftX; int faceHeight = faceBottomRightY - faceTopLeftY; DoubleOperator percW = new DoubleOperator((double)sourceWidth, 4); percW.divide((float)faceWidth); percW.subtract(1); percW.multiply(100); DoubleOperator percH = new DoubleOperator((double)sourceHeight, 4); percH.divide((float)faceHeight); percH.subtract(1); percH.multiply(100); File targetDir = new File(getFoto().getPuntoFoto().getPathCompletoFotoFace()); if (!targetDir.exists()) targetDir.mkdirs(); if (percW.getResult() < 26.0D || percH.getResult() < 26.0D) { DBAdapter.copyFile(getFoto().getFileNameFullPath(), getFullFaceImgPath()); } else { BufferedImage faceImage = sourceImage.getSubimage(faceTopLeftX, faceTopLeftY, faceWidth, faceHeight); ImageIO.write(faceImage, "jpg", faceImg); } } } catch (Exception e) { e.printStackTrace(); } return rp; } public String getFullFaceImgPath() { return getFoto().getPuntoFoto().getPathCompletoFotoFace() + "/" + getFoto().getPuntoFoto().getPathCompletoFotoFace(); } protected void fillFields(ResultSet rst) { super.fillFields(rst); setLabelDb(getLabel()); createFaceImage(false); } public boolean hasImageBounds() { if (getFaceTopVx() == 0L || getFaceBottomVx() == 0L || getFaceBottomVy() == 0L || getFaceTopVy() == 0L) return false; return true; } public String getLabelDb() { return (this.labelDb == null) ? "" : this.labelDb.trim(); } public void setLabelDb(String labelDb) { this.labelDb = labelDb; } protected void initFields() { super.initFields(); setLabelDb(null); } }