Skip to content

Commit

Permalink
major refactoring of classes and layout
Browse files Browse the repository at this point in the history
  • Loading branch information
eloquentarduino committed Nov 10, 2021
1 parent 5fb8f3f commit a7b44b6
Show file tree
Hide file tree
Showing 512 changed files with 24,009 additions and 1,784 deletions.
66 changes: 46 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ interface to load a model and run inferences.

## Install

Clone this repo in you Arduino libraries folder.
EloquentTinyML is available from the Arduino IDE Library Manager or
you can clone this repo in you Arduino libraries folder.

```bash
git clone https://github.com/eloquentarduino/EloquentTinyML.git
```

**Be sure you install version 2.4.0 or newer.**

## Export TensorFlow Lite model

To run a model on your microcontroller, you should first have a model.
Expand All @@ -22,42 +25,65 @@ I suggest you use [`tinymlgen`](https://github.com/eloquentarduino/tinymlgen) to
it will export your TensorFlow Lite model to a C array ready to be loaded
by this library.

```python
from tinymlgen import port


tf_model = create_tf_network()
print(port(tf_model))
```


## Use

```cpp
#include <EloquentTinyML.h>
#include <eloquent_tinyml/tensorflow.h>

// sine_model.h contains the array you exported from Python with xxd or tinymlgen
#include "sine_model.h"

#define NUMBER_OF_INPUTS 1
#define NUMBER_OF_OUTPUTS 1
#define N_INPUTS 1
#define N_OUTPUTS 1
// in future projects you may need to tweak this value: it's a trial and error process
#define TENSOR_ARENA_SIZE 2*1024

Eloquent::TinyML::TfLite<
NUMBER_OF_INPUTS,
NUMBER_OF_OUTPUTS,
TENSOR_ARENA_SIZE> ml;
Eloquent::TinyML::TensorFlow::TensorFlow<N_INPUTS, N_OUTPUTS, TENSOR_ARENA_SIZE> tf;


void setup() {
Serial.begin(115200);
ml.begin(sine_model);
delay(4000);
tf.begin(sine_model);

// check if model loaded fine
if (!tf.isOk()) {
Serial.print("ERROR: ");
Serial.println(tf.getErrorMessage());

while (true) delay(1000);
}
}

void loop() {
float x = 3.14 * random(100) / 100;
float y = sin(x);
float input[1] = { x };
float predicted = ml.predict(input);

Serial.print("sin(");
Serial.print(x);
Serial.print(") = ");
Serial.print(y);
Serial.print("\t predicted: ");
Serial.println(predicted);
delay(1000);
for (float i = 0; i < 10; i++) {
// pick x from 0 to PI
float x = 3.14 * i / 10;
float y = sin(x);
float input[1] = { x };
float predicted = tf.predict(input);
Serial.print("sin(");
Serial.print(x);
Serial.print(") = ");
Serial.print(y);
Serial.print("\t predicted: ");
Serial.println(predicted);
}

delay(10000);
}

```

## Compatibility
Expand Down
24 changes: 24 additions & 0 deletions examples/2.4/PersonDetection/ESP32Camera.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#define CAMERA_MODEL_M5STACK_WIDE
#include <EloquentVision.h>

Eloquent::Vision::ESP32Camera camera;
camera_fb_t *frame;



/**
* Configure camera
*/
void initCamera() {
camera.begin(FRAMESIZE_QVGA, PIXFORMAT_GRAYSCALE, 20000000);
}


/**
* Capture frame from ESP32 camera
*/
uint8_t* captureFrame() {
frame = camera.capture();

return frame->buf;
}
60 changes: 60 additions & 0 deletions examples/2.4/PersonDetection/PersonDetection.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include <EloquentTinyML.h>
#include <eloquent_tinyml/tensorflow/person_detection.h>

#if defined(ESP32)
#include "ESP32Camera.h"
#else
#include "PortentaVision.h"
#endif

const uint16_t imageWidth = 320;
const uint16_t imageHeight = 240;


Eloquent::TinyML::TensorFlow::PersonDetection<imageWidth, imageHeight> detector;


void setup() {
Serial.begin(115200);
delay(5000);
initCamera();

// configure a threshold for "robust" person detection
// if no threshold is set, "person" would be detected everytime person_score > not_person_score
// even if just by 1
// by trial and error, considering that scores range from 0 to 255, a threshold of 190-200
// dramatically reduces the number of false positives
detector.setDetectionAbsoluteThreshold(190);
detector.begin();

// abort if an error occurred
if (!detector.isOk()) {
Serial.print("Setup error: ");
Serial.println(detector.getErrorMessage());

while (true) delay(1000);
}
}

void loop() {
uint8_t *frame = captureFrame();
bool isPersonInFrame = detector.detectPerson(frame);

if (!detector.isOk()) {
Serial.print("Loop error: ");
Serial.println(detector.getErrorMessage());

delay(10000);
return;
}

Serial.print(isPersonInFrame ? "Person detected" : "No person detected");
Serial.print(" (it took ");
Serial.print(detector.getElapsedTime());
Serial.println("ms to detect)");
Serial.print("\t > Person score: ");
Serial.println(detector.getPersonScore());
Serial.print("\t > Not person score: ");
Serial.println(detector.getNotPersonScore());
delay(1000);
}
22 changes: 22 additions & 0 deletions examples/2.4/PersonDetection/PortentaVision.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "camera.h"

CameraClass cam;
uint8_t frame[320*240];


/**
* Configure camera
*/
void initCamera() {
cam.begin(CAMERA_R320x240, 30);
}


/**
* Capture frame from Vision shield
*/
uint8_t* captureFrame() {
cam.grab(frame);

return frame;
}
46 changes: 46 additions & 0 deletions examples/2.4/SineExample/SineExample.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include <EloquentTinyML.h>
#include <eloquent_tinyml/tensorflow.h>

// sine_model.h contains the array you exported from Python with xxd or tinymlgen
#include "sine_model.h"

#define N_INPUTS 1
#define N_OUTPUTS 1
// in future projects you may need to tweak this value: it's a trial and error process
#define TENSOR_ARENA_SIZE 2*1024

Eloquent::TinyML::TensorFlow::TensorFlow<N_INPUTS, N_OUTPUTS, TENSOR_ARENA_SIZE> tf;


void setup() {
Serial.begin(115200);
delay(4000);
tf.begin(sine_model);

// check if model loaded fine
if (!tf.isOk()) {
Serial.print("ERROR: ");
Serial.println(tf.getErrorMessage());

while (true) delay(1000);
}
}

void loop() {
for (float i = 0; i < 10; i++) {
// pick x from 0 to PI
float x = 3.14 * i / 10;
float y = sin(x);
float input[1] = { x };
float predicted = tf.predict(input);

Serial.print("sin(");
Serial.print(x);
Serial.print(") = ");
Serial.print(y);
Serial.print("\t predicted: ");
Serial.println(predicted);
}

delay(1000);
}
Loading

0 comments on commit a7b44b6

Please sign in to comment.