Skip to content

Commit

Permalink
SDK release 1.47.0
Browse files Browse the repository at this point in the history
  • Loading branch information
francovaro committed Mar 8, 2024
1 parent 5212573 commit 2ec61a0
Show file tree
Hide file tree
Showing 17 changed files with 825 additions and 475 deletions.
12 changes: 9 additions & 3 deletions EdgeImpulse.EI-SDK.pdsc
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
<name>EI-SDK</name>
<license>LICENSE-apache-2.0.txt</license>
<description>Edge Impulse SDK</description>
<url>https://github.com/edgeimpulse/edge-impulse-sdk-pack/releases/download/v1.46.6/</url>
<url>https://github.com/edgeimpulse/edge-impulse-sdk-pack/releases/download/v1.47.0/</url>
<supportContact>[email protected]</supportContact>
<repository type="git">https://github.com/edgeimpulse/edge-impulse-sdk-pack.git</repository>
<releases>
<release version="1.46.6" tag="v1.46.6" date="2024-03-06" url="https://github.com/edgeimpulse/edge-impulse-sdk-pack/releases/download/v1.46.6/EdgeImpulse.EI-SDK.1.46.6.pack">
<release version="1.47.0" tag="v1.47.0" date="2024-03-08" url="https://github.com/edgeimpulse/edge-impulse-sdk-pack/releases/download/v1.47.0/EdgeImpulse.EI-SDK.1.47.0.pack">
EI-SDK
</release>
<release version="1.46.6" tag="v1.46.6" date="2024-03-06" url="https://github.com/edgeimpulse/edge-impulse-sdk-pack/releases/download/v1.46.6/EdgeImpulse.EI-SDK.1.46.6.pack">
EI-SDK
</release>
<release version="1.46.4" tag="v1.46.4" date="2024-03-05" url="https://github.com/edgeimpulse/edge-impulse-sdk-pack/releases/download/v1.46.4/EdgeImpulse.EI-SDK.1.46.4.pack">
EI-SDK
</release>
Expand Down Expand Up @@ -77,7 +80,7 @@
</packages>
</requirements>
<components>
<component Cclass="EdgeImpulse" Cgroup="SDK" Cversion="1.46.6">
<component Cclass="EdgeImpulse" Cgroup="SDK" Cversion="1.47.0">
<description>Edge Impulse SDK</description>
<!-- short component description -->
<files>
Expand Down Expand Up @@ -535,11 +538,14 @@
<file category="header" name="edgeimpulse/edge-impulse-sdk/tensorflow/lite/c/c_api_types.h"/>
<file category="header" name="edgeimpulse/edge-impulse-sdk/tensorflow/lite/c/builtin_op_data.h"/>
<file category="header" name="edgeimpulse/edge-impulse-sdk/tensorflow/lite/c/common.h"/>
<file category="header" name="edgeimpulse/edge-impulse-sdk/dsp/ei_flatten.h"/>
<file category="header" name="edgeimpulse/edge-impulse-sdk/dsp/ei_dsp_handle.h"/>
<file category="header" name="edgeimpulse/edge-impulse-sdk/dsp/numpy_types.h"/>
<file category="header" name="edgeimpulse/edge-impulse-sdk/dsp/ei_profiler.h"/>
<file category="header" name="edgeimpulse/edge-impulse-sdk/dsp/ei_utils.h"/>
<file category="header" name="edgeimpulse/edge-impulse-sdk/dsp/ei_alloc.h"/>
<file category="header" name="edgeimpulse/edge-impulse-sdk/dsp/ei_vector.h"/>
<file category="header" name="edgeimpulse/edge-impulse-sdk/dsp/returntypes.h"/>
<file category="header" name="edgeimpulse/edge-impulse-sdk/dsp/kissfft/_kiss_fft_guts.h"/>
<file category="header" name="edgeimpulse/edge-impulse-sdk/dsp/kissfft/kiss_fft.h"/>
<file category="header" name="edgeimpulse/edge-impulse-sdk/dsp/kissfft/kissfft.h"/>
Expand Down
4 changes: 2 additions & 2 deletions EdgeImpulse.pidx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<index schemaVersion="1.0.0" xs:noNamespaceSchemaLocation="PackIndex.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
<vendor>EdgeImpulse</vendor>
<url>https://raw.githubusercontent.com/edgeimpulse/edge-impulse-sdk-pack/main/</url>
<timestamp>2024-03-06 17:40:41</timestamp>
<timestamp>2024-03-08 09:13:21</timestamp>
<pindex>
<pdsc url="https://github.com/edgeimpulse/edge-impulse-sdk-pack/releases/download/v1.46.6/" vendor="EdgeImpulse" name="EI-SDK" version="1.46.6"/>
<pdsc url="https://github.com/edgeimpulse/edge-impulse-sdk-pack/releases/download/v1.47.0/" vendor="EdgeImpulse" name="EI-SDK" version="1.47.0"/>
</pindex>
</index>
499 changes: 253 additions & 246 deletions edgeimpulse/edge-impulse-sdk/classifier/ei_fill_result_struct.h

