Commit d098169b by vincent

fixed the face alignment bug in allFaces + default parameters

parent 5cc2741b
...@@ -105,7 +105,7 @@ export class FaceLandmarks { ...@@ -105,7 +105,7 @@ export class FaceLandmarks {
const x = Math.floor(Math.max(0, refPoint.x - (relX * size))) const x = Math.floor(Math.max(0, refPoint.x - (relX * size)))
const y = Math.floor(Math.max(0, refPoint.y - (relY * size))) const y = Math.floor(Math.max(0, refPoint.y - (relY * size)))
return new Rect(x, y, Math.min(size, this._imageWidth - x), Math.min(size, this._imageHeight - y)) return new Rect(x, y, Math.min(size, this._imageWidth + x), Math.min(size, this._imageHeight + y))
} }
protected getRefPointsForAlignment(): Point[] { protected getRefPointsForAlignment(): Point[] {
......
...@@ -2,25 +2,45 @@ import { extractFaceTensors } from './extractFaceTensors'; ...@@ -2,25 +2,45 @@ import { extractFaceTensors } from './extractFaceTensors';
import { FaceDetectionNet } from './faceDetectionNet/FaceDetectionNet'; import { FaceDetectionNet } from './faceDetectionNet/FaceDetectionNet';
import { FaceLandmarkNet } from './faceLandmarkNet/FaceLandmarkNet'; import { FaceLandmarkNet } from './faceLandmarkNet/FaceLandmarkNet';
import { FaceLandmarks68 } from './faceLandmarkNet/FaceLandmarks68'; import { FaceLandmarks68 } from './faceLandmarkNet/FaceLandmarks68';
import { FaceRecognitionNet } from './faceRecognitionNet/FaceRecognitionNet';
import { FullFaceDescription } from './FullFaceDescription'; import { FullFaceDescription } from './FullFaceDescription';
import { Mtcnn } from './mtcnn/Mtcnn'; import { Mtcnn } from './mtcnn/Mtcnn';
import { MtcnnForwardParams } from './mtcnn/types'; import { MtcnnForwardParams } from './mtcnn/types';
import { Rect } from './Rect'; import { Rect } from './Rect';
import { TNetInput } from './types'; import { TNetInput } from './types';
function computeDescriptorsFactory(
recognitionNet: FaceRecognitionNet
) {
return async function(input: TNetInput, alignedFaceBoxes: Rect[], useBatchProcessing: boolean) {
const alignedFaceTensors = await extractFaceTensors(input, alignedFaceBoxes)
const descriptors = useBatchProcessing
? await recognitionNet.computeFaceDescriptor(alignedFaceTensors) as Float32Array[]
: await Promise.all(alignedFaceTensors.map(
faceTensor => recognitionNet.computeFaceDescriptor(faceTensor)
)) as Float32Array[]
alignedFaceTensors.forEach(t => t.dispose())
return descriptors
}
}
export function allFacesFactory( export function allFacesFactory(
detectionNet: FaceDetectionNet, detectionNet: FaceDetectionNet,
landmarkNet: FaceLandmarkNet, landmarkNet: FaceLandmarkNet,
computeDescriptors: (input: TNetInput, alignedFaceBoxes: Rect[], useBatchProcessing: boolean) => Promise<Float32Array[]> recognitionNet: FaceRecognitionNet
) { ) {
const computeDescriptors = computeDescriptorsFactory(recognitionNet)
return async function( return async function(
input: TNetInput, input: TNetInput,
minConfidence: number, minConfidence: number = 0.8,
useBatchProcessing: boolean = false useBatchProcessing: boolean = false
): Promise<FullFaceDescription[]> { ): Promise<FullFaceDescription[]> {
const detections = await detectionNet.locateFaces(input, minConfidence) const detections = await detectionNet.locateFaces(input, minConfidence)
const faceTensors = await extractFaceTensors(input, detections) const faceTensors = await extractFaceTensors(input, detections)
const faceLandmarksByFace = useBatchProcessing const faceLandmarksByFace = useBatchProcessing
...@@ -50,11 +70,13 @@ export function allFacesFactory( ...@@ -50,11 +70,13 @@ export function allFacesFactory(
export function allFacesMtcnnFactory( export function allFacesMtcnnFactory(
mtcnn: Mtcnn, mtcnn: Mtcnn,
computeDescriptors: (input: TNetInput, alignedFaceBoxes: Rect[], useBatchProcessing: boolean) => Promise<Float32Array[]> recognitionNet: FaceRecognitionNet
) { ) {
const computeDescriptors = computeDescriptorsFactory(recognitionNet)
return async function( return async function(
input: TNetInput, input: TNetInput,
mtcnnForwardParams: MtcnnForwardParams, mtcnnForwardParams: MtcnnForwardParams = {},
useBatchProcessing: boolean = false useBatchProcessing: boolean = false
): Promise<FullFaceDescription[]> { ): Promise<FullFaceDescription[]> {
......
...@@ -50,7 +50,7 @@ export class FaceDetectionNet extends NeuralNetwork<NetParams> { ...@@ -50,7 +50,7 @@ export class FaceDetectionNet extends NeuralNetwork<NetParams> {
public async locateFaces( public async locateFaces(
input: TNetInput, input: TNetInput,
minConfidence: number = 0.8, minConfidence: number = 0.8,
maxResults: number = 100, maxResults: number = 100
): Promise<FaceDetection[]> { ): Promise<FaceDetection[]> {
const netInput = await toNetInput(input, true) const netInput = await toNetInput(input, true)
......
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { allFacesFactory, allFacesMtcnnFactory } from './allFacesFactory'; import { allFacesFactory, allFacesMtcnnFactory } from './allFacesFactory';
import { extractFaceTensors } from './extractFaceTensors';
import { FaceDetection } from './FaceDetection'; import { FaceDetection } from './FaceDetection';
import { FaceDetectionNet } from './faceDetectionNet/FaceDetectionNet'; import { FaceDetectionNet } from './faceDetectionNet/FaceDetectionNet';
import { FaceLandmarkNet } from './faceLandmarkNet/FaceLandmarkNet'; import { FaceLandmarkNet } from './faceLandmarkNet/FaceLandmarkNet';
...@@ -11,7 +10,6 @@ import { FullFaceDescription } from './FullFaceDescription'; ...@@ -11,7 +10,6 @@ import { FullFaceDescription } from './FullFaceDescription';
import { Mtcnn } from './mtcnn/Mtcnn'; import { Mtcnn } from './mtcnn/Mtcnn';
import { MtcnnForwardParams, MtcnnResult } from './mtcnn/types'; import { MtcnnForwardParams, MtcnnResult } from './mtcnn/types';
import { NetInput } from './NetInput'; import { NetInput } from './NetInput';
import { Rect } from './Rect';
import { TNetInput } from './types'; import { TNetInput } from './types';
export const detectionNet = new FaceDetectionNet() export const detectionNet = new FaceDetectionNet()
...@@ -79,39 +77,25 @@ export function mtcnn( ...@@ -79,39 +77,25 @@ export function mtcnn(
return nets.mtcnn.forward(input, forwardParams) return nets.mtcnn.forward(input, forwardParams)
} }
export const allFaces: ( export type allFacesFunction = (
input: tf.Tensor | NetInput | TNetInput, input: tf.Tensor | NetInput | TNetInput,
minConfidence: number, minConfidence?: number,
useBatchProcessing?: boolean useBatchProcessing?: boolean
) => Promise<FullFaceDescription[]> = allFacesFactory( ) => Promise<FullFaceDescription[]>
detectionNet,
landmarkNet, export const allFaces: allFacesFunction = allFacesFactory(
computeDescriptorsFactory(nets.faceRecognitionNet) nets.ssdMobilenet,
nets.faceLandmark68Net,
nets.faceRecognitionNet
) )
export const allFacesMtcnn: ( export type allFacesMtcnnFunction = (
input: tf.Tensor | NetInput | TNetInput, input: tf.Tensor | NetInput | TNetInput,
mtcnnForwardParams: MtcnnForwardParams, mtcnnForwardParams?: MtcnnForwardParams,
useBatchProcessing?: boolean useBatchProcessing?: boolean
) => Promise<FullFaceDescription[]> = allFacesMtcnnFactory( ) => Promise<FullFaceDescription[]>
nets.mtcnn,
computeDescriptorsFactory(nets.faceRecognitionNet)
)
function computeDescriptorsFactory( export const allFacesMtcnn: allFacesMtcnnFunction = allFacesMtcnnFactory(
recognitionNet: FaceRecognitionNet nets.mtcnn,
) { nets.faceRecognitionNet
return async function(input: TNetInput, alignedFaceBoxes: Rect[], useBatchProcessing: boolean) { )
const alignedFaceTensors = await extractFaceTensors(input, alignedFaceBoxes) \ No newline at end of file
const descriptors = useBatchProcessing
? await recognitionNet.computeFaceDescriptor(alignedFaceTensors) as Float32Array[]
: await Promise.all(alignedFaceTensors.map(
faceTensor => recognitionNet.computeFaceDescriptor(faceTensor)
)) as Float32Array[]
alignedFaceTensors.forEach(t => t.dispose())
return descriptors
}
}
\ No newline at end of file
...@@ -28,7 +28,7 @@ export class Mtcnn extends NeuralNetwork<NetParams> { ...@@ -28,7 +28,7 @@ export class Mtcnn extends NeuralNetwork<NetParams> {
public async forwardInput( public async forwardInput(
input: NetInput, input: NetInput,
forwardParams: MtcnnForwardParams forwardParams: MtcnnForwardParams = {}
): Promise<{ results: MtcnnResult[], stats: any }> { ): Promise<{ results: MtcnnResult[], stats: any }> {
const { params } = this const { params } = this
...@@ -132,7 +132,7 @@ export class Mtcnn extends NeuralNetwork<NetParams> { ...@@ -132,7 +132,7 @@ export class Mtcnn extends NeuralNetwork<NetParams> {
public async forward( public async forward(
input: TNetInput, input: TNetInput,
forwardParams: MtcnnForwardParams forwardParams: MtcnnForwardParams = {}
): Promise<MtcnnResult[]> { ): Promise<MtcnnResult[]> {
return ( return (
await this.forwardInput( await this.forwardInput(
...@@ -144,7 +144,7 @@ export class Mtcnn extends NeuralNetwork<NetParams> { ...@@ -144,7 +144,7 @@ export class Mtcnn extends NeuralNetwork<NetParams> {
public async forwardWithStats( public async forwardWithStats(
input: TNetInput, input: TNetInput,
forwardParams: MtcnnForwardParams forwardParams: MtcnnForwardParams = {}
): Promise<{ results: MtcnnResult[], stats: any }> { ): Promise<{ results: MtcnnResult[], stats: any }> {
return this.forwardInput( return this.forwardInput(
await toNetInput(input, true, true), await toNetInput(input, true, true),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment