diff --git a/applications/gui/src/media_panel.cpp b/applications/gui/src/media_panel.cpp index 83bad8511a287e35454ef61050e01f6a2c4d39b3..2e0f5fae21e2bb0f45492b0885ff68afe747adba 100644 --- a/applications/gui/src/media_panel.cpp +++ b/applications/gui/src/media_panel.cpp @@ -17,6 +17,7 @@ MediaPanel::MediaPanel(ftl::gui::Screen *screen) : nanogui::Window(screen, ""), using namespace nanogui; paused_ = false; + writer_ = nullptr; setLayout(new BoxLayout(Orientation::Horizontal, Alignment::Middle, 5, 10)); @@ -54,8 +55,24 @@ MediaPanel::MediaPanel(ftl::gui::Screen *screen) : nanogui::Window(screen, ""), button = new Button(this, "", ENTYPO_ICON_CONTROLLER_RECORD); button->setFlags(Button::ToggleButton); button->setChangeCallback([this,button](bool state) { - if (state) button->setTextColor(nanogui::Color(1.0f,0.1f,0.1f,1.0f)); - else button->setTextColor(nanogui::Color(1.0f,1.0f,1.0f,1.0f)); + if (state){ + auto *cam = screen_->activeCamera(); + + button->setTextColor(nanogui::Color(1.0f,0.1f,0.1f,1.0f)); + char timestamp[18]; + std::time_t t=std::time(NULL); + std::strftime(timestamp, sizeof(timestamp), "%F-%H%M%S", std::localtime(&t)); + writer_ = new ftl::rgbd::SnapshotStreamWriter(std::string(timestamp) + ".tar.gz", 1000 / 25); + writer_->addSource(cam->source()); + writer_->start(); + } else { + button->setTextColor(nanogui::Color(1.0f,1.0f,1.0f,1.0f)); + if (writer_) { + writer_->stop(); + delete writer_; + writer_ = nullptr; + } + } //if (state) ... start //else ... stop }); @@ -92,12 +109,10 @@ MediaPanel::MediaPanel(ftl::gui::Screen *screen) : nanogui::Window(screen, ""), auto writer = ftl::rgbd::SnapshotWriter(std::string(timestamp) + ".tar.gz"); cv::Mat rgb, depth; cam->source()->getFrames(rgb, depth); - if (!writer.addCameraRGBD( + if (!writer.addCameraParams("0", cam->source()->getPose(), cam->source()->parameters()) || !writer.addCameraRGBD( "0", // TODO rgb, - depth, - cam->source()->getPose(), - cam->source()->parameters() + depth )) { LOG(ERROR) << "Snapshot failed"; } diff --git a/applications/gui/src/media_panel.hpp b/applications/gui/src/media_panel.hpp index 0f17bd340ab0b5b7e8881ff98ccd95021233f77d..c65c48770fe4523e5c4847ca63a50a60f0af918d 100644 --- a/applications/gui/src/media_panel.hpp +++ b/applications/gui/src/media_panel.hpp @@ -4,6 +4,11 @@ #include <nanogui/window.h> namespace ftl { + +namespace rgbd { +class SnapshotStreamWriter; +} + namespace gui { class Screen; @@ -16,6 +21,7 @@ class MediaPanel : public nanogui::Window { private: ftl::gui::Screen *screen_; bool paused_; + ftl::rgbd::SnapshotStreamWriter *writer_; }; } diff --git a/applications/gui/src/src_window.cpp b/applications/gui/src/src_window.cpp index 8a0f93da2f2663fb14c956d6867a2ead6641d314..1242855738c87bae915d00bb48e8b788744f71a4 100644 --- a/applications/gui/src/src_window.cpp +++ b/applications/gui/src/src_window.cpp @@ -88,7 +88,7 @@ SourceWindow::SourceWindow(ftl::gui::Screen *screen) auto button_snapshot = new Button(this, "Snapshot", ENTYPO_ICON_IMAGES); button_snapshot->setCallback([this] { try { - char timestamp[18]; + /*char timestamp[18]; std::time_t t=std::time(NULL); std::strftime(timestamp, sizeof(timestamp), "%F-%H%M%S", std::localtime(&t)); auto writer = ftl::rgbd::SnapshotWriter(std::string(timestamp) + ".tar.gz"); diff --git a/components/rgbd-sources/include/ftl/rgbd/snapshot.hpp b/components/rgbd-sources/include/ftl/rgbd/snapshot.hpp index 9643b1312b59ba068e300bc304a01c3f62d5d955..edec6150217a6655021b94d49ef36d6018d87374 100644 --- a/components/rgbd-sources/include/ftl/rgbd/snapshot.hpp +++ b/components/rgbd-sources/include/ftl/rgbd/snapshot.hpp @@ -3,14 +3,17 @@ #define _FTL_RGBD_SNAPSHOT_HPP_ #include <loguru.hpp> +#include <thread> #include <opencv2/opencv.hpp> #include <Eigen/Eigen> #include <opencv2/core/eigen.hpp> +#include <ftl/rgbd/source.hpp> #include <ftl/rgbd/camera.hpp> +#include <atomic> #include <archive.h> #include <archive_entry.h> @@ -24,7 +27,8 @@ public: explicit SnapshotWriter(const std::string &filename); ~SnapshotWriter(); - bool addCameraRGBD(const std::string &name, const cv::Mat &rgb, const cv::Mat &depth, const Eigen::Matrix4d &pose, const ftl::rgbd::Camera ¶ms); + bool addCameraParams(const std::string &name, const Eigen::Matrix4d &pose, const ftl::rgbd::Camera ¶ms); + bool addCameraRGBD(const std::string &name, const cv::Mat &rgb, const cv::Mat &depth); bool addMat(const std::string &name, const cv::Mat &mat, const std::string &format="tiff"); bool addEigenMatrix4d(const std::string &name, const Eigen::Matrix4d &m, const std::string &format="pfm"); bool addFile(const std::string &name, const std::vector<uchar> &buf); @@ -35,7 +39,28 @@ private: struct archive_entry *entry_; }; +class SnapshotStreamWriter { +public: + SnapshotStreamWriter(const std::string &filename, int delay); + ~SnapshotStreamWriter(); + void addSource(ftl::rgbd::Source* src); + void start(); + void stop(); + +private: + std::atomic<bool> run_; + bool finished_; + int delay_; + + std::vector<ftl::rgbd::Source*> sources_; + SnapshotWriter writer_; + std::thread thread_; + + void run(); +}; + struct SnapshotEntry { + long t; cv::Mat rgb; cv::Mat depth; Eigen::Matrix4d pose; diff --git a/components/rgbd-sources/src/snapshot.cpp b/components/rgbd-sources/src/snapshot.cpp index 5599364c6508184c57651d7c46ca54951ac0d4ab..23c9d218b2e72328ee15247906dfae9f6dc2386f 100644 --- a/components/rgbd-sources/src/snapshot.cpp +++ b/components/rgbd-sources/src/snapshot.cpp @@ -124,11 +124,8 @@ bool SnapshotWriter::addEigenMatrix4d(const string &name, const Matrix4d &m, con return addMat(name, tmp, format); } -bool SnapshotWriter::addCameraRGBD(const string &name, const Mat &rgb, const Mat &depth, - const Matrix4d &pose, const Camera ¶ms) { +bool SnapshotWriter::addCameraParams(const string &name, const Matrix4d &pose, const Camera ¶ms) { bool retval = true; - retval &= addMat(name + "-RGB", rgb); - retval &= addMat(name + "-D", depth); retval &= addEigenMatrix4d(name + "-POSE", pose); nlohmann::json j; @@ -138,6 +135,65 @@ bool SnapshotWriter::addCameraRGBD(const string &name, const Mat &rgb, const Mat return retval; } +bool SnapshotWriter::addCameraRGBD(const string &name, const Mat &rgb, const Mat &depth) { + bool retval = true; + cv::Mat tdepth; + depth.convertTo(tdepth, CV_16SC1, 16.0f*10.0f); + retval &= addMat(name + "-RGB", rgb, "jpg"); + retval &= addMat(name + "-D", tdepth, "png"); + return retval; +} + +SnapshotStreamWriter::SnapshotStreamWriter(const string &filename, int delay) : + run_(false), finished_(false), writer_(filename), delay_(delay) {} + +SnapshotStreamWriter::~SnapshotStreamWriter() { + +} + +void SnapshotStreamWriter::addSource(ftl::rgbd::Source *src) { + writer_.addCameraParams(std::to_string(sources_.size()), src->getPose(), src->parameters()); + sources_.push_back(src); +} + +void SnapshotStreamWriter::run() { + vector<Mat> rgb(sources_.size()); + vector<Mat> depth(sources_.size()); + + while(run_) { + auto now = std::chrono::system_clock::now(); + auto duration = now.time_since_epoch(); + auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count(); + + for(size_t i = 0; i < sources_.size(); ++i) { + sources_[i]->getFrames(rgb[i], depth[i]); + } + + for(size_t i = 0; i < sources_.size(); ++i) { + writer_.addCameraRGBD(std::to_string(ms) + "-" + std::to_string(i), rgb[i], depth[i]); + } + + std::this_thread::sleep_for(std::chrono::milliseconds(delay_)); + } + + run_ = false; + finished_ = true; +} + +void SnapshotStreamWriter::start() { + if (run_ || finished_) return; + run_ = true; + thread_ = std::thread([this] { run(); }); +} + + +void SnapshotStreamWriter::stop() { + bool wasrunning = run_; + run_ = false; + if (wasrunning) thread_.join(); +} + + SnapshotReader::SnapshotReader(const string &filename) { archive_ = archive_read_new();