diff --git a/components/modules/ai/who_human_face_detection.cpp b/components/modules/ai/who_human_face_detection.cpp
deleted file mode 100644
index 15b12c9..0000000
--- a/components/modules/ai/who_human_face_detection.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-#include "who_human_face_detection.hpp"
-
-#include "esp_log.h"
-#include "esp_camera.h"
-
-#include "dl_image.hpp"
-#include "human_face_detect_msr01.hpp"
-#include "human_face_detect_mnp01.hpp"
-
-#include "who_ai_utils.hpp"
-
-#define TWO_STAGE_ON 1
-
-static const char *TAG = "human_face_detection";
-
-static QueueHandle_t xQueueFrameI = NULL;
-static QueueHandle_t xQueueEvent = NULL;
-static QueueHandle_t xQueueFrameO = NULL;
-static QueueHandle_t xQueueResult = NULL;
-
-static bool gEvent = true;
-static bool gReturnFB = true;
-
-static void task_process_handler(void *arg)
-{
-    camera_fb_t *frame = NULL;
-    HumanFaceDetectMSR01 detector(0.3F, 0.3F, 10, 0.3F);
-#if TWO_STAGE_ON
-    HumanFaceDetectMNP01 detector2(0.4F, 0.3F, 10);
-#endif
-
-    while (true)
-    {
-        if (gEvent)
-        {
-            bool is_detected = false;
-            if (xQueueReceive(xQueueFrameI, &frame, portMAX_DELAY))
-            {
-#if TWO_STAGE_ON
-                std::list<dl::detect::result_t> &detect_candidates = detector.infer((uint16_t *)frame->buf, {(int)frame->height, (int)frame->width, 3});
-                std::list<dl::detect::result_t> &detect_results = detector2.infer((uint16_t *)frame->buf, {(int)frame->height, (int)frame->width, 3}, detect_candidates);
-#else
-                std::list<dl::detect::result_t> &detect_results = detector.infer((uint16_t *)frame->buf, {(int)frame->height, (int)frame->width, 3});
-#endif
-
-                if (detect_results.size() > 0)
-                {
-                    draw_detection_result((uint16_t *)frame->buf, frame->height, frame->width, detect_results);
-                    print_detection_result(detect_results);
-                    is_detected = true;
-                }
-            }
-
-            if (xQueueFrameO)
-            {
-                xQueueSend(xQueueFrameO, &frame, portMAX_DELAY);
-            }
-            else if (gReturnFB)
-            {
-                esp_camera_fb_return(frame);
-            }
-            else
-            {
-                free(frame);
-            }
-
-            if (xQueueResult)
-            {
-                xQueueSend(xQueueResult, &is_detected, portMAX_DELAY);
-            }
-        }
-    }
-}
-
-static void task_event_handler(void *arg)
-{
-    while (true)
-    {
-        xQueueReceive(xQueueEvent, &(gEvent), portMAX_DELAY);
-    }
-}
-
-void register_human_face_detection(const QueueHandle_t frame_i,
-                                   const QueueHandle_t event,
-                                   const QueueHandle_t result,
-                                   const QueueHandle_t frame_o,
-                                   const bool camera_fb_return)
-{
-    xQueueFrameI = frame_i;
-    xQueueFrameO = frame_o;
-    xQueueEvent = event;
-    xQueueResult = result;
-    gReturnFB = camera_fb_return;
-
-    xTaskCreatePinnedToCore(task_process_handler, TAG, 4 * 1024, NULL, 5, NULL, 0);
-    if (xQueueEvent)
-        xTaskCreatePinnedToCore(task_event_handler, TAG, 4 * 1024, NULL, 5, NULL, 1);
-}
diff --git a/components/modules/ai/who_human_face_detection.hpp b/components/modules/ai/who_human_face_detection.hpp
deleted file mode 100644
index c3b8b4f..0000000
--- a/components/modules/ai/who_human_face_detection.hpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-
-#include "freertos/FreeRTOS.h"
-#include "freertos/queue.h"
-#include "freertos/task.h"
-#include "freertos/semphr.h"
-
-void register_human_face_detection(QueueHandle_t frame_i,
-                                   QueueHandle_t event,
-                                   QueueHandle_t result,
-                                   QueueHandle_t frame_o = NULL,
-                                   const bool camera_fb_return = false);
diff --git a/components/modules/ai/who_plumerai_people_detection.cpp b/components/modules/ai/who_plumerai_people_detection.cpp
new file mode 100644
index 0000000..7e27ace
--- /dev/null
+++ b/components/modules/ai/who_plumerai_people_detection.cpp
@@ -0,0 +1,156 @@
+#include "who_plumerai_people_detection.hpp"
+
+#include "esp_log.h"
+#include "esp_camera.h"
+
+#include "dl_image.hpp"
+#include "human_face_detect_msr01.hpp"
+#include "human_face_detect_mnp01.hpp"
+
+#include "who_ai_utils.hpp"
+
+#include "plumerai/model_defines.h"
+#include "plumerai/people_detection_micro.h"
+
+extern "C" void DebugLog(const char *s) { printf("%s", s); }
+
+int clip(float value, int max) { return std::max(0, std::min(static_cast<int>(value), max)); }
+
+constexpr int num_colors = 19;
+const int colors[num_colors] = {15785, 57545, 65283, 1049,  62470, 37110, 18334, 61852, 55207, 65018, 1040,  56831, 43877, 65497, 32768, 45048, 33792, 65206, 1};
+
+void draw_detection(BoxPrediction &p, uint16_t * buffer, int width, int height) {
+    if (p.confidence < 0.7) { return; }   // confidence threshold, adjust as needed
+    int color = colors[p.id % num_colors];
+    for (int w = 0; w < 4; ++w) {
+        int x_min = clip(p.x_min * width + w, width - 1);
+        int y_min = clip(p.y_min * height + w, height - 1);
+        int x_max = clip(p.x_max * width + w, width - 1);
+        int y_max = clip(p.y_max * height + w, height - 1);
+        dl::image::draw_hollow_rectangle(buffer, height, width, x_min, y_min, x_max, y_max, color_red);
+    }
+}
+
+constexpr int lcd_width = 240;
+constexpr int lcd_height = 240;
+constexpr int lcd_display_height = 180;  // For 4:3 aspect ratio
+camera_fb_t * lcd_buffer = nullptr;
+
+camera_fb_t *frame = NULL;
+
+void resize_for_display_and_free_framebuffer(void *_) {
+    dl::image::resize_image_nearest(
+        reinterpret_cast<uint16_t *>(frame->buf), {(int)frame->height, (int)frame->width, 1},
+        reinterpret_cast<uint16_t *>(lcd_buffer->buf), {lcd_display_height, lcd_width, 1}
+    );
+
+    // The input resizing is done (in network) and so is the LCD resizing (above),
+    // now we can return the framebuffer such that the camera can get a new frame.
+    esp_camera_fb_return(frame);
+}
+
+static const char *TAG = "plumerai_people_detection";
+
+static QueueHandle_t xQueueFrameI = NULL;
+static QueueHandle_t xQueueEvent = NULL;
+static QueueHandle_t xQueueFrameO = NULL;
+static QueueHandle_t xQueueResult = NULL;
+
+static bool gEvent = true;
+static bool gReturnFB = true;
+
+static void task_process_handler(void *arg)
+{
+    lcd_buffer = reinterpret_cast<camera_fb_t *>(heap_caps_aligned_alloc(16, sizeof(camera_fb_t), MALLOC_CAP_8BIT));
+    lcd_buffer->height = lcd_height;
+    lcd_buffer->width = lcd_width;
+    lcd_buffer->len = 2 * lcd_buffer->width * lcd_buffer->height;
+    lcd_buffer->format = PIXFORMAT_RGB565;
+    ESP_LOGI(TAG, "Allocating %d bytes LCD buffer in external PSRAM", lcd_buffer->len);
+    lcd_buffer->buf = reinterpret_cast<uint8_t *>(heap_caps_aligned_alloc(16, lcd_buffer->len, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM));
+    for (int i = 0; i < lcd_buffer->len; ++i) { lcd_buffer->buf[i] = 0; }
+
+    ESP_LOGI(TAG, "Reserving %d bytes of tensor arena in internal RAM", TENSOR_ARENA_SIZE);
+    auto tensor_arena = reinterpret_cast<unsigned char *>(heap_caps_aligned_alloc(16, TENSOR_ARENA_SIZE, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL));
+    if (tensor_arena == nullptr) { ESP_LOGI(TAG, "Error: could not allocate tensor arena"); }
+
+    ESP_LOGI(TAG, "Initializing the Plumerai People Detection");
+    auto error_code = PeopleDetectionMicroInit(tensor_arena);
+    if (error_code != 0) { ESP_LOGI(TAG, "Error: could not initialize Plumerai People Detection"); }
+
+    PeopleDetectionReadDataCallback(resize_for_display_and_free_framebuffer);
+
+    constexpr int max_detections = 20;
+    BoxPrediction predictions[max_detections];
+
+    float delta_t_s = 1.0f;  // will be set below properly
+    auto prev_end_time = esp_timer_get_time();
+
+    while (true)
+    {
+        if (gEvent)
+        {
+            bool is_detected = false;
+            if (xQueueReceive(xQueueFrameI, &frame, portMAX_DELAY))
+            {
+                int num_results = 0;
+                error_code = PeopleDetectionMicroProcessFrame(predictions, max_detections, &num_results, delta_t_s, frame->buf);
+                if (error_code != 0) { ESP_LOGI(TAG, "Error: could not process a frame using Plumerai People Detection"); }
+                ESP_LOGI(TAG, "Detected %d person(s)", num_results);
+
+                for (int result_id = 0; result_id < num_results; ++result_id) {
+                    draw_detection(predictions[result_id], reinterpret_cast<uint16_t *>(lcd_buffer->buf), lcd_width, lcd_display_height);
+                    is_detected = true;
+                }
+
+                auto time_since_last_update = esp_timer_get_time() - prev_end_time;
+                delta_t_s = static_cast<float>(time_since_last_update) / 1000000.0f;
+                prev_end_time = esp_timer_get_time();
+                ESP_LOGI(TAG, "Total speed of demo: %.3fms (%.1f FPS)", delta_t_s * 1000.f, 1.0f / delta_t_s);
+            }
+
+            if (xQueueFrameO)
+            {
+                xQueueSend(xQueueFrameO, &lcd_buffer, portMAX_DELAY);
+            }
+            else if (gReturnFB)
+            {
+                esp_camera_fb_return(frame);
+            }
+            else
+            {
+                free(frame);
+            }
+
+            if (xQueueResult)
+            {
+                xQueueSend(xQueueResult, &is_detected, portMAX_DELAY);
+            }
+        }
+    }
+}
+
+static void task_event_handler(void *arg)
+{
+    while (true)
+    {
+        xQueueReceive(xQueueEvent, &(gEvent), portMAX_DELAY);
+    }
+}
+
+void register_plumerai_people_detection(const QueueHandle_t frame_i,
+                                        const QueueHandle_t event,
+                                        const QueueHandle_t result,
+                                        const QueueHandle_t frame_o,
+                                        const bool camera_fb_return)
+{
+    xQueueFrameI = frame_i;
+    xQueueFrameO = frame_o;
+    xQueueEvent = event;
+    xQueueResult = result;
+    gReturnFB = camera_fb_return;
+
+    xTaskCreatePinnedToCore(task_process_handler, TAG, 8 * 1024, NULL, 5, NULL, 0);
+    if (xQueueEvent)
+        xTaskCreatePinnedToCore(task_event_handler, TAG, 4 * 1024, NULL, 5, NULL, 1);
+}
diff --git a/components/modules/ai/who_plumerai_people_detection.hpp b/components/modules/ai/who_plumerai_people_detection.hpp
new file mode 100644
index 0000000..e5e57ae
--- /dev/null
+++ b/components/modules/ai/who_plumerai_people_detection.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/queue.h"
+#include "freertos/task.h"
+#include "freertos/semphr.h"
+
+void register_plumerai_people_detection(QueueHandle_t frame_i,
+                                        QueueHandle_t event,
+                                        QueueHandle_t result,
+                                        QueueHandle_t frame_o = NULL,
+                                        const bool camera_fb_return = false);
diff --git a/components/modules/lcd/who_lcd.c b/components/modules/lcd/who_lcd.c
index 0e6ba59..eabb681 100644
--- a/components/modules/lcd/who_lcd.c
+++ b/components/modules/lcd/who_lcd.c
@@ -28,7 +28,7 @@ static void task_process_handler(void *arg)
             }
             else if (gReturnFB)
             {
-                esp_camera_fb_return(frame);
+                //esp_camera_fb_return(frame);  // done in `who_human_face_detection.cpp` instead
             }
             else
             {
diff --git a/components/screen/controller_driver/st7789/st7789.c b/components/screen/controller_driver/st7789/st7789.c
index 3ec4574..fb63274 100644
--- a/components/screen/controller_driver/st7789/st7789.c
+++ b/components/screen/controller_driver/st7789/st7789.c
@@ -77,6 +77,11 @@ static void lcd_st7789_init_reg(void)
     LCD_WRITE_CMD(0x3A);
     LCD_WRITE_DATA(0x05);
 
+    // Set proper RGB565 little-endianness
+    LCD_WRITE_CMD(0xB0);
+    LCD_WRITE_DATA(0x00);
+    LCD_WRITE_DATA(0xF8);
+
     LCD_WRITE_CMD(0xB2);
     LCD_WRITE_DATA(0x0C);
     LCD_WRITE_DATA(0x0C);
diff --git a/examples/human_face_detection/lcd/CMakeLists.txt b/examples/human_face_detection/lcd/CMakeLists.txt
index 221cbd3..f260609 100644
--- a/examples/human_face_detection/lcd/CMakeLists.txt
+++ b/examples/human_face_detection/lcd/CMakeLists.txt
@@ -5,4 +5,6 @@ cmake_minimum_required(VERSION 3.5)
 set(EXTRA_COMPONENT_DIRS ../../../components)
 add_compile_options(-fdiagnostics-color=always)
 include($ENV{IDF_PATH}/tools/cmake/project.cmake)
-project(human_face_detection_lcd)
+include_directories(${CMAKE_CURRENT_LIST_DIR}/plumerai_people_detection_micro_esp32/include)
+project(plumerai_people_detection_lcd)
+target_link_libraries(${PROJECT_NAME}.elf ${CMAKE_CURRENT_LIST_DIR}/plumerai_people_detection_micro_esp32/lib/esp32-s3/libplumerai_people_detection_micro.a)
diff --git a/examples/human_face_detection/lcd/main/app_main.cpp b/examples/human_face_detection/lcd/main/app_main.cpp
index 454d5d8..c1b3dd6 100755
--- a/examples/human_face_detection/lcd/main/app_main.cpp
+++ b/examples/human_face_detection/lcd/main/app_main.cpp
@@ -1,5 +1,5 @@
 #include "who_camera.h"
-#include "who_human_face_detection.hpp"
+#include "who_plumerai_people_detection.hpp"
 #include "who_lcd.h"
 
 static QueueHandle_t xQueueAIFrame = NULL;
@@ -10,7 +10,7 @@ extern "C" void app_main()
     xQueueAIFrame = xQueueCreate(2, sizeof(camera_fb_t *));
     xQueueLCDFrame = xQueueCreate(2, sizeof(camera_fb_t *));
 
-    register_camera(PIXFORMAT_RGB565, FRAMESIZE_240X240, 2, xQueueAIFrame);
-    register_human_face_detection(xQueueAIFrame, NULL, NULL, xQueueLCDFrame, false);
+    register_camera(PIXFORMAT_RGB565, FRAMESIZE_VGA, 2, xQueueAIFrame);
+    register_plumerai_people_detection(xQueueAIFrame, NULL, NULL, xQueueLCDFrame, false);
     register_lcd(xQueueLCDFrame, NULL, true);
 }
