ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
face.cpp
Go to the documentation of this file.
1#include <emscripten/bind.h>
2extern "C" {
5}
6#include <array>
7#include <cstddef>
8
11
12static face_follow_state_t state;
13static std::array<unsigned char, FACE_FOLLOW_DETECT_WIDTH * FACE_FOLLOW_DETECT_HEIGHT * 4> rgba;
14static std::array<unsigned char, FACE_FOLLOW_DETECT_WIDTH * FACE_FOLLOW_DETECT_HEIGHT * 3> bgr;
15static std::array<unsigned char, FACE_FOLLOW_RESULT_BUFFER_SIZE> results;
16static size_t face_count;
17
18static void reset_face() {
19 face_follow_init(&state);
20 face_count = 0;
21}
22
23static int detect_face(FacePixels pixels, int width, int height, double now) {
24 const size_t length = pixels["length"].as<size_t>();
26 length != static_cast<size_t>(width) * height * 4)
27 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid face detector image: %dx%d, %zu bytes", width, height, length);
28 emscripten::val(emscripten::typed_memory_view(length, rgba.data())).call<void>("set", pixels);
29 for (int i = 0; i < width * height; ++i) {
30 bgr[i * 3] = rgba[i * 4 + 2];
31 bgr[i * 3 + 1] = rgba[i * 4 + 1];
32 bgr[i * 3 + 2] = rgba[i * 4];
33 }
35 face_follow_detect(results.data(), bgr.data(), width, height, faces, FACE_FOLLOW_MAX_DETECTIONS, &face_count);
36 face_follow_observe(&state, faces, face_count, now);
37 return 0;
38}
39static FaceValues tick_face(double now, bool enabled) {
40 face_follow_tick(&state, now, enabled);
41 const std::array<float, 11> values = {state.crop.x,
42 state.crop.y,
43 state.crop.w,
44 state.crop.h,
45 state.face.x,
46 state.face.y,
47 state.face.w,
48 state.face.h,
49 static_cast<float>(state.detected && now - state.last_seen < 0.3),
50 static_cast<float>(face_count),
51 static_cast<float>(state.tracking && now - state.last_seen <= 0.7)};
52 emscripten::val result = emscripten::val::global("Float32Array").new_(values.size());
53 result.call<void>("set", emscripten::val(emscripten::typed_memory_view(values.size(), values.data())));
54 return FaceValues(result);
55}
56
57EMSCRIPTEN_BINDINGS(ascii_chat_face_follow) {
58 emscripten::register_type<FacePixels>("FacePixels", "Uint8ClampedArray");
59 emscripten::register_type<FaceValues>("FaceValues", "Float32Array");
60 emscripten::function("faceReset", &reset_face);
61 emscripten::function("faceDetect", &detect_face);
62 emscripten::function("faceTick", &tick_face);
63}
Synchronized per-thread pending error stacks and value snapshots. SET_ERRNO pushes,...
#define SET_ERRNO(code,...)
EMSCRIPTEN_BINDINGS(ascii_chat_face_follow)
Definition face.cpp:57
EMSCRIPTEN_DECLARE_VAL_TYPE(FacePixels)
void face_follow_detect(unsigned char *results, unsigned char *bgr, int width, int height, face_follow_detection_t *faces, size_t capacity, size_t *count)
void face_follow_tick(face_follow_state_t *state, double now, bool enabled)
void face_follow_init(face_follow_state_t *state)
Definition face_follow.c:13
void face_follow_observe(face_follow_state_t *state, const face_follow_detection_t *faces, size_t count, double now)
Definition face_follow.c:25
#define FACE_FOLLOW_DETECT_HEIGHT
Definition face_follow.h:5
#define FACE_FOLLOW_DETECT_WIDTH
Definition face_follow.h:4
#define FACE_FOLLOW_MAX_DETECTIONS
Definition face_follow.h:7
unsigned int height
Definition fft.c:23
unsigned int width
Definition fft.c:23
bool enabled
Is filtering active?
Definition grep.c:62
@ ERROR_INVALID_PARAM
face follow state keeps the values that move through the subsystem: crop, target, face,...
Definition face_follow.h:36