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.
|
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>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user