8000 person detection · eloquentarduino/EloquentTinyML@62addfe · GitHub
[go: up one dir, main page]

Skip to content

Commit 62addfe

Browse files
person detection
1 parent 61bc8ff commit 62addfe

File tree

5 files changed

+25252
-36
lines changed

5 files changed

+25252
-36
lines changed

library.json

Lines changed: 0 additions & 16 deletions
This file was deleted.

src/eloquent_tinyml/.DS_Store

-6 KB
Binary file not shown.

src/eloquent_tinyml/tf.h

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,17 @@ namespace Eloquent {
8484
numInputs = TF_NUM_INPUTS;
8585
#endif
8686

87-
#ifdef TF_NUM_INPUTS
87+
#ifdef TF_NUM_OUTPUTS
8888
if (!numOutputs)
8989
numOutputs = TF_NUM_OUTPUTS;
9090
#endif
9191

92+
if (!numInputs)
93+
return exception.set("You must set the number of inputs");
94+
95+
if (!numOutputs)
96+
return exception.set("You must set the number of outputs");
97+
9298
#ifdef TF_OP_ADD
9399
resolver.AddAdd();
94100
#endif
@@ -132,12 +138,6 @@ namespace Eloquent {
132138
resolver.AddSoftmax();
133139
#endif
134140

135-
if (!numInputs)
136-
return exception.set("You must set the number of inputs");
137-
138-
if (!numOutputs)
139-
return exception.set("You must set the number of outputs");
140-
141141
model = tflite::GetModel(data);
142142

143143
if (model->version() != TFLITE_SCHEMA_VERSION)
@@ -151,37 +151,55 @@ namespace Eloquent {
151151
in = interpreter->input(0);
152152
out = interpreter->output(0);
153153

154+
// allocate outputs
155+
outputs = (float*) calloc(numOutputs, sizeof(float));
156+
154157
return exception.clear();
155158
}
156159

157160
/**
158161
*
159162
*/
160-
template<typename T>
161-
Exception& predict(T *x) {
162-
// quantize
163-
const float inputScale = in->params.scale;
164-
const float inputOffset = in->params.zero_point;
165-
163+
Exception& predict(float *x) {
166164
for (uint16_t i = 0; i < numInputs; i++)
167165
in->data.f[i] = x[i];
168166

169-
// execute
170167
benchmark.start();
171168

172169
if (interpreter->Invoke() != kTfLiteOk)
173170
return exception.set("Invoke() failed");
174171

175-
// allocate outputs
176-
if (outputs == NULL)
177-
outputs = (float*) calloc(numOutputs, sizeof(float));
172+
for (uint16_t i = 0; i < numOutputs; i++) {
173+
outputs[i] = out->data.f[i];
174+
}
175+
176+
getClassificationResult();
177+
benchmark.stop();
178178

179-
// dequantize
179+
return exception.clear();
180+
}
181+
182+
/**
183+
*
184+
*/
185+
Exception& predict(int8_t *x) {
186+
// quantization
187+
const float inputScale = in->params.scale;
188+
const float inputOffset = in->params.zero_point;
180189
const float outputScale = out->params.scale;
181190
const float outputOffset = out->params.zero_point;
182191

183-
for (uint16_t i = 0; i < numOutputs; i++)
184-
outputs[i] = out->data.f[i];
192+
memcpy(in->data.int8, x, sizeof(int8_t) * numInputs);
193+
194+
// execute
195+
benchmark.start();
196+
197+
if (interpreter->Invoke() != kTfLiteOk)
198+
return exception.set("Invoke() failed");
199+
200+
for (uint16_t i = 0; i < numOutputs; i++) {
201+
outputs[i] = out->data.int8[i];
202+
}
185203

186204
getClassificationResult();
187205
benchmark.stop();
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#ifndef ELOQUENTTINYML_ZOO_PERSON_DETECTION_H
2+
#define ELOQUENTTINYML_ZOO_PERSON_DETECTION_H
3+
4+
#ifndef PERSON_DETECTION_ARENA_SIZE
5+
#define PERSON_DETECTION_ARENA_SIZE 90000L
6+
#endif
7+
8+
#include "../tf.h"
9+
#include "../exception.h"
10+
#include "../benchmark.h"
11+
#include "./person_detection_model.h"
12+
13+
using Eloquent::TF::Sequential;
14+
using Eloquent::Error::Exception;
15+
16+
17+
namespace Eloquent {
18+
namespace TinyML {
19+
namespace Zoo {
20+
/**
21+
* Run person detection on 96x96 grayscale image
22+
*/
23+
class PersonDetection {
24+
public:
25+
Sequential<5, PERSON_DETECTION_ARENA_SIZE> tf;
26+
Exception exception;
27+
28+
/**
29+
* Constructor
30+
*/
31+
PersonDetection() :
32+
exception("PersonDetection"),
33+
_thresh(180) {
34+
35+
}
36+
37+
/**
38+
* Test if a person is detected
39+
*/
40+
operator bool() {
41+
if (exception || tf.exception)
42+
return false;
43+
44+
const uint8_t pos = personScore();
45+
const uint8_t neg = notPersonScore();
46+
47+
return pos > neg && pos >= _thresh;
48+
}
49+
50+
/**
51+
* Init model
52+
* @return
53+
*/
54+
Exception& begin() {
55+
tf.setNumInputs(96 * 96);
56+
tf.setNumOutputs(3);
57+
tf.resolver.AddDepthwiseConv2D();
58+
tf.resolver.AddConv2D();
59+
tf.resolver.AddAveragePool2D();
60+
tf.resolver.AddReshape();
61+
tf.resolver.AddSoftmax();
62+
63+
if (!tf.begin(eloq::tinyml::zoo::personDetectionModel).isOk())
64+
return tf.exception;
65+
66+
return exception.clear();
67+
}
68+
69+
/**
70+
* Run detection on frame
71+
* @param image
72+
* @return
73+
*/
74+
Exception& run(uint8_t *image) {
75+
for (int i = 0; i < 96 * 96; i++)
76+
_buffer[i] = ((int16_t) image[i]) - 128;
77+
78+
if (!tf.predict(_buffer).isOk())
79+
return tf.exception;
80+
81+
return exception.clear();
82+
}
83+
84+
/**
85+
* Run detection on camera
86+
* @param camera
87+
* @return
88+
*/
89+
template<typename Camera>
90+
Exception& run(Camera& camera) {
91+
return run(camera.frame->buf);
92+
}
93+
94+
/**
95+
*
96+
* @return
97+
*/
98+
uint8_t personScore() {
99+
return 128 + tf.output(1);
100+
}
101+
102+
/**
103+
*
104+
* @return
105+
*/
106+
uint8_t notPersonScore() {
107+
return 128 + tf.output(2);
108+
}
109+
110+
protected:
111+
uint8_t _thresh;
112+
int8_t _buffer[96 * 96];
113+
};
114+
}
115+
}
116+
}
117+
118+
namespace eloq {
119+
namespace tinyml {
120+
namespace zoo {
121+
static Eloquent::TinyML::Zoo::PersonDetection personDetection;
122+
}
123+
}
124+
}
125+
126+
#endif //ELOQUENTTINYML_ZOO_PERSON_DETECTION_H

0 commit comments

Comments
 (0)
0