ESP32 CAM Support

@tcontrada After you’ve managed to get it working based on @aurel’s comments the prefered way of getting data in is by implementing the signal.get_data callback:

int raw_feature_get_data(size_t offset, size_t length, float *out_ptr) {
    // Here read `length` bytes from offset `offset` from the camera's *frame buffer*
    // then copy into `out_ptr` in the format from Studio 
    // (1 pixel per value like 0xFF0000 for red)
    return 0;
}

signal_t features_signal;
features_signal.total_length = EI_CLASSIFIER_INPUT_WIDTH * EI_CLASSIFIER_INPUT_HEIGHT;
features_signal.get_data = &raw_feature_get_data;

This way you don’t allocate another large buffer, but can stream straight from frame buffer => neural network.

2 Likes

Well, call me stupid, but I am not able to understand what you want me to do!
Can you be more specific?

Thanks…

In the Arduino sketch, you have the following array assignment:

static const float features[] = { ... }

It needs to be filled with the pixels from the image you want to classify. First step is just to make sure it works, by pasting an image example directly from your Edge Impulse project. Then you can use the ESP32Cam method to capture a frame (probably with esp_camera_fb_get() but I’m not familiar with this target).

Aurelien

1 Like

I filled the array with a random example from my project.
I get the following debug output:

