#pragma once #ifdef HAVE_OPENCV constexpr bool g_ps_move_tracking_supported = true; #else constexpr bool g_ps_move_tracking_supported = false; #endif struct ps_move_info { bool valid = false; f32 radius = 0.0f; f32 distance = 0.0f; u32 x_pos = 0; u32 y_pos = 0; u32 x_max = 0; u32 y_max = 0; }; template class ps_move_tracker { public: ps_move_tracker(); virtual ~ps_move_tracker(); void set_image_data(const void* buf, u64 size, u32 width, u32 height, s32 format); void init_workers(); void process_image(); void convert_image(s32 output_format); void process_hues(); void process_contours(ps_move_info& info, u32 index); void set_active(u32 index, bool active); void set_hue(u32 index, u16 hue); void set_hue_threshold(u32 index, u16 threshold); void set_saturation_threshold(u32 index, u16 threshold); void set_min_radius(f32 radius) { m_min_radius = radius; } void set_max_radius(f32 radius) { m_max_radius = radius; } void set_filter_small_contours(bool enabled = false) { m_filter_small_contours = enabled; } void set_show_all_contours(bool enabled = false) { m_show_all_contours = enabled; } void set_draw_contours(bool enabled = false) { m_draw_contours = enabled; } void set_draw_overlays(bool enabled = false) { m_draw_overlays = enabled; } const std::array& info() { return m_info; } const std::array& hues() { return m_hues; } const std::vector& rgba() { return m_image_rgba; } const std::vector& rgba_contours() { return m_image_rgba_contours; } const std::vector& hsv() { return m_image_hsv; } const std::vector& gray() { return m_image_gray; } const std::vector& binary(u32 index) { return ::at32(m_image_binary, index); } static std::tuple hsv_to_rgb(u16 hue, float saturation, float value); static std::tuple rgb_to_hsv(float r, float g, float b); private: struct ps_move_config { bool active = false; u16 hue = 0; u16 hue_threshold = 0; u16 saturation_threshold_u8 = 0; s16 min_hue = 0; s16 max_hue = 0; f32 saturation_threshold = 0.0f; void calculate_values(); }; u32 m_width = 0; u32 m_height = 0; s32 m_format = 0; f32 m_min_radius = 0.0f; f32 m_max_radius = 1.0f; bool m_filter_small_contours = true; bool m_show_all_contours = false; bool m_draw_contours = false; bool m_draw_overlays = false; std::vector m_image_data; std::vector m_image_rgba; std::vector m_image_rgba_contours; std::vector m_image_hsv; std::vector m_image_gray; std::array, CELL_GEM_MAX_NUM> m_image_hue_filtered{}; std::array, CELL_GEM_MAX_NUM> m_image_binary{}; std::array m_hues{}; std::array m_info{}; std::array m_config{}; std::array>>, CELL_GEM_MAX_NUM> m_workers{}; std::array, CELL_GEM_MAX_NUM> m_wake_up_workers{}; std::array, CELL_GEM_MAX_NUM> m_workers_finished{}; };