This commit is contained in:
watsonb8
2020-12-19 17:09:39 -05:00
parent cf2c20b6e0
commit a57b576962
10 changed files with 443 additions and 21 deletions

View File

@ -9,10 +9,22 @@ export const minConfidence = 0.4;
export const inputSize = 416;
export const scoreThreshold = 0.5;
export const getFaceDetectorOptions = (net: faceapi.NeuralNetwork<any>) => {
export const getFaceDetectorOptions = (
net: faceapi.NeuralNetwork<any>,
options?: {
confidence?: number;
inputSize?: number;
scoreThreshold?: number;
}
) => {
return net === faceapi.nets.ssdMobilenetv1
? new faceapi.SsdMobilenetv1Options({ minConfidence })
: new faceapi.TinyFaceDetectorOptions({ inputSize, scoreThreshold });
? new faceapi.SsdMobilenetv1Options({
minConfidence: options?.confidence ?? minConfidence,
})
: new faceapi.TinyFaceDetectorOptions({
inputSize: options?.inputSize ?? inputSize,
scoreThreshold: options?.scoreThreshold ?? scoreThreshold,
});
};
export const saveFile = async (

View File

@ -12,6 +12,7 @@ export interface IConfig extends PlatformConfig {
debug?: boolean;
writeOutput?: boolean;
rate?: number;
confidence?: number;
}
export interface IRoom {

View File

@ -87,7 +87,8 @@ export class HomeLocationPlatform implements DynamicPlatformPlugin {
if (this.config.trainOnStartup) {
const trainer = new Trainer(
this.config.refImageDirectory,
this.config.trainedModelDirectory
this.config.trainedModelDirectory,
this.config.confidence
);
faceMatcher = await trainer.train(true);
} else {

View File

@ -16,6 +16,7 @@ import { Event } from "../events";
import { IConfig } from "../config";
import { MonitorState } from "./monitorState";
import { IStream } from "./stream";
import sharp from "sharp";
const { Canvas, Image, ImageData } = canvas;
const defaultWatchDog = 30000;
@ -143,20 +144,36 @@ export class Monitor {
this._config.watchdogTimeout ?? 30000
);
const regularizedImgData = await sharp(args.data)
.modulate({ brightness: 3 })
.sharpen()
.toBuffer();
//Detect faces in image
const input = ((await canvas.loadImage(args.data)) as unknown) as ImageData;
const input = ((await canvas.loadImage(
regularizedImgData
)) as unknown) as ImageData;
const out = faceapi.createCanvasFromMedia(input);
const resultsQuery = await faceapi
.detectAllFaces(out, getFaceDetectorOptions(this._faceDetectionNet))
.detectAllFaces(
out,
getFaceDetectorOptions(this._faceDetectionNet, {
confidence: this._config.confidence,
})
)
.withFaceLandmarks()
.withFaceDescriptors();
//Write to output image
if (this._config.writeOutput) {
await saveFile(this._config.outputDirectory, room + ".jpg", args.data);
await saveFile(
this._config.outputDirectory,
room + ".jpg",
regularizedImgData
);
}
for (const res of resultsQuery) {
const bestMatch = this._matcher.matchDescriptor(res.descriptor);
const bestMatch = this._matcher.findBestMatch(res.descriptor);
const old = this._state[bestMatch.label];
this._state[bestMatch.label] = room;
this._stateChangedEvent.fire(this, {
@ -165,9 +182,13 @@ export class Monitor {
label: bestMatch.label,
});
if (this._config.debug) {
this._logger.info(`Face Detected: ${bestMatch.label} in room ${room}`);
}
this._logger.info(
`Face Detected with ${
res.detection.score * 100
}% accuracy and a distance of ${bestMatch.distance}: ${
bestMatch.label
} in room ${room}`
);
}
};

View File

@ -78,6 +78,7 @@ export class Rtsp {
const argStrings = [
`-rtsp_transport tcp`,
`-i ${this._connecteionString}`,
`-qscale:v 1`,
`-r ${this._options.rate ?? 10}`,
`-vf mpdecimate,setpts=N/FRAME_RATE/TB`,
this._options.image

View File

@ -12,7 +12,11 @@ const { Canvas, Image, ImageData } = canvas;
faceapi.env.monkeyPatch({ Canvas, Image, ImageData });
export class Trainer {
constructor(private _refImageDir: string, private _trainedModelDir: string) {}
constructor(
private _refImageDir: string,
private _trainedModelDir: string,
private _confidence?: number
) {}
public async train(writeToDisk: boolean): Promise<faceapi.FaceMatcher> {
const faceDetectionNet = faceapi.nets.ssdMobilenetv1;
@ -24,18 +28,25 @@ export class Trainer {
path.join(__dirname, "../weights")
);
const options = getFaceDetectorOptions(faceDetectionNet);
const options = getFaceDetectorOptions(faceDetectionNet, {
confidence: this._confidence,
});
const dirs = fs.readdirSync(this._refImageDir);
const refs = [];
for (const dir of dirs) {
const descriptor = new LabeledFaceDescriptors(dir, []);
await this.getLabeledFaceDescriptorFromDir(
path.join(this._refImageDir, dir),
descriptor,
options
);
try {
await this.getLabeledFaceDescriptorFromDir(
path.join(this._refImageDir, dir),
descriptor,
options
);
} catch (err) {
console.log(err);
}
if (descriptor) {
refs.push(descriptor);
}
@ -93,8 +104,11 @@ export class Trainer {
labeldFaceDescriptors.descriptors.push(descriptor.descriptor);
} catch (err) {
throw new Error(
"An error occurred loading image at path: " + path.join(dir, file)
console.log(
"An error occurred loading image at " +
path.join(dir, file) +
": " +
err.message
);
}
})