ets Jun 8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:9720
ho 0 tail 12 room 4
load:0x40080400,len:6352
entry 0x400806b8
Edge Impulse Inferencing Demo
Edge Impulse standalone inferencing (Arduino)
Guru Meditation Error: Core 1⸮ets Jun 8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:9720
ho 0 tail 12 room 4
load:0x40080400,len:6352
entry 0x400806b8
Edge Impulse Inferencing Demo
Edge Impulse standalone inferencing (Arduino)
Guru Meditation Error: Core 1 panic’ed (StoreProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x400ec2b2 PS : 0x00060730 A0 : 0x800ee1cd A1 : 0x3ffb1e10
A2 : 0x3ffc647c A3 : 0x00000040 A4 : 0x00045810 A5 : 0x00000001
A6 : 0x00000040 A7 : 0x400ec254 A8 : 0x00044f98 A9 : 0x00037230
A10 : 0x00000002 A11 : 0x00000002 A12 : 0x00000008 A13 : 0x3ffb1e64
A14 : 0x00000004 A15 : 0x00000002 SAR : 0x0000000a EXCCAUSE: 0x0000001d
EXCVADDR: 0x00045810 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0xffffffff

Backtrace: 0x400ec2b2:0x3ffb1e10 0x400ee1ca:0x3ffb1e30 0x400ec14d:0x3ffb1e90 0x400eb925:0x3ffb1ec0 0x400ebbfe:0x3ffb1f00 0x400ebe81:0x3ffb1f50 0x400e6931:0x3ffb1fb0 0x4008a53d:0x3ffb1fd0

1 Like

It looks like the program tries to access some prohibited memory space but you’ll need to decode the backtrace to understand where the issue comes from. This plugin seems to do the work: https://github.com/me-no-dev/EspExceptionDecoder

Also what is the RAM and Flash capacity on your board?

Aurelien

1 Like

I’ve ordered an ESP32-CAM board to try this out - hopefully that will work faster.

1 Like

In the configuration for Huge app on the ESP32 CAM, max flash is 3145728, max ram is 327680
Is this enough to run the application? The CAM board has a micro SD card slot available as well…

Great Idea!!

When you load the ESP32 board files there is a sample application, CameraWebServer, try that out first to make sure everything works.

Thanks!

Oh, you will also nee a USB to Serial adapter, like the FTDI board. Set the voltage switch to 5v.

See this link: https://randomnerdtutorials.com/program-upload-code-esp32-cam/

1 Like

Yeah that should be fine - will check if I have the board in!

1 Like

Hi Any update on the ESP32 CAM?

1 Like

@tcontrada I have the board laying around but haven’t gotten to use it yet. In the meantime we had a few users that have used the ESP32 CAM, incl. here: ESP32WROOM or ESP8266EX Node MCU Support and I’ve written an example to create a signal from a RGB565 frame buffer (which I think the ESP32 CAM uses): https://github.com/edgeimpulse/example-signal-from-rgb565-frame-buffer

1 Like

@janjongboom I just received an ESP32 cam. I’m trying to learn how the data is classified. Does the software support classification of live streaming data or is it just classifying single pictures/frames?

1 Like

Frame-by-frame, I don’t really get how you would do live streaming of the data. The buffer should remain the same until classification is done, then you can read from the camera again.

1 Like

Good point, I didn’t think of that. I lack that basic understanding on how data is read from the camera and how that data is structured which I’m currently researching.

I also read your github. So I need to convert the RGB565 to RGB888 then I can feed it into the static buffer?

@electronictechgreg Yes, just use the example repo to turn the RGB565 frame buffer into a signal_t structure. You then ask the classifier to classify the signal. Then you get predictions, and you can take the next photo!

1 Like

I watched your video on Adding sight to your sensors. When I was talking about streaming what I meant was live classification like you did in the video. So that answered that question for me.

As for the ESP32 cam, apparently I can output in RGB888 format using the fmt2rgb888 function from the esp_camera.h library. Then convert it to a signal_t structure then feed it into the classifier. I think I got it.

1 Like

@janjongboom I apologize if this issue has been resolved and I just could not find a resolution. I uploaded static_buffer sketch to ESP32 Cam board and getting ‘panic’ exception. When I decoded the trace I found this

As per all the suggestion in this thread, I converted feature to RGB888 following your repo. I have tested basic web camera code with this board which is working. So my board and fine. I also uploaded the same sketch to Nano BLE sense and it worked. Just can’t get it working with ESP32 Cam. Here is my code.

  /* Edge Impulse Arduino examples
 * Copyright (c) 2020 EdgeImpulse Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/* Includes ---------------------------------------------------------------- */
#include <animal_faces_inference.h>

#define CUTOUT_COLS                 EI_CLASSIFIER_INPUT_WIDTH
#define CUTOUT_ROWS                 EI_CLASSIFIER_INPUT_HEIGHT
#define FRAME_BUFFER_COLS           48
#define FRAME_BUFFER_ROWS           48
uint16_t frame_buffer[FRAME_BUFFER_COLS * FRAME_BUFFER_ROWS] = { 0 };
const int cutout_row_start = (FRAME_BUFFER_ROWS - CUTOUT_ROWS) / 2;
const int cutout_col_start = (FRAME_BUFFER_COLS - CUTOUT_COLS) / 2;

static const float features[] = {
   0xaf9118, 0xcea714, 0xdbb618, 0xd5b613, 0xcbb10d, 0xd7bc0e, 0xdfc017, 0xdcb924, 0xbea32e, 0xc3af40, 0xcdba5d, 0xc5b467, 0xbcb57c, 0xb4b48f, 0xaaaa81, 0x9ea483, 0x95a491, 0x9db3b4, 0x9eb5bc, 0x96acb0, 0x8f9683, 0x858366, 0x6e6b51, 0x646249, 0x6c6a54, 0x5f5c4b, 0x5c5948, 0x555140, 0x564e3b, 0x655b43, 0x655d43, 0x685e46, 0x6a614a, 0x6b634c, 0x72674d, 0x797052, 0x827756, 0x847a5c, 0x897f63, 0x8c8261, 0x9d9777, 0xa9ada5, 0x9e9f8c, 0x9c9477, 0x9a8f6a, 0x9b8e66, 0x9a8c64, 0x9a8d66, 0xb18e23, 0xd1a320, 0xc6a62b, 0xb09c21, 0xc0a517, 0xd4b80e, 0xceb207, 0xe4c114, 0xe6c01d, 0xdbbc17, 0xdfbf18, 0xdec019, 0xd7b81e, 0xd4b72d, 0xc3a92c, 0xc5a937, 0xb4a143, 0x9d985a, 0x94925d, 0x918a5a, 0x94823a, 0x8f8137, 0x655d36, 0x524e34, 0x524d38, 0x534f3a, 0x545240, 0x444134, 0x464237, 0x4c473a, 0x524c3d, 0x534c3d, 0x595241, 0x5b5542, 0x605844, 0x685e48, 0x71674d, 0x72674f, 0x796d52, 0x7e7255, 0x887d5a, 0x9b9677, 0x928864, 0x8d7f5c, 0x8c7e5d, 0x90835f, 0x968761, 0x93875d, 0xb08d37, 0xa6852f, 0x9a8426, 0x8f7d2c, 0xb89c22, 0xbea216, 0xb0990c, 0xceaf15, 0xe5c01f, 0xd7b70b, 0xdab918, 0xd9b81f, 0xddc017, 0xdabf16, 0xd3b71c, 0xe1c02d, 0xc9ae25, 0xc2a71f, 0xc7a826, 0xbba120, 0xc0a324, 0xaf9625, 0x95812a, 0x8c782c, 0x5d542f, 0x4c4731, 0x554f34, 0x4c4632, 0x4d4935, 0x4a4737, 0x4c4839, 0x4c473b, 0x4f4b3c, 0x544f3f, 0x565140, 0x635c44, 0x6c664b, 0x665e4c, 0x706750, 0x807558, 0x898160, 0x858067, 0x898170, 0x80755e, 0x82765e, 0x84775d, 0x897a5d, 0x8c7a5d, 0xc4a819, 0xceb026, 0xc6aa19, 0xc3a319, 0xcda814, 0xd4b109, 0xcfaf12, 0xbc9d14, 0xc6ac11, 0xbaa50f, 0xcaad0f, 0xd8b50e, 0xdbbc0c, 0xd8bd0c, 0xccb214, 0xd4b718, 0xdabd0f, 0xdbbd10, 0xddbd1e, 0xd6ba18, 0xd7b718, 0xd8b81e, 0xcfb026, 0xd5b02b, 0xc2a224, 0xab9222, 0xa99022, 0xa58b24, 0x998323, 0x927a31, 0x745f36, 0x6e5c39, 0x605537, 0x544d3a, 0x5a553c, 0x5a553e, 0x5f5a41, 0x686347, 0x706951, 0x817958, 0x8c855f, 0x8b8461, 0x847e6b, 0x7c735d, 0x7a6c59, 0x7e6f5b, 0x84725a, 0x897359, 0xc3ac02, 0xd3b50a, 0xcfab14, 0xcfaa0e, 0xd7b60a, 0xd7b711, 0xdbb90c, 0xd4b506, 0xcdb405, 0xb6a403, 0xb8a007, 0xc3a90b, 0xaf9f05, 0xc7b204, 0xcab10f, 0xcaae12, 0xd5ba08, 0xddc009, 0xe2c114, 0xd6b316, 0xdfbd14, 0xe5c123, 0xebc632, 0xe1bd27, 0xdcba21, 0xdeb922, 0xdbb325, 0xd6ae23, 0xcaa323, 0xd3aa30, 0xcba53f, 0xc69e40, 0xc19f40, 0x9f8636, 0x988137, 0x8d793b, 0x6d5f3e, 0x6c6140, 0x766945, 0x7a6d4c, 0x7a6e4c, 0x88825d, 0x7a745e, 0x756a54, 0x766854, 0x796a55, 0x837054, 0x8b7354, 0xc1a702, 0xc8ac04, 0xc7a117, 0xc8992c, 0xc9a115, 0xbc9c11, 0xcdb20a, 0xcdb701, 0xcab504, 0xc5b003, 0xccae09, 0xc8a90b, 0xc3aa0a, 0xd0b604, 0xd9be07, 0xdcbc0e, 0xc8ac0e, 0xc5ad0a, 0xccb60b, 0xc2b00b, 0xcbb609, 0xd2b415, 0xd3b31f, 0xd4b419, 0xd7b51d, 0xd6b328, 0xd7b525, 0xd4b122, 0xd4b129, 0xceae2c, 0xd1af2d, 0xdbb543, 0xd7b448, 0xd3b040, 0xd1ae42, 0xd7b14e, 0xcaa24f, 0xbb9749, 0xa88d45, 0xa38648, 0xae8f4c, 0x958651, 0x817753, 0x74664d, 0x736650, 0x776853, 0x7f6b51, 0x897152, 0xa59009, 0xb99e05, 0xb89313, 0xc9992c, 0xc99e23, 0xc3a014, 0xcfb219, 0xbda70d, 0xc5aa0e, 0xceb114, 0xb9a416, 0xceb214, 0xc29e17, 0xc3ab19, 0xc4ac0f, 0xd2b110, 0xbc981a, 0xa88a1b, 0xb29f0e, 0xbfac0a, 0xb8a706, 0xc7ac07, 0xbaa10b, 0xbfa514, 0xd0b215, 0xc2a612, 0xc0a60e, 0xc5ac13, 0xbca020, 0xaf9525, 0xbe9d1f, 0xc7ac26, 0xceb42f, 0xcdb131, 0xc7ac2f, 0xc7a93a, 0xc9aa41, 0xc6aa42, 0xc6a943, 0xbea143, 0xb89c43, 0xbd9f47, 0xb3974c, 0xad924d, 0xac8f4c, 0xa58a4e, 0xaa8e51, 0xb19153, 0x9f890e, 0xbd990d, 0xb99218, 0xa88827, 0xb89b26, 0xb0932d, 0xbb9727, 0xb39918, 0xa99315, 0xc1a11d, 0x938221, 0xad9524, 0xab9023, 0x816f2c, 0x8f792a, 0xab8f23, 0x9e8624, 0x9f8329, 0xc9b11a, 0xa99a12, 0x8b7a19, 0xa58f11, 0xb7a107, 0xb39712, 0xc5a718, 0xb29917, 0xac9516, 0xa9931c, 0xa2892a, 0x96852b, 0x978429, 0x988a25, 0xa79424, 0xaa952d, 0xa58e38, 0x9b8735, 0x937e38, 0x8f7e38, 0x9d8a3a, 0x9e863b, 0x8c7e3c, 0xa58e41, 0xbb9948, 0xc2a14e, 0xc5a34c, 0xbf9c4a, 0xc1a04d, 0xc6a450, 0xa88e18, 0xc39d15, 0xc8a40c, 0xa8841e, 0xbd9320, 0xb29327, 0xbfa224, 0xbba515, 0xbba613, 0xc9b315, 0xbaa021, 0xb69129, 0x9f8025, 0x967722, 0x977223, 0xc29130, 0x997b2a, 0x6f6025, 0x988824, 0xa6941f, 0x846c27, 0x927429, 0xb48e23, 0xb78f2a, 0xbd942b, 0xb9922e, 0xb18d2d, 0xc29d3c, 0xbf9c3c, 0xa28325, 0x967c30, 0x967f36, 0x997b2c, 0xa58733, 0xa2863f, 0xa7843a, 0xbc923e, 0xb58b40, 0xa2813d, 0x9a7f40, 0x9a8040, 0x947d40, 0x9c8244, 0x9f8645, 0xa28847, 0xab8b49, 0xb68f4b, 0xba974f, 0xa38a1c, 0xa08c11, 0xbfab02, 0xcaaf0a, 0xbfa50f, 0xbba90d, 0xb8ab09, 0x988612, 0xa98c27, 0xc0a52c, 0xb8a41c, 0xc4a918, 0xb69224, 0xba9c0e, 0xcda90f, 0xdba428, 0xd29c33, 0xaf862c, 0xb0872c, 0xca9b2f, 0xc89329, 0xd8a233, 0xd29e32, 0xcd983a, 0xd29d36, 0xcd982e, 0xc39232, 0xc39933, 0xb0922c, 0xac8d22, 0xb6962a, 0xaa892f, 0xa6812b, 0xa7832f, 0xa48130, 0xaf8633, 0xc6953b, 0xb88f40, 0xa0833e, 0x9e8541, 0x998342, 0xa08848, 0xa38946, 0x9e8545, 0xa38748, 0xac8d4c, 0xb38f4d, 0xbb984f, 0xa28219, 0x847911, 0x998e09, 0x989409, 0x938c10, 0xa99612, 0xad9813, 0xbb9e15, 0xc09c2f, 0xbea32e, 0x9c9312, 0xa59906, 0xab9b0c, 0x7c750c, 0xb1a00c, 0xdbbd0f, 0xd1af13, 0xc3a119, 0xc2a415, 0xc3a01c, 0xb1941b, 0xd4a523, 0xca9429, 0xc79733, 0xb79524, 0xb8901d, 0xbc8f24, 0xb68a30, 0xae9124, 0xa08a1a, 0xa89016, 0xb09119, 0xa98629, 0xa38928, 0xa5842f, 0xa07f30, 0xb38b36, 0xb99239, 0xa5843a, 0xaa8e3e, 0xab923f, 0xad8f47, 0xaf8b45, 0xb59047, 0xb5944a, 0xb9964c, 0xb8964a, 0xba9d4d, 0xa3850c, 0xae8e08, 0xbf9f07, 0x9b8808, 0x69680b, 0x83741b, 0x90801f, 0xb2951a, 0xa68826, 0xa29224, 0xa39b13, 0xaca007, 0xbba901, 0x91840e, 0x9f9014, 0xa59a08, 0xb4ad01, 0xb0a503, 0xa89b04, 0xae9e0d, 0xb6a111, 0xbc9c1c, 0xb69023, 0xaa921c, 0x918f0e, 0xae9f08, 0xb49f12, 0xab921f, 0x9e8a19, 0x9f9115, 0x9a8a19, 0xa18f18, 0x837925, 0x8f8625, 0x978428, 0x957d2c, 0x9d7b30, 0xab8833, 0xb08d37, 0xa38b38, 0xa38f3a, 0xac8f39, 0xaa8743, 0xad884a, 0xb08d4a, 0xb9994b, 0xb19a49, 0xaf964e, 0x9b8110, 0x806913, 0x9a8109, 0xb99807, 0x8a7710, 0x88761e, 0x938022, 0x978317, 0xa0901b, 0x827b18, 0x706b13, 0x9f8f0e, 0xab9111, 0xad9e0a, 0xa39d0e, 0x988c18, 0xa8a00b, 0xb0ab06, 0xaa9c06, 0xbb9f17, 0xb9a511, 0x998b0d, 0x9e9011, 0x868112, 0x8c8911, 0x958f08, 0x817914, 0x8d831a, 0x968025, 0x7e7226, 0x7c7322, 0xa4911f, 0x978829, 0x958a2b, 0x8c812b, 0x8c7830, 0x987d30, 0x9e8037, 0x9a7c3b, 0x8b743a, 0x917b42, 0x988146, 0x9b814a, 0x9e8151, 0xa08654, 0xa08a53, 0xa99452, 0xae9456, 0x8c7218, 0x896b1a, 0x907412, 0xa9890a, 0xac8c0f, 0xa38517, 0xa58322, 0x877417, 0x837a11, 0x928a0b, 0x8d7f0f, 0x907f12, 0x9e8215, 0xb49f07, 0xaa9c0c, 0x978616, 0x958311, 0xa59211, 0x9e8412, 0xaf9117, 0xbea20e, 0xa38d08, 0x9f8e09, 0x746c12, 0x726b13, 0x898011, 0x948014, 0x907813, 0x977f20, 0x867127, 0x7c6823, 0x776822, 0x7e6c2a, 0x87782a, 0x87762b, 0x776c32, 0x867637, 0x937e40, 0x83733e, 0x87753f, 0x8f7a42, 0x9c854a, 0x947f4b, 0x917f54, 0x9e895b, 0xa18d60, 0xa79264, 0xaa9767, 0x8b7c0a, 0x988109, 0xa2850d, 0x957e0b, 0xa48e07, 0xa89305, 0xaf9309, 0xac8f06, 0x918106, 0x9a8907, 0x9c8d09, 0x988e0a, 0x928209, 0x8c7b0b, 0x8f7916, 0x896f1d, 0xa08419, 0xb19012, 0xa77f13, 0x9b7e0a, 0x967b00, 0x9b8802, 0xb39f0f, 0xac9523, 0x97872f, 0x83773a, 0x988740, 0x958036, 0x937e34, 0x9d843b, 0x8c7033, 0x706435, 0x7d6d33, 0x7a6f33, 0x928851, 0x716d35, 0x71682a, 0x7d7032, 0x736b35, 0x857b43, 0x867b46, 0x877c4a, 0x958754, 0xa59360, 0xb7a06e, 0xbaa571, 0xb2a176, 0xb8a87e, 0x786910, 0x877507, 0x948105, 0x837506, 0x958406, 0xa59203, 0x998905, 0xbc9e05, 0xa09003, 0x908206, 0x92820c, 0x8f810d, 0x907b0e, 0x957815, 0x997622, 0xa58123, 0xa7831c, 0xaf7d10, 0xa67712, 0x91792c, 0x9a8c5d, 0x888e76, 0x8f997f, 0x89938f, 0x879099, 0x8f989f, 0x929ba4, 0x909699, 0x90948f, 0x929592, 0x8d908c, 0x91958f, 0x9a9e93, 0xa0a299, 0xb4b3b8, 0x9b9a8f, 0xaaa282, 0xaa9f7b, 0x988d67, 0x92894f, 0x8b823f, 0x898048, 0x918a54, 0xad9d6b, 0xc7b17f, 0xc9b986, 0xc7b589, 0xcfbf92, 0xaa8d10, 0xa89202, 0xa68f04, 0x9c8707, 0x85750c, 0x6c6315, 0x6f660f, 0x73680b, 0xa49106, 0x998a06, 0xb09b05, 0x9a8906, 0x9d880d, 0xb29c0f, 0xab9613, 0x9a8112, 0x8a6f15, 0x8c7532, 0x8a846f, 0x7f909f, 0x6383a4, 0x52749d, 0x42638c, 0x37577e, 0x334f72, 0x304a6c, 0x304767, 0x314968, 0x354b6a, 0x384d6a, 0x3c4f6b, 0x40536c, 0x465972, 0x545e76, 0xa5a5b1, 0xded6da, 0xbeb8bd, 0xafabae, 0xb4b1ac, 0xcac4b4, 0xc5bfa1, 0xa6a06f, 0x908d56, 0x9b9366, 0xb9aa7e, 0xc1b58a, 0xd1c394, 0xe0ce9c, 0x81770d, 0x817607, 0xa28808, 0x86790a, 0x7c710e, 0x6a6510, 0x5d5a0f, 0x796f0c, 0x938305, 0x827c06, 0x827e06, 0x797509, 0x464a18, 0x55590b, 0x606903, 0x8b8b1c, 0x92946a, 0x8b9cb2, 0x6484a8, 0x3f6484, 0x3d5e6f, 0x3d5964, 0x3c525c, 0x364c56, 0x263a4f, 0x25364c, 0x26364a, 0x28384a, 0x293748, 0x2c3b4b, 0x3a4d56, 0x425559, 0x303f4a, 0x616670, 0xd1cac8, 0x798490, 0x4b677e, 0x516f87, 0x597389, 0x677788, 0x878e96, 0xbab8b2, 0xc1bca9, 0xa19d80, 0xa2997a, 0xaea487, 0xc0b393, 0xc7bc97, 0x76680d, 0x82710c, 0xa58212, 0x97810c, 0x81720f, 0x756c11, 0x726a0d, 0x76700f, 0x696a0e, 0x635c12, 0x625a1b, 0x7c7313, 0x615e21, 0x676a57, 0x6a7060, 0x8a999d, 0x8b9eb9, 0x5c788f, 0x365568, 0x3a525d, 0x3f5558, 0x3e5050, 0x3c4e51, 0x32444b, 0x243241, 0x232f3e, 0x283541, 0x25313d, 0x26313c, 0x2c3945, 0x384d56, 0x314650, 0x39414e, 0xbeb8b8, 0x808e9c, 0x305777, 0x375d7e, 0x3c617f, 0x517088, 0x5f788c, 0x5d7489, 0x57687a, 0x90959a, 0xcbc8c2, 0xb7b3a3, 0xa59f84, 0xb0a990, 0xb2ae97, 0x6b6010, 0x685e11, 0x8c6f10, 0x86770e, 0x746816, 0x716113, 0x68610f, 0x605b13, 0x514c0e, 0x4c4310, 0x584c12, 0x564c05, 0x7d794c, 0xa0a5b6, 0x97a3b5, 0x5a718d, 0x3a5064, 0x354950, 0x38494f, 0x354348, 0x354444, 0x374444, 0x384646, 0x29363c, 0x1e2633, 0x25313b, 0x2f3c42, 0x212a34, 0x242d37, 0x26303a, 0x2b3640, 0x24333e, 0x949395, 0x999da5, 0x47637f, 0x8a9fb4, 0x9cacbc, 0x93a4b2, 0x5c7990, 0x597389, 0x5f758a, 0x5a6f89, 0x546c82, 0x747d87, 0xd5d3d0, 0xc3c1b7, 0xabaa94, 0xb2ae9a, 0x625612, 0x544b14, 0x554b12, 0x403a09, 0x3e390a, 0x4a4618, 0x4a4b27, 0x605e33, 0x6f6d3d, 0x747047, 0x7d7850, 0x848050, 0x959485, 0xa9a9b4, 0x6c7887, 0x45535f, 0x45525b, 0x414c56, 0x3e4a51, 0x3e494d, 0x3d494c, 0x3a4447, 0x384145, 0x272f3c, 0x232b39, 0x232d3b, 0x212c3b, 0x202a38, 0x242d3b, 0x1e2631, 0xe1623, 0x585b62, 0xaca9a8, 0x405060, 0x5c6f82, 0x7c848e, 0x7a8089, 0x8f9096, 0x6e7f8d, 0x4d677c, 0x5d6f82, 0x5d6d81, 0x67768a, 0x808690, 0xdfdad4, 0xe3e1df, 0xc7c8c4, 0xb9bab0, 0x585015, 0x60510e, 0x70632a, 0x76745a, 0x8c8c7d, 0xa8a69c, 0xbbb9b3, 0xd1cec7, 0xe7e4dd, 0xf6f2ea, 0xf3f2ed, 0xecedeb, 0xe5e5e6, 0xd5d6d9, 0xc2c7ce, 0xbcc1cb, 0xb2b6c3, 0xa7adbb, 0x9fa6b2, 0xa0a6b2, 0x9ba3b0, 0x9099a7, 0x7f8da1, 0x74839b, 0x6d7c95, 0x6e7c91, 0x727c91, 0x788195, 0x7a8395, 0x727985, 0x636771, 0xb5b2b5, 0x85868b, 0x363e4b, 0x2c323a, 0x494848, 0x848182, 0x908d8f, 0xa1a3a9, 0xadb1b7, 0xb6b6bb, 0xb6b8bc, 0xbab9bb, 0xd3d1ce, 0xe6e1dd, 0xe7e1dd, 0xdfdcda, 0xdedcda, 0x584f18, 0x878263, 0xa2a7ac, 0xb6c0cd, 0xcbd4e2, 0xcdd3e0, 0xd3d8e1, 0xc9d1d9, 0xc4ccd5, 0xbac4cf, 0xb4bfcc, 0xadbac9, 0xaab7c6, 0xa5b5c6, 0xa0b1c2, 0xa2b0c2, 0xb2bbcc, 0xbdc4d1, 0xbec5d2, 0xb3bbc9, 0xadb4c3, 0xa9b3c5, 0xadb7c6, 0xbcc1cd, 0xc8cad4, 0xd3d4d9, 0xdddbdf, 0xe2e1e3, 0xe3e3e4, 0xdedee3, 0xdbdbe0, 0xdcdad9, 0xb4b8c0, 0x3a4f69, 0x565e6a, 0xbebcbc, 0xe7e5e6, 0xe0e0e2, 0xdededf, 0xdadbdd, 0xd9dbdb, 0xd5d6d7, 0xcaced0, 0xc7c9cc, 0xdddad9, 0xe2deda, 0xddd9d7, 0xdddad9, 0x8f8c81, 0x7e89a7, 0x9ea8c1, 0xabb3c2, 0xa8b4c1, 0x96a5bb, 0x91a3b9, 0x92a4ba, 0x94a5bb, 0x96a7bb, 0x95a6bc, 0x95a6bc, 0x95a6bb, 0x99aabd, 0xaab9c8, 0xb7c1d3, 0xa7b2c4, 0x929bae, 0x738095, 0x6b758c, 0x6b748c, 0x6f788f, 0xb3b3bd, 0xe4e1e0, 0xe6e0e0, 0xeeeae9, 0xede9e8, 0xe1dedd, 0xdbd9d7, 0xd7d5d7, 0xd4d3d8, 0xcbcdd2, 0xa1aebe, 0x6d86a4, 0xb4bbc7, 0xd0d0d4, 0xc4c6cb, 0xc2c5ca, 0xbec4c9, 0xc3c7cd, 0x9fa2ab, 0x9b9ba0, 0xbbc0c5, 0xbbbec3, 0xbdbfc5, 0xb1b3ba, 0xc8c6cc, 0xd1d1d2, 0x7e8daa, 0x8589a0, 0xb0b3c2, 0x919db3, 0x8a99b0, 0x8b99b3, 0x8998b3, 0x8999b4, 0x8d9db7, 0x8f9fb9, 0x90a1ba, 0x90a2bb, 0x98a7be, 0xaab6c8, 0x97a4b9, 0x697990, 0x5a6983, 0x394760, 0x5d6377, 0x7b8195, 0x627088, 0xa8acba, 0xc1c3cc, 0xc1c2cb, 0xd5d3d8, 0xa8a9ad, 0x7c7d83, 0x909398, 0x9ca1a7, 0x9fa4ab, 0x9ea2a9, 0xa7abb1, 0xa2aebc, 0xa9b4c3, 0xccccd1, 0xc5c8cc, 0xc3c7cb, 0xc2c5cb, 0xbec2c8, 0xbdc0c7, 0x9b9da6, 0x95989c, 0xb3b8bb, 0xacb2b9, 0x959ba5, 0x989da6, 0x8d8e93, 0x81807e, 0x9a9eb2, 0xb4b9c8, 0x95a1b8, 0x939fb7, 0x95a2b9, 0x8695b0, 0x8696af, 0x95a4bb, 0x95a6bc, 0x98a8c0, 0x97a7c0, 0x9aaac2, 0xa3b3c7, 0xa5afc0, 0x7b8092, 0x697688, 0x848798, 0x6e7385, 0x6f6f7d, 0x818493, 0xa7a9b7, 0xbdbfc9, 0x9ca3b2, 0xa4a9b6, 0x7b7b80, 0x555455, 0x5e5e5d, 0x272d31, 0x71767b, 0x848a93, 0x727983, 0x8a949b, 0x97a0ab, 0x9fa5ae, 0x9ea3ac, 0x959ca6, 0x9199a1, 0x8d949e, 0x878f99, 0x828b94, 0x848c95, 0x858b94, 0x8d9299, 0x8e959c, 0x889199, 0x7f8287, 0x7f7c79, 0x7f7b7a, 0x9399ac, 0x909bb2, 0x8b9bb2, 0x93a0b7, 0x909fb6, 0x6e7ea1, 0x7a8aa5, 0x93a1b6, 0x93a1b8, 0x919fb9, 0x96a6bb, 0x93a5b7, 0x9aaabd, 0x8a96a8, 0x77818f, 0x768191, 0x707c8c, 0x717e90, 0x78899d, 0xb9c1cd, 0xd9d8df, 0xbec0c8, 0x9196a5, 0x6b6970, 0x404043, 0x8e847c, 0x8d8a84, 0x1b2428, 0x343a3d, 0x686e75, 0x575d64, 0x727a85, 0x6c747f, 0x69717f, 0x666e7b, 0x656e7a, 0x656c77, 0x636b76, 0x636b76, 0x636a77, 0x656c76, 0x686e77, 0x6e7179, 0x737981, 0x737981, 0x6e716f, 0x6a6a67, 0x676864, 0x546070, 0x6d788d, 0x717f96, 0x7e8b9f, 0x8793a9, 0x8b98ad, 0x8a98ae, 0x8594a9, 0x8692aa, 0x8a98ae, 0x93a2b4, 0x919fb1, 0x8898ac, 0x8898ae, 0x7f91a7, 0x5f6e83, 0x576778, 0x505c6c, 0x39444f, 0x898a90, 0xcacbd2, 0xb4b9c3, 0x8c747b, 0x2e2225, 0x212528, 0x746f6c, 0x5e5f64, 0x262f34, 0x1b2326, 0x4a5055, 0x424a53, 0x565f69, 0x535c66, 0x505a64, 0x4e5762, 0x4e5761, 0x515964, 0x525a64, 0x545c66, 0x585f68, 0x585f68, 0x575c64, 0x5f6268, 0x6c7078, 0x686c72, 0x585b5a, 0x636362, 0x656362, 0x27282e, 0x292933, 0x292d34, 0x2c333a, 0x31353d, 0x32373e, 0x333840, 0x30353f, 0x2e333d, 0x31363e, 0x313641, 0x30363f, 0x2e353d, 0x333a44, 0x818a96, 0x7f8691, 0x7c8187, 0x6f7076, 0x27292f, 0x2c2e32, 0xa3a4a9, 0x98a0aa, 0x4a3a3f, 0x1b1b1f, 0x202227, 0x5a5856, 0x646667, 0x1e282d, 0x192024, 0x3f454a, 0x434b53, 0x475159, 0x47505a, 0x454d58, 0x444c57, 0x434d55, 0x424a54, 0x414a54, 0x404953, 0x3f4751, 0x4c5159, 0x6a6d75, 0x6a6e76, 0x64696e, 0x505253, 0x5a5958, 0x6a6869, 0x828080, 0x292b2e, 0x1f1e22, 0x1c1d20, 0x1a1d20, 0x191d1f, 0x1b1f20, 0x1d2121, 0x1e2122, 0x1f2122, 0x202023, 0x1d2022, 0x1d2022, 0x18181b, 0x454749, 0x7d7c7b, 0x726f6b, 0x6f6a67, 0x52504e, 0x1c1f24, 0x1e2228, 0x5d6065, 0x717981, 0x27282d, 0x1b1c1f, 0x202226, 0x51514f, 0x58585c, 0x192027, 0x171e23, 0x4b5056, 0x434b55, 0x2a343d, 0x2e3641, 0x29323c, 0x28323b, 0x2c343e, 0x363e48, 0x444c54, 0x51575f, 0x70757a, 0xb1b2b5, 0xb0b1b4, 0x707278, 0x5a5b5f, 0x4d4c47, 0x73726e, 0x707072, 0x606061, 0x404042, 0x1e2025, 0x202226, 0x1c2022, 0x1d2122, 0x1e2224, 0x202225, 0x212527, 0x222629, 0x232728, 0x24282a, 0x25292b, 0x2e3135, 0x626363, 0x736e69, 0x74706a, 0x7a7774, 0x4f5053, 0x16181d, 0x1c1c21, 0x484d53, 0x58636b, 0x1f2227, 0x171c1d, 0x1c1f20, 0x817c77, 0x55585d, 0x1f262c, 0x151d21, 0x4d525a, 0x636a71, 0x686d72, 0x6d7276, 0x7b7e81, 0x85898d, 0x8f9195, 0x929498, 0x959698, 0xa1a0a1, 0xaeacad, 0x8b8c8c, 0x535251, 0x504b4b, 0x52504f, 0x484744, 0x5a5b59, 0x5a5a5a, 0x6a6b6e, 0x272a2d, 0x1d1e21, 0x1c1e21, 0x1a1c1e, 0x191d1e, 0x1b1d1f, 0x1c1d21, 0x181c20, 0x171b1f, 0x171a1f, 0x181b1f, 0x181a1e, 0x1d1f24, 0x45474b, 0x798289, 0x84919c, 0x909cad, 0x5e697b, 0x101119, 0x2d2f34, 0x565b61, 0x3b4146, 0x1c1d21, 0x191b1d, 0x171b1c, 0x6f6d68, 0x4d5354, 0x1a2127, 0x262c2f, 0x54595d, 0x5b5f64, 0x7f7e80, 0x7f7e7e, 0x787778, 0x737172, 0x6d6c6d, 0x676869, 0x68696d, 0x6a6c6f, 0x64676d, 0x65686c, 0x818085, 0x6b6969, 0x434139, 0x4b4943, 0x6b6a67, 0x858483, 0xa0a2a2, 0x62564a, 0x292726, 0x181a1d, 0x1a1e1f, 0x181c1d, 0x1a1b1e, 0x181a1d, 0x212325, 0x282a2a, 0x292829, 0x272629, 0x2f2d2f, 0x39393c, 0x3b3f41, 0x44484c, 0x616871, 0x6d727a, 0x606468, 0x575959, 0x555555, 0x4e4b49, 0x353636, 0x17191d, 0x161a1b, 0x181a1b, 0x555556, 0x4c5051, 0x14181c, 0x212627, 0x404343, 0x63676b, 0x575b5d, 0x525552, 0x4f514e, 0x555653, 0x5d5f5d, 0x5e6265, 0x61646a, 0x666a71, 0x646c73, 0x7a7e86, 0x858990, 0x696b6f, 0x42403c, 0x403e36, 0x525048, 0x85837d, 0x969996, 0xc7a486, 0x504840, 0x14171b, 0x191c1e, 0x16171a, 0x16161a, 0x101216, 0x736c5e, 0x968a74, 0x8a7e6e, 0x847a6b, 0x817a6a, 0x7b7568, 0x726d63, 0x645f56, 0x59544b, 0x514b43, 0x4d473f, 0x48463f, 0x41403c, 0x393834, 0x242726, 0x111517, 0x141619, 0x111415, 0x57524d, 0x2c2e31, 0xb1011, 0xf1416, 0x1c2224, 0x2a2f31, 0x282a29, 0x2c2e2b, 0x2c2f2c, 0x282a27, 0x232423, 0x262724, 0x2c2c2b, 0x333331, 0x3a3c37, 0x3f403c, 0x44453f, 0x4e4e49, 0x5a5953, 0x5a5a51, 0x595950, 0x5d5c54, 0x605e55, 0xab927b, 0x827764, 0x191b1c, 0xf1116, 0xf1115, 0xc0e13, 0x15171a, 0x47423e, 0x45413b, 0x383633, 0x31312c, 0x272826, 0x1e2021, 0x1d1f20, 0x1a1c1c, 0x181a1a, 0x141617, 0x101314, 0x141314, 0x151718, 0x1e1f1e, 0x272726, 0x2c2c28, 0x32312c, 0x373631, 0x4f4b43, 0x44443b, 0x45443e, 0x45453f, 0x43433d, 0x464640, 0x4c4d47, 0x4c4c45, 0x4a4c45, 0x4b4d47, 0x4e4f48, 0x50504a, 0x53534e, 0x5a5a53, 0x5d5e56, 0x5b5c55, 0x5c5c55, 0x5e5e56, 0x5b5a54, 0x5a5953, 0x5a5a51, 0x5e5d54, 0x65655b, 0x373634, 0x302f2f, 0x242325, 0x222223, 0x222223, 0x242424, 0x262526, 0x272625, 0x262625, 0x2e2d2b, 0x393834, 0x3f3d38, 0x403e38, 0x41403a, 0x4c4940, 0x545147, 0x5a574b, 0x5e5b50, 0x5f5a50, 0x5b574c, 0x59564a, 0x565247, 0x565247, 0x59564b, 0x58574b, 0x4e4d42, 0x504f44, 0x4a4a3f, 0x4b4b42, 0x4f4f46, 0x55554c, 0x505247, 0x4f5247, 0x4f504a, 0x4f504a, 0x4f5048, 0x4b4b45, 0x4a4943, 0x4b4b45, 0x484942, 0x4a4b44, 0x4e4e48, 0x53524d, 0x575750, 0x5b5c56, 0x616059, 0x626159, 0x636156, 0x665f57, 0x6c655d, 0x6f685e, 0x6b6559, 0x6a6559, 0x6c675b, 0x6e695c, 0x6f695c, 0x6f695c, 0x6b6559, 0x666054, 0x625d51, 0x605b4f, 0x5c574a, 0x575246, 0x575247, 0x565347, 0x565247, 0x585449, 0x575348, 0x585447, 0x575247, 0x575348, 0x575347, 0x5b594d, 0x5f5d50, 0x585649, 0x525146, 0x4e4e44, 0x494941, 0x4c4c41, 0x46473d, 0x44453a, 0x44443b, 0x45463d, 0x45463f, 0x464540, 0x4f4f46, 0x515147, 0x4e4e47, 0x53524b, 0x53534e, 0x52524d, 0x51504a, 0x4e4f49, 0x5a5952, 0x615f56, 0x66645b, 0x6b6559, 0x655d53, 0x615a50, 0x5c574d, 0x5a5448, 0x555045, 0x5a564b, 0x555146, 0x555046, 0x595449, 0x555146, 0x575347, 0x5c574b, 0x5a5549, 0x535043, 0x595647, 0x5c594b, 0x5c584b, 0x5b584b, 0x5d584d, 0x5f5b4f, 0x5d5a4e, 0x555146, 0x4c483d, 0x4a493d, 0x45463b, 0x424238, 0x46463b, 0x45463c, 0x494a3f, 0x4e4c42, 0x4b4a41, 0x504d43, 0x4d4d43, 0x4c4d45, 0x505047, 0x4b4b42, 0x4e4e43, 0x4e4e46, 0x54554d, 0x585951, 0x585951, 0x5b5b54, 0x5b5c54, 0x5f6058, 0x66665d, 0x69695f, 0x6b6b61, 0x5c564a, 0x5e574d, 0x575047, 0x5e574b, 0x686255, 0x666154, 0x605a4e, 0x625d4f, 0x5c564a, 0x5f584c, 0x5e584b, 0x5c5549, 0x605a4e, 0x615c50, 0x5d584c, 0x5d574c, 0x585346, 0x524d42, 0x4a463c, 0x49453a, 0x48453a, 0x4f4c41, 0x4e4b40, 0x514d42, 0x545245, 0x535045, 0x524e44, 0x4f4e42, 0x514f45, 0x525145, 0x545345, 0x535246, 0x58564a, 0x59574b, 0x5a5a4f, 0x5d5c53, 0x5a5b50, 0x5a584d, 0x605f55, 0x5b5c53, 0x5e5e55, 0x62625a, 0x5f5f58, 0x606059, 0x64645c, 0x696960, 0x66665e, 0x66665e, 0x625a4f, 0x5f584d, 0x585247, 0x5d574a, 0x5e574c, 0x5d564b, 0x585246, 0x605a4c, 0x5f5a4e, 0x5e574c, 0x5d574c, 0x5a5549, 0x4f4b40, 0x4e493c, 0x514c40, 0x514d41, 0x5e5a4d, 0x575347, 0x555045, 0x625c4f, 0x656054, 0x645f52, 0x595548, 0x5f5a4e, 0x605a4e, 0x646053, 0x625e53, 0x626053, 0x5f5e51, 0x646155, 0x626153, 0x636154, 0x5e5b52, 0x605e51, 0x5d5b51, 0x646259, 0x606056, 0x59594f, 0x66665c, 0x61635a, 0x5b5c55, 0x64655e, 0x65655d, 0x61615a, 0x626259, 0x66665e, 0x696961, 0x6a6b64, 0x5c5449, 0x5e584d, 0x5c574c, 0x5c564a, 0x575042, 0x554b44, 0x595249, 0x625b4f, 0x5d564b, 0x655f52, 0x645e52, 0x665f53, 0x676254, 0x696354, 0x6a6354, 0x656050, 0x686255, 0x6b6558, 0x6a6355, 0x706958, 0x706a5a, 0x716b5d, 0x686152, 0x696354, 0x6e685b, 0x696558, 0x676356, 0x625e52, 0x5f5c50, 0x605b51, 0x615e53, 0x605c51, 0x615f54, 0x5e5c53, 0x666259, 0x5c5b52, 0x5e5f54, 0x616056, 0x64655b, 0x64655b, 0x616158, 0x66665e, 0x65655d, 0x5f6157, 0x63645b, 0x63645c, 0x676860, 0x676862, 0x625a50, 0x635b51, 0x615b4e, 0x666052, 0x6a6354, 0x70695b, 0x756f5f, 0x706a5a, 0x746d5d, 0x706859, 0x736e5c, 0x736b5d, 0x736c5c, 0x6d6558, 0x716a5b, 0x746d5e, 0x746e5f, 0x736b5d, 0x706a5a, 0x706a57, 0x6c6656, 0x666254, 0x625f51, 0x625c4f, 0x686156, 0x615c4e, 0x635f53, 0x676357, 0x666155, 0x605b4f, 0x656055, 0x615e52, 0x5f5d52, 0x625f56, 0x625f57, 0x5d5a51, 0x625f56, 0x605c53, 0x58564d, 0x5c5d53, 0x5a5a53, 0x636159, 0x606057, 0x616258, 0x616158, 0x5f5f57, 0x606058, 0x67675f, 0x787162, 0x756e61, 0x766e61, 0x787162, 0x797262, 0x766f5d, 0x756e5d, 0x6c6558, 0x746d5c, 0x6a6356, 0x716a5b, 0x736b5e, 0x70685c, 0x766e60, 0x746d5c, 0x746d5b, 0x6f685a, 0x746e5d, 0x6c6656, 0x696252, 0x6a6456, 0x6d6759, 0x665f52, 0x666053, 0x635d50, 0x645e51, 0x625e52, 0x646054, 0x5e5b4f, 0x5e594e, 0x615b50, 0x625f53, 0x615d52, 0x5d5d50, 0x646258, 0x5e5a4f, 0x5f5b52, 0x686559, 0x5e5b50, 0x626156, 0x5f5f58, 0x615f56, 0x626258, 0x66665c, 0x66665b, 0x67675e, 0x6a6961, 0x6e6e63, 0x726b5c, 0x71695d, 0x6f675c, 0x70685a, 0x6d6557, 0x797361, 0x766e5f, 0x71695d, 0x6c6557, 0x716b5b, 0x6e675a, 0x70695d, 0x756f62, 0x6f675c, 0x6f6758, 0x6f6857, 0x736d5c, 0x6a6355, 0x645d50, 0x6e6758, 0x6b6556, 0x686455, 0x635e52, 0x645e51, 0x666054, 0x635e52, 0x625e52, 0x615d51, 0x5b574c, 0x635e54, 0x635f54, 0x645e54, 0x615d52, 0x5b594d, 0x666357, 0x666358, 0x615e55, 0x6a665c, 0x6c6a5d, 0x6c6b61, 0x6d6b61, 0x6f6d63, 0x717067, 0x6f6f65, 0x6b6a60, 0x6d6c63, 0x6b6a62, 0x65655f, 0x6a6455, 0x676054, 0x726c5c, 0x776f5f, 0x6e6658, 0x726b5b, 0x6d6457, 0x736c5d, 0x756f5e, 0x766e60, 0x726b5e, 0x706a5c, 0x676053, 0x635c4f, 0x686054, 0x6c6656, 0x726b5a, 0x696152, 0x696254, 0x6a6454, 0x6e6858, 0x696258, 0x665f54, 0x6a6457, 0x655f52, 0x655f53, 0x635e53, 0x615d51, 0x615d52, 0x5f5c51, 0x696559, 0x655f55, 0x676358, 0x676358, 0x68655a, 0x6a695d, 0x6e6a60, 0x6f6d64, 0x6e6c60, 0x726f63, 0x716d62, 0x716d63, 0x6c6960, 0x626058, 0x66635b, 0x58564f, 0x55554e, 0x55544e, 0x777061, 0x716a5a, 0x696254, 0x6e675a, 0x5f5a4f, 0x6b6555, 0x6e6656, 0x726a5b, 0x6f6858, 0x696255, 0x6f685a, 0x696154, 0x625b4f, 0x6d6557, 0x6c6657, 0x645e51, 0x6d6656, 0x6d6656, 0x675f51, 0x696254, 0x676154, 0x6c6357, 0x726a5f, 0x6b6658, 0x676153, 0x645f53, 0x6c675c, 0x6c685c, 0x6e6a5e, 0x706a5d, 0x736e62, 0x737165, 0x726f63, 0x6a675b, 0x6c685b, 0x6f6b5e, 0x6b665a, 0x655f56, 0x5b574e, 0x5d584e, 0x6f695f, 0x71685e, 0x73695d, 0x6a6359, 0x7d766c, 0x746c60, 0x796e61, 0x776c5f, 0x6b6356, 0x6c6457, 0x615b4e, 0x645d52, 0x615b51, 0x686253, 0x726b5a, 0x726b5d, 0x676153, 0x655f50, 0x686053, 0x635d51, 0x655d51, 0x6d645a, 0x6d675a, 0x645f52, 0x6a6356, 0x686152, 0x6e6758, 0x6b6556, 0x676152, 0x6a6256, 0x6c6459, 0x70685c, 0x746d60, 0x6d675a, 0x6c675a, 0x6f6a5e, 0x6a6757, 0x706b5d, 0x666359, 0x57554c, 0x5f5b51, 0x5b574e, 0x5a574d, 0x555046, 0x585247, 0x5d564b, 0x555045, 0x565048, 0x5e5650, 0x5e554c, 0x5e544a, 0x534b43, 0x534c46, 0x4c4942, 0x48423b, 0x3e3b35, 0x645b50, 0x6c6358, 0x6f675b, 0x655e53, 0x625c4f, 0x70695b, 0x6c6354, 0x6d6756, 0x696256, 0x6d6558, 0x6e6658, 0x6a6255, 0x696156, 0x675f54, 0x5b564a, 0x5d5b4e, 0x615e52, 0x5f594f, 0x585249, 0x575347, 0x575348, 0x4f4b42, 0x4c4740, 0x49483f, 0x46423b, 0x3c3b35, 0x373832, 0x373832, 0x2e2f29, 0x2b2b28, 0x202121, 0x1a1a1b, 0x1d1d1d, 0x18181a, 0x161719, 0x141516, 0x151617, 0x171618, 0x171419, 0x17161a, 0x15141a, 0x131419, 0x131518, 0x151419, 0x151318, 0x141316, 0x151419, 0x121316
};

/**
 * @brief      Copy raw feature data in out_ptr
 *             Function called by inference library
 *
 * @param[in]  offset   The offset
 * @param[in]  length   The length
 * @param      out_ptr  The out pointer
 *
 * @return     0
 */
int raw_feature_get_data(size_t offset, size_t length, float *out_ptr) {
    memcpy(out_ptr, features + offset, length * sizeof(float));
    return 0;
}

void r565_to_rgb(uint16_t color, uint8_t *r, uint8_t *g, uint8_t *b) {
    *r = (color & 0xF800) >> 8;
    *g = (color & 0x07E0) >> 3;
    *b = (color & 0x1F) << 3;
}

int cutout_get_data(size_t offset, size_t length, float *out_ptr) {
    // so offset and length naturally operate on the *cutout*, so we need to cut it out from the real framebuffer
    size_t bytes_left = length;
    size_t out_ptr_ix = 0;

    // read byte for byte
    while (bytes_left != 0) {
        // find location of the byte in the cutout
        size_t cutout_row = floor(offset / CUTOUT_COLS);
        size_t cutout_col = offset - (cutout_row * CUTOUT_COLS);

        // then read the value from the real frame buffer
        size_t frame_buffer_row = cutout_row + cutout_row_start;
        size_t frame_buffer_col = cutout_col + cutout_col_start;

        // grab the value and convert to r/g/b
        uint16_t pixel = frame_buffer[(frame_buffer_row * FRAME_BUFFER_COLS) + frame_buffer_col];

        uint8_t r, g, b;
        r565_to_rgb(pixel, &r, &g, &b);

        // then convert to out_ptr format
        float pixel_f = (r << 16) + (g << 8) + b;
        out_ptr[out_ptr_ix] = pixel_f;

        // and go to the next pixel
        out_ptr_ix++;
        offset++;
        bytes_left--;
    }

    // and done!
    return 0;
}


/**
 * @brief      Arduino setup function
 */
void setup()
{
    // put your setup code here, to run once:
    Serial.begin(115200);

    Serial.println("Edge Impulse Inferencing Demo");
}

/**
 * @brief      Arduino main function
 */
void loop()
{
    ei_printf("Edge Impulse standalone inferencing (Arduino)\n");

    if (sizeof(features) / sizeof(float) != EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE) {
        ei_printf("The size of your 'features' array is not correct. Expected %lu items, but had %lu\n",
            EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, sizeof(features) / sizeof(float));
        delay(1000);
        return;
    }

    ei_impulse_result_t result = { 0 };

    // the features are stored into flash, and we don't want to load everything into RAM
    signal_t features_signal;
    features_signal.total_length = sizeof(features) / sizeof(features[0]);
    //features_signal.get_data = &raw_feature_get_data;
    features_signal.get_data = &cutout_get_data;

    // invoke the impulse
    EI_IMPULSE_ERROR res = run_classifier(&features_signal, &result, false /* debug */);
    ei_printf("run_classifier returned: %d\n", res);

    if (res != 0) return;

    // print the predictions
    ei_printf("Predictions ");
    ei_printf("(DSP: %d ms., Classification: %d ms., Anomaly: %d ms.)",
        result.timing.dsp, result.timing.classification, result.timing.anomaly);
    ei_printf(": \n");
    ei_printf("[");
    for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
        ei_printf("%.5f", result.classification[ix].value);
#if EI_CLASSIFIER_HAS_ANOMALY == 1
        ei_printf(", ");
#else
        if (ix != EI_CLASSIFIER_LABEL_COUNT - 1) {
            ei_printf(", ");
        }
#endif
    }
#if EI_CLASSIFIER_HAS_ANOMALY == 1
    ei_printf("%.3f", result.anomaly);
#endif
    ei_printf("]\n");

    // human-readable predictions
    for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
        ei_printf("    %s: %.5f\n", result.classification[ix].label, result.classification[ix].value);
    }
#if EI_CLASSIFIER_HAS_ANOMALY == 1
    ei_printf("    anomaly score: %.3f\n", result.anomaly);
#endif

    delay(1000);
}

/**
 * @brief      Printf function uses vsnprintf and output using Arduino Serial
 *
 * @param[in]  format     Variable argument list
 */
void ei_printf(const char *format, ...) {
    static char print_buf[1024] = { 0 };

    va_list args;
    va_start(args, format);
    int r = vsnprintf(print_buf, sizeof(print_buf), format, args);
    va_end(args);

    if (r > 0) {
        Serial.write(print_buf);
    }
}

My model is trained in grayscale with 48x48 resolution.
Any thoughts please ?

You guys are incredible. I want to you know that I have successfully deployed the edge impulse project to the esp32cam development board (uninstall and re install Arduino and platform.local.txt helped a lot.

After copying raw data in the project and deploying it successfully, I didn’t see the desired result in the serial monitor. As shown in the figure below. Is it the wrong data I copied, or something else?
image


Hi @jiffy, it cannot allocate a buffer large enough to run the neural network calculations. How large is the model that you created (as it states on the Deployment page)? Probably pick a smaller transfer learning model or set the size of your image to a lower resolution (on Create impulse page).

1 Like