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