Added best guess

Signed-off-by: James Ketrenos <james_gitlab@ketrenos.com>
This commit is contained in:
James Ketrenos 2020-01-20 19:15:10 -08:00
parent 2e5955acd9
commit a8165046d5

View File

@ -9,7 +9,7 @@
3. Put a UI that let's the user pick from existing identities. 3. Put a UI that let's the user pick from existing identities.
4. Select / Deselect all faces that match 4. Select / Deselect all faces that match
5. "Match" to bind the faces to the identity 5. "Match" to bind the faces to the identity
6 Create new Identity 6. Create new Identity
*/ */
@ -53,6 +53,8 @@ function shuffle(array) {
document.addEventListener("DOMContentLoaded", (event) => { document.addEventListener("DOMContentLoaded", (event) => {
loadFace(); loadFace();
const newIdentity = document.getElementById("new-identity");
newIdentity.appendChild(createNewIdenityEditor());
}); });
function loadFace(id) { function loadFace(id) {
@ -71,36 +73,43 @@ function loadFace(id) {
const editor = document.createElement("div"); const editor = document.createElement("div");
editor.classList.add("editor"); editor.classList.add("editor");
editor.appendChild(createFace(face.id, face.photoId)); editor.appendChild(createFace(face.id, face.photoId));
for (let key in face) { let row = document.createElement("div"),
const row = document.createElement("div"), label = document.createElement("div"),
left = document.createElement("div"); a = document.createElement("a");
row.classList.add("editor-row"); row.classList.add("editor-row");
left.classList.add("key"); label.textContent = "View photo: ";
left.textContent = key; row.appendChild(label);
a.setAttribute("target", "photo-" + face.photoId);
let right; a.href = "face-explorer.html?" + face.photoId;
a.textContent = "photo " + face.photoId;
if (key == "relatedFaces") { row.appendChild(a);
right = document.createElement("div"); editor.appendChild(row);
right.classList.add("related-faces"); row = document.createElement("div");
for (let i = 0; i < face.relatedFaces.length && i < 20; i++) { row.classList.add("editor-row");
let relation = face.relatedFaces[i]; let message = "Related faces: ",
const distance = document.createElement("div"), max = Math.min(face.relatedFaces.length, 9);
facePhoto = createFace(relation.faceId, relation.photoId, true); if (max > 0) {
distance.classList.add("distance"); message += face.relatedFaces.length + " related. Showing top " + max + ". (tap to deselect)";
distance.textContent = relation.distance.toFixed(2); } else {
facePhoto.appendChild(distance); message += "No matches found.";
right.appendChild(facePhoto);
}
} else {
right = document.createElement("input");
right.value = face[key];
}
row.appendChild(left);
row.appendChild(right);
editor.appendChild(row);
} }
row.textContent = message;
editor.appendChild(row);
row = document.createElement("div");
row.classList.add("editor-row");
row.classList.add("related-faces");
for (let i = 0; i < max; i++) {
let relation = face.relatedFaces[i];
const distance = document.createElement("div"),
facePhoto = createFace(relation.faceId, relation.photoId, true);
distance.classList.add("distance");
distance.textContent = relation.distance.toFixed(2);
facePhoto.appendChild(distance);
row.appendChild(facePhoto);
}
editor.appendChild(row);
faceEditorBlock.appendChild(editor); faceEditorBlock.appendChild(editor);
}); });
@ -112,8 +121,6 @@ function getIdentities(id) {
const search = id ? "?withScore=" + id : ""; const search = id ? "?withScore=" + id : "";
window.fetch("api/v1/identities" + search).then(res => res.json()).then((identities) => { window.fetch("api/v1/identities" + search).then(res => res.json()).then((identities) => {
identitiesBlock.appendChild(createNewIdenityEditor());
identities.sort((a, b) => { identities.sort((a, b) => {
if (a.lastName == b.lastName) { if (a.lastName == b.lastName) {
return a.firstName.localeCompare(b.firstName); return a.firstName.localeCompare(b.firstName);
@ -163,15 +170,41 @@ function getIdentities(id) {
}); });
div = document.createElement("div"); div = document.createElement("div");
div.classList.add("face-block"); div.classList.add("face-block");
let minDistance = {
distance: 1
};
for (let i = 0; i < identity.relatedFaces.length && i < 4; i++) { for (let i = 0; i < identity.relatedFaces.length && i < 4; i++) {
const facePhoto = createFace(identity.relatedFaces[i].faceId, identity.relatedFaces[i].photoId), const target = identity.relatedFaces[i];
const facePhoto = createFace(target.faceId, target.photoId),
distance = document.createElement("div"); distance = document.createElement("div");
if (target.distance < minDistance.distance) {
minDistance.distance = target.distance;
minDistance.photoId = target.photoId;
minDistance.faceId = target.faceId;
}
distance.classList.add("distance"); distance.classList.add("distance");
distance.textContent = identity.relatedFaces[i].distance.toFixed(2); distance.textContent = target.distance.toFixed(2);
facePhoto.appendChild(distance); facePhoto.appendChild(distance);
div.appendChild(facePhoto); div.appendChild(facePhoto);
} }
if (minDistance.distance < 0.4) {
const bestMatch = document.getElementById("best-match");
const distance = document.createElement("div"),
facePhoto = createFace(minDistance.faceId, minDistance.photoId);
distance.classList.add("distance");
distance.textContent = minDistance.distance.toFixed(2);
facePhoto.appendChild(distance);
bestMatch.innerHTML = "";
bestMatch.appendChild(facePhoto);
} else {
const bestMatch = document.getElementById("best-match");
bestMatch.innerHTML = "No best guess for match.";
}
block.appendChild(div); block.appendChild(div);
identitiesBlock.appendChild(block); identitiesBlock.appendChild(block);
}); });
@ -183,6 +216,11 @@ function createNewIdenityEditor() {
block.classList.add("block"); block.classList.add("block");
const editor = document.createElement("div"); const editor = document.createElement("div");
editor.classList.add("editor"); editor.classList.add("editor");
const button = document.createElement("button");
button.textContent = "New Identity";
editor.appendChild(button);
[ "lastName", "firstName", "middleName", "name" ].forEach((key) => { [ "lastName", "firstName", "middleName", "name" ].forEach((key) => {
const row = document.createElement("div"), const row = document.createElement("div"),
left = document.createElement("div"), left = document.createElement("div"),
@ -194,8 +232,7 @@ function createNewIdenityEditor() {
row.appendChild(right); row.appendChild(right);
editor.appendChild(row); editor.appendChild(row);
}); });
const button = document.createElement("button");
button.textContent = "New Identity";
button.addEventListener("click", (event) => { button.addEventListener("click", (event) => {
const rows = event.currentTarget.parentElement.querySelectorAll(".editor-row"), const rows = event.currentTarget.parentElement.querySelectorAll(".editor-row"),
object = {}; object = {};
@ -222,7 +259,6 @@ function createNewIdenityEditor() {
loadFace(parseInt(face.getAttribute("face-id"))); loadFace(parseInt(face.getAttribute("face-id")));
}); });
}); });
editor.appendChild(button);
block.appendChild(editor); block.appendChild(editor);
return block; return block;
@ -243,6 +279,19 @@ body {
cursor: pointer; cursor: pointer;
} }
#face-editor {
max-width: calc(128px * 4);
}
#face-editor .related-faces {
display: flex;
flex-wrap: wrap;
}
#new-identity {
padding: 0.5em;
}
#identities { #identities {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
@ -290,6 +339,7 @@ body {
height: 128px; height: 128px;
background-size: contain; background-size: contain;
background-position: center center; background-position: center center;
background-repeat: no-repeat;
display: inline-block; display: inline-block;
border: 1px solid black; border: 1px solid black;
margin: 0.5em; margin: 0.5em;
@ -323,6 +373,12 @@ body {
</style> </style>
<body> <body>
<div id="face-editor" class="block"></div> <div style="display:flex;flex-direction:column">
<div id="identities" class="block"></div> <div style="display:flex;flex-direction:row">
<div id="face-editor" class="block"></div>
<div id="best-match" class="block"></div>
<div id="new-identity" class="block"></div>
</div>
<div id="identities" class="block"></div>
</div>
</body> </body>