Pull out the alignment

This commit is contained in:
Manav Rathi
2024-05-30 09:43:22 +05:30
parent 54654159ff
commit bae4c65ab3
3 changed files with 33 additions and 34 deletions

View File

@@ -1,9 +1,14 @@
import { blobCache } from "@/next/blob-cache";
import type { FaceAlignment } from "./f-index";
import type { Box } from "./types";
import type { Face, FaceAlignment } from "./types-old";
import type { Face } from "./types-old";
export const saveFaceCrop = async (imageBitmap: ImageBitmap, face: Face) => {
const faceCrop = extractFaceCrop(imageBitmap, face.alignment);
export const saveFaceCrop = async (
imageBitmap: ImageBitmap,
face: Face,
alignment: FaceAlignment,
) => {
const faceCrop = extractFaceCrop(imageBitmap, alignment);
const blob = await imageBitmapToBlob(faceCrop);
faceCrop.close();

View File

@@ -22,12 +22,7 @@ import {
warpAffineFloat32List,
} from "./image";
import type { Box, Dimensions } from "./types";
import type {
Face,
FaceAlignment,
FaceDetection,
MlFileData,
} from "./types-old";
import type { Face, FaceDetection, MlFileData } from "./types-old";
/**
* Index faces in the given file.
@@ -109,11 +104,12 @@ const indexFaces_ = async (enteFile: EnteFile, imageBitmap: ImageBitmap) => {
const alignments: FaceAlignment[] = [];
for (const face of mlFile.faces) {
const alignment = faceAlignment(face.detection);
face.alignment = alignment;
const alignment = computeFaceAlignment(face.detection);
alignments.push(alignment);
await saveFaceCrop(imageBitmap, face);
// This step is not really part of the indexing pipeline, we just do
// it here since we have already computed the face alignment.
await saveFaceCrop(imageBitmap, face, alignment);
}
const alignedFacesData = convertToMobileFaceNetInput(
@@ -393,13 +389,30 @@ const makeFaceID = (
return [`${fileID}`, xMin, yMin, xMax, yMax].join("_");
};
export interface FaceAlignment {
/**
* An affine transformation matrix (rotation, translation, scaling) to align
* the face extracted from the image.
*/
affineMatrix: number[][];
/**
* The bounding box of the transformed box.
*
* The affine transformation shifts the original detection box a new,
* transformed, box (possibily rotated). This property is the bounding box
* of that transformed box. It is in the coordinate system of the original,
* full, image on which the detection occurred.
*/
boundingBox: Box;
}
/**
* Compute and return an {@link FaceAlignment} for the given face detection.
*
* @param faceDetection A geometry indicating a face detected in an image.
*/
const faceAlignment = (faceDetection: FaceDetection): FaceAlignment =>
faceAlignmentUsingSimilarityTransform(
const computeFaceAlignment = (faceDetection: FaceDetection): FaceAlignment =>
computeFaceAlignmentUsingSimilarityTransform(
faceDetection,
normalizeLandmarks(idealMobileFaceNetLandmarks, mobileFaceNetFaceSize),
);
@@ -422,7 +435,7 @@ const normalizeLandmarks = (
): [number, number][] =>
landmarks.map(([x, y]) => [x / faceSize, y / faceSize]);
const faceAlignmentUsingSimilarityTransform = (
const computeFaceAlignmentUsingSimilarityTransform = (
faceDetection: FaceDetection,
alignedLandmarks: [number, number][],
): FaceAlignment => {

View File

@@ -7,29 +7,10 @@ export interface FaceDetection {
probability?: number;
}
export interface FaceAlignment {
/**
* An affine transformation matrix (rotation, translation, scaling) to align
* the face extracted from the image.
*/
affineMatrix: number[][];
/**
* The bounding box of the transformed box.
*
* The affine transformation shifts the original detection box a new,
* transformed, box (possibily rotated). This property is the bounding box
* of that transformed box. It is in the coordinate system of the original,
* full, image on which the detection occurred.
*/
boundingBox: Box;
}
export interface Face {
fileId: number;
detection: FaceDetection;
id: string;
alignment?: FaceAlignment;
blurValue?: number;
embedding?: Float32Array;