Large diffs are not rendered by default.

68 changes: 68 additions & 0 deletions edgeimpulse/edge-impulse-sdk/classifier/ei_model_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <stdint.h>

#include "edge-impulse-sdk/classifier/ei_classifier_types.h"
#include "edge-impulse-sdk/dsp/ei_dsp_handle.h"
#include "edge-impulse-sdk/dsp/numpy.hpp"
#if EI_CLASSIFIER_USE_FULL_TFLITE || (EI_CLASSIFIER_INFERENCING_ENGINE == EI_CLASSIFIER_AKIDA) || (EI_CLASSIFIER_INFERENCING_ENGINE == EI_CLASSIFIER_MEMRYX)
#include "tensorflow-lite/tensorflow/lite/c/common.h"
Expand Down Expand Up @@ -104,6 +105,9 @@ typedef struct {
void *config;
uint8_t *axes;
size_t axes_size;
int version; // future proof, can easily add to this struct now
DspHandle* (*factory)(void* config); // nullptr means no state
// v1 ends here
} ei_model_dsp_t;

typedef struct {
Expand Down Expand Up @@ -242,6 +246,70 @@ typedef struct ei_impulse {
ei_object_detection_nms_config_t object_detection_nms;
} ei_impulse_t;

class ei_impulse_state_t {
typedef DspHandle* _dsp_handle_ptr_t;
public:
const ei_impulse_t *impulse; // keep a pointer to the impulse
_dsp_handle_ptr_t *dsp_handles;
bool is_temp_handle = false; // to know if we're using the old (stateless) API
ei_impulse_state_t(const ei_impulse_t *impulse)
: impulse(impulse)
{
const auto num_dsp_blocks = impulse->dsp_blocks_size;
dsp_handles = (_dsp_handle_ptr_t*)ei_malloc(sizeof(_dsp_handle_ptr_t)*num_dsp_blocks);
for(size_t ix = 0; ix < num_dsp_blocks; ix++) {
dsp_handles[ix] = nullptr;
}
}

DspHandle* get_dsp_handle(size_t ix) {
if (dsp_handles[ix] == nullptr) {
dsp_handles[ix] = impulse->dsp_blocks[ix].factory(impulse->dsp_blocks[ix].config);
}
return dsp_handles[ix];
}

void reset()
{
for (size_t ix = 0; ix < impulse->dsp_blocks_size; ix++) {
if (dsp_handles[ix] != nullptr) {
delete dsp_handles[ix];
dsp_handles[ix] = nullptr;
}
}
}

void* operator new(size_t size) {
return ei_malloc(size);
}

void operator delete(void* ptr) {
ei_free(ptr);
}

void* operator new[](size_t size) {
return ei_malloc(size);
}

void operator delete[](void* ptr) {
ei_free(ptr);
}

~ei_impulse_state_t()
{
reset();
ei_free(dsp_handles);
}
};

class ei_impulse_handle_t {
public:
ei_impulse_handle_t(const ei_impulse_t *impulse)
: state(impulse), impulse(impulse) {};
ei_impulse_state_t state;
const ei_impulse_t *impulse;
};

typedef struct {
uint32_t block_id;
uint16_t implementation_version;
Expand Down
134 changes: 91 additions & 43 deletions edgeimpulse/edge-impulse-sdk/classifier/ei_nms.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ static inline void NonMaxSuppression(const float* boxes, const int num_boxes,
}
++*num_selected_indices;
}
if (next_candidate.score > score_threshold) {
if ((soft_nms_sigma > 0.0) && (next_candidate.score > score_threshold)) {
// Soft suppression might have occurred and current score is still
// greater than score_threshold; add next_candidate back onto priority
// queue.
Expand All @@ -205,45 +205,22 @@ static inline void NonMaxSuppression(const float* boxes, const int num_boxes,
*/
EI_IMPULSE_ERROR ei_run_nms(
const ei_impulse_t *impulse,
std::vector<ei_impulse_result_bounding_box_t> *results) {
std::vector<ei_impulse_result_bounding_box_t> *results,
float *boxes,
float *scores,
int *classes,
size_t bb_count,
bool clip_boxes) {

size_t bb_count = 0;
for (size_t ix = 0; ix < results->size(); ix++) {
auto bb = results->at(ix);
if (bb.value == 0) {
continue;
}
bb_count++;
}

float *boxes = (float*)ei_malloc(4 * bb_count * sizeof(float));
float *scores = (float*)ei_malloc(1 * bb_count * sizeof(float));
int *selected_indices = (int*)ei_malloc(1 * bb_count * sizeof(int));
float *selected_scores = (float*)ei_malloc(1 * bb_count * sizeof(float));

if (!scores || !boxes || !selected_indices || !selected_scores) {
ei_free(boxes);
ei_free(scores);
if (!scores || !boxes || !selected_indices || !selected_scores || !classes) {
ei_free(selected_indices);
ei_free(selected_scores);
return EI_IMPULSE_OUT_OF_MEMORY;
}

size_t box_ix = 0;
for (size_t ix = 0; ix < results->size(); ix++) {
auto bb = results->at(ix);
if (bb.value == 0) {
continue;
}
boxes[(box_ix * 4) + 0] = bb.y;
boxes[(box_ix * 4) + 1] = bb.x;
boxes[(box_ix * 4) + 2] = bb.y + bb.height;
boxes[(box_ix * 4) + 3] = bb.x + bb.width;
scores[box_ix] = bb.value;

box_ix++;
}

// boxes: box encodings in format [y1, x1, y2, x2], shape: [num_boxes, 4]
// num_boxes: number of candidates
// scores: scores for candidate boxes, in the same order. shape: [num_boxes]
Expand All @@ -269,17 +246,29 @@ EI_IMPULSE_ERROR ei_run_nms(
std::vector<ei_impulse_result_bounding_box_t> new_results;

for (size_t ix = 0; ix < (size_t)num_selected_indices; ix++) {
auto bb = results->at(selected_indices[ix]);

ei_printf("Found bb with label %s\n", bb.label);
// ei_printf("Found bb with label %s\n", bb.label);

int out_ix = selected_indices[ix];
ei_impulse_result_bounding_box_t r;
r.label = bb.label;
r.x = bb.x;
r.y = bb.y;
r.width = bb.width;
r.height = bb.height;
r.value = selected_scores[ix];
r.label = impulse->categories[classes[out_ix]];
r.value = selected_scores[ix];

float ymin = boxes[(out_ix * 4) + 0];
float xmin = boxes[(out_ix * 4) + 1];
float ymax = boxes[(out_ix * 4) + 2];
float xmax = boxes[(out_ix * 4) + 3];

if (clip_boxes) {
ymin = std::min(std::max(ymin, 0.0f), (float)impulse->input_height);
xmin = std::min(std::max(xmin, 0.0f), (float)impulse->input_width);
ymax = std::min(std::max(ymax, 0.0f), (float)impulse->input_height);
xmax = std::min(std::max(xmax, 0.0f), (float)impulse->input_width);
}

r.y = static_cast<uint32_t>(ymin);
r.x = static_cast<uint32_t>(xmin);
r.height = static_cast<uint32_t>(ymax) - r.y;
r.width = static_cast<uint32_t>(xmax) - r.x;
new_results.push_back(r);
}

Expand All @@ -289,21 +278,80 @@ EI_IMPULSE_ERROR ei_run_nms(
results->push_back(new_results[ix]);
}

ei_free(boxes);
ei_free(scores);
ei_free(selected_indices);
ei_free(selected_scores);

return EI_IMPULSE_OK;

}

/**
* Run non-max suppression over the results array (for bounding boxes)
*/
EI_IMPULSE_ERROR ei_run_nms(
const ei_impulse_t *impulse,
std::vector<ei_impulse_result_bounding_box_t> *results) {

size_t bb_count = 0;
for (size_t ix = 0; ix < results->size(); ix++) {
auto bb = results->at(ix);
if (bb.value == 0) {
continue;
}
bb_count++;
}

float *boxes = (float*)ei_malloc(4 * bb_count * sizeof(float));
float *scores = (float*)ei_malloc(1 * bb_count * sizeof(float));
int *classes = (int*) ei_malloc(bb_count * sizeof(int));

if (!scores || !boxes || !classes) {
ei_free(boxes);
ei_free(scores);
ei_free(classes);
return EI_IMPULSE_OUT_OF_MEMORY;
}

size_t box_ix = 0;
for (size_t ix = 0; ix < results->size(); ix++) {
auto bb = results->at(ix);
if (bb.value == 0) {
continue;
}
boxes[(box_ix * 4) + 0] = bb.y;
boxes[(box_ix * 4) + 1] = bb.x;
boxes[(box_ix * 4) + 2] = bb.y + bb.height;
boxes[(box_ix * 4) + 3] = bb.x + bb.width;
scores[box_ix] = bb.value;

for (size_t j = 0; j < impulse->label_count; j++) {
if (strcmp(impulse->categories[j], bb.label) == 0)
classes[box_ix] = j;
}

box_ix++;
}

EI_IMPULSE_ERROR nms_res = ei_run_nms(impulse, results,
boxes, scores,
classes, bb_count,
true /*clip_boxes*/);


ei_free(boxes);
ei_free(scores);
ei_free(classes);

return nms_res;

}

/**
* Run non-max suppression over the results array (for bounding boxes)
*/
EI_IMPULSE_ERROR ei_run_nms(std::vector<ei_impulse_result_bounding_box_t> *results) {
#if EI_CLASSIFIER_HAS_MODEL_VARIABLES == 1
const ei_impulse_t impulse = ei_default_impulse;
auto& impulse = *ei_default_impulse.impulse;
#else
const ei_impulse_t impulse = {
.object_detection_nms.confidence_threshold = 0.0f,
Expand Down
Loading

0 comments on commit 2ec61a0

Please sign in to comment.