2020-12-23 18:58:47 +01:00
|
|
|
import * as tf from '../../dist/tfjs.esm';
|
2020-08-18 13:54:53 +02:00
|
|
|
|
2020-12-19 17:46:41 +01:00
|
|
|
import { Rect } from '../classes/index';
|
2020-08-18 13:54:53 +02:00
|
|
|
import { FaceDetection } from '../classes/FaceDetection';
|
2020-12-19 17:46:41 +01:00
|
|
|
import { isTensor3D, isTensor4D } from '../utils/index';
|
2020-08-18 13:54:53 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Extracts the tensors of the image regions containing the detected faces.
|
|
|
|
* Useful if you want to compute the face descriptors for the face images.
|
|
|
|
* Using this method is faster then extracting a canvas for each face and
|
|
|
|
* converting them to tensors individually.
|
|
|
|
*
|
|
|
|
* @param imageTensor The image tensor that face detection has been performed on.
|
|
|
|
* @param detections The face detection results or face bounding boxes for that image.
|
|
|
|
* @returns Tensors of the corresponding image region for each detected face.
|
|
|
|
*/
|
2021-03-20 02:39:45 +01:00
|
|
|
export async function extractFaceTensors(imageTensor: tf.Tensor3D | tf.Tensor4D, detections: Array<FaceDetection | Rect>): Promise<tf.Tensor3D[]> {
|
2020-08-18 13:54:53 +02:00
|
|
|
if (!isTensor3D(imageTensor) && !isTensor4D(imageTensor)) {
|
2020-12-23 17:26:55 +01:00
|
|
|
throw new Error('extractFaceTensors - expected image tensor to be 3D or 4D');
|
2020-08-18 13:54:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (isTensor4D(imageTensor) && imageTensor.shape[0] > 1) {
|
2020-12-23 17:26:55 +01:00
|
|
|
throw new Error('extractFaceTensors - batchSize > 1 not supported');
|
2020-08-18 13:54:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return tf.tidy(() => {
|
2020-12-23 17:26:55 +01:00
|
|
|
const [imgHeight, imgWidth, numChannels] = imageTensor.shape.slice(isTensor4D(imageTensor) ? 1 : 0);
|
2020-08-18 13:54:53 +02:00
|
|
|
|
2021-03-20 02:39:45 +01:00
|
|
|
const boxes = detections
|
|
|
|
.map((det) => (det instanceof FaceDetection
|
2020-08-18 13:54:53 +02:00
|
|
|
? det.forSize(imgWidth, imgHeight).box
|
2021-03-20 02:39:45 +01:00
|
|
|
: det))
|
2020-12-23 17:26:55 +01:00
|
|
|
.map((box) => box.clipAtImageBorders(imgWidth, imgHeight));
|
2020-08-18 13:54:53 +02:00
|
|
|
|
2020-12-23 17:26:55 +01:00
|
|
|
const faceTensors = boxes.map(({
|
|
|
|
x, y, width, height,
|
|
|
|
}) => tf.slice3d(imageTensor.as3D(imgHeight, imgWidth, numChannels), [y, x, 0], [height, width, numChannels]));
|
2020-08-18 13:54:53 +02:00
|
|
|
|
2020-12-23 17:26:55 +01:00
|
|
|
return faceTensors;
|
|
|
|
});
|
|
|
|
}
|