-
Notifications
You must be signed in to change notification settings - Fork 11
/
facetracker.js
125 lines (124 loc) · 3.67 KB
/
facetracker.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import React, { Component } from "react";
import { RNVisionProvider, RNVisionConsumer } from "./wrapper";
import PropTypes from "prop-types";
const intersect = (a, b) => {
if (!a && !b) return false;
return !(
b.x > a.x + a.width ||
a.x > b.x + b.width ||
b.y > a.y + a.height ||
a.y > b.y + b.height
);
};
class FaceTracker extends Component {
state = {
interval: null,
intervalDuration: 0,
onDetectedFaces: null,
regions: null
};
static getDerivedStateFromProps(nextProps, prevState) {
var ret = prevState;
if (
nextProps.interval &&
nextProps.interval != prevState.intervalDuration
) {
ret.intervalDuration = nextProps.interval;
}
return ret;
}
updateInterval() {
clearInterval(this.state.interval);
this.setState({
interval: setInterval(() => {
this.setState({
onDetectedFaces: faces => {
var out = {};
var doneIndexes = [];
if (faces && faces.length) {
if (this.state.regions) {
faces.forEach((v, i) => {
var done = false;
const newRect = {
x: v.x - v.width * 0.1,
y: v.y - v.height * 0.2,
height: v.height * 1.4,
width: v.width * 1.2
};
Object.keys(this.state.regions).forEach(region => {
if (done) return;
if (region == "") return;
const rect = this.state.regions[region];
if (intersect(newRect, rect)) {
out[region] = newRect;
doneIndexes.push(i);
done = true;
}
});
});
}
faces.forEach((v, i) => {
if (doneIndexes.indexOf(i) > -1) return;
var i = 0;
var key;
do {
key = "face" + String(i);
i++;
} while (Object.keys(out).indexOf(key) > -1);
const newRect = {
x: v.x - v.width * 0.1,
y: v.y - v.height * 0.2,
height: v.height * 1.4,
width: v.width * 1.2
};
out[key] = newRect;
});
this.setState({ trackedObjects: out, onDetectedFaces: null });
} else {
this.setState({ trackedObjects: null, onDetectedFaces: null });
}
}
});
}, this.state.intervalDuration)
});
}
componentDidUpdate(prevProps, prevState) {
if (prevState.intervalDuration != prevState.intervalDuration) {
this.updateInterval();
}
}
componentDidMount() {
this.updateInterval();
}
componentWillUnmount() {
if (this.state.interval) clearInterval(this.state.interval);
}
render() {
return (
<RNVisionProvider
{...this.props}
onDetectedFaces={this.state.onDetectedFaces}
trackedObjects={{
...this.props.trackedObjects,
...this.state.trackedObjects
}}
onRegionsChanged={regions => {
this.setState({ regions: regions });
if (this.props.onRegionsChange) this.props.onRegionsChange(regions);
}}
children={
typeof this.props.children == "function" ? (
<RNVisionConsumer>{this.props.children}</RNVisionConsumer>
) : (
this.props.children
)
}
/>
);
}
}
FaceTracker.propTypes = {
...RNVisionProvider.propTypes,
interval: PropTypes.number.isRequired
};
export default FaceTracker;