Program Listing for File pose_worker.hpp#
↰ Return to documentation for file (src/analysis/pose_worker.hpp)
#pragma once
#include <QImage>
#include <QObject>
#include <QVariantList>
#include <memory>
namespace mosaic {
// Runs the Python pose-estimation subprocess and provides real-time keypoints.
//
// Start the worker once at app startup (or when pose overlay is first enabled).
// Submit BGR preview frames via submit_frame(); receive keypoints via pose_ready().
//
// The subprocess is expected at python/pose/frame_server.py (relative to exe dir,
// or set via MOSAIC_PYTHON env var for the interpreter path).
class PoseWorker : public QObject {
Q_OBJECT
public:
explicit PoseWorker(QObject* parent = nullptr);
~PoseWorker() override;
// Start the Python subprocess. Returns false if the interpreter is not found.
// interpeter: path to the Python executable inside the venv (or system Python).
bool start(const QString& interpreter, const QString& scriptPath);
void stop();
[[nodiscard]] bool is_running() const;
// Pausing does NOT tear down the subprocess — it just makes submit_frame()
// a no-op, so the process idles on a blocking stdin read (free) instead of
// paying subprocess-restart cost every time recording starts/stops. Used
// to free up CPU for the 6-camera grab/encode pipeline while a real
// recording is in progress (see MainWindow's RecordManager wiring).
void set_paused(bool paused);
[[nodiscard]] bool is_paused() const;
public slots:
void submit_frame(int cameraIndex, QImage frame);
signals:
// keypoints is a QVariantList of QVariantMap: {x, y, z, visibility, name}
void pose_ready(int cameraIndex, QVariantList keypoints);
// gazeData is a QVariantMap: {face_box:{x,y,w,h}, left_iris:{x,y},
// right_iris:{x,y}, gaze_dx, gaze_dy}
void gaze_ready(int cameraIndex, QVariantMap gazeData);
void process_error(QString message);
void paused_changed(bool paused);
private:
struct Impl;
std::unique_ptr<Impl> d;
};
} // namespace mosaic