From f36864914fde7e19779bce65706b4dc89440ac98 Mon Sep 17 00:00:00 2001 From: Sebastian Hahta <joseha@utu.fi> Date: Wed, 8 Jan 2020 11:47:12 +0200 Subject: [PATCH] player screenshots and bug fixes --- applications/player/src/main.cpp | 176 ++++++++++++++++++++----------- 1 file changed, 117 insertions(+), 59 deletions(-) diff --git a/applications/player/src/main.cpp b/applications/player/src/main.cpp index 2741cac2e..6fd7c54ce 100644 --- a/applications/player/src/main.cpp +++ b/applications/player/src/main.cpp @@ -11,22 +11,35 @@ #include <Eigen/Eigen> +const static std::string help[] = { + "Esc", "close", + "0-9", "change source", + "D", "toggle depth", + "S", "save screenshot", +}; + +std::string time_now_string() { + char timestamp[18]; + std::time_t t=std::time(NULL); + std::strftime(timestamp, sizeof(timestamp), "%F-%H%M%S", std::localtime(&t)); + return std::string(timestamp); +} + using ftl::codecs::codec_t; using ftl::codecs::Channel; -static ftl::codecs::Decoder *decoder; - +static std::map<Channel, ftl::codecs::Decoder*> decoders; -static void createDecoder(const ftl::codecs::Packet &pkt) { - if (decoder) { - if (!decoder->accepts(pkt)) { - ftl::codecs::free(decoder); +static void createDecoder(const Channel channel, const ftl::codecs::Packet &pkt) { + if (decoders[channel]) { + if (!decoders[channel]->accepts(pkt)) { + ftl::codecs::free(decoders[channel]); } else { return; } } - decoder = ftl::codecs::allocateDecoder(pkt); + decoders[channel] = ftl::codecs::allocateDecoder(pkt); } static void visualizeDepthMap( const cv::Mat &depth, cv::Mat &out, @@ -56,28 +69,34 @@ static std::string nameForCodec(ftl::codecs::codec_t c) { } int main(int argc, char **argv) { - std::string filename(argv[1]); - LOG(INFO) << "Playing: " << filename; + std::string filename(argv[1]); + LOG(INFO) << "Playing: " << filename; auto root = ftl::configure(argc, argv, "player_default"); std::ifstream f; - f.open(filename); - if (!f.is_open()) LOG(ERROR) << "Could not open file"; + f.open(filename); + if (!f.is_open()) LOG(ERROR) << "Could not open file"; - ftl::codecs::Reader r(f); - if (!r.begin()) LOG(ERROR) << "Bad ftl file"; + ftl::codecs::Reader r(f); + if (!r.begin()) LOG(ERROR) << "Bad ftl file"; - LOG(INFO) << "Playing..."; + LOG(INFO) << "Playing..."; - int current_stream = 0; - int current_channel = 0; + int current_stream = 0; + int current_channel = 0; int stream_mask = 0; + + static volatile bool screenshot; + static int64_t screenshot_ts; + static cv::Mat screenshot_color; + static cv::Mat screenshot_depth; + std::vector<std::bitset<128>> channel_mask; ftl::timer::add(ftl::timer::kTimerMain, [¤t_stream,¤t_channel,&r,&stream_mask,&channel_mask](int64_t ts) { - bool res = r.read(ts, [¤t_stream,¤t_channel,&r,&stream_mask,&channel_mask](const ftl::codecs::StreamPacket &spkt, const ftl::codecs::Packet &pkt) { + bool res = r.read(ts, [ts, ¤t_stream,¤t_channel,&r,&stream_mask,&channel_mask](const ftl::codecs::StreamPacket &spkt, const ftl::codecs::Packet &pkt) { if (!(stream_mask & (1 << spkt.streamID))) { stream_mask |= 1 << spkt.streamID; LOG(INFO) << " - Stream found (" << (int)spkt.streamID << ")"; @@ -95,56 +114,95 @@ int main(int argc, char **argv) { LOG(INFO) << " - Blocks = " << (int)pkt.block_total; } - if (spkt.streamID == current_stream) { + if (spkt.streamID != current_stream) { return; } - if (pkt.codec == codec_t::POSE) { - Eigen::Matrix4d p = Eigen::Map<Eigen::Matrix4d>((double*)pkt.data.data()); - LOG(INFO) << "Have pose: " << p; - return; - } + if (pkt.codec == codec_t::POSE) { + Eigen::Matrix4d p = Eigen::Map<Eigen::Matrix4d>((double*)pkt.data.data()); + LOG(INFO) << "Have pose: " << p; + return; + } - if (pkt.codec == codec_t::CALIBRATION) { - ftl::rgbd::Camera *camera = (ftl::rgbd::Camera*)pkt.data.data(); - LOG(INFO) << "Have calibration: " << camera->fx; - return; - } - - if (spkt.channel != static_cast<ftl::codecs::Channel>(current_channel)) return; + if (pkt.codec == codec_t::CALIBRATION) { + ftl::rgbd::Camera *camera = (ftl::rgbd::Camera*)pkt.data.data(); + LOG(INFO) << "Have calibration: " << camera->fx; + return; + } + + auto channel = static_cast<ftl::codecs::Channel>(current_channel); + if (pkt.codec == ftl::codecs::codec_t::MSGPACK) { return; } + //LOG(INFO) << "Reading packet: (" << (int)spkt.streamID << "," << (int)spkt.channel << ") " << (int)pkt.codec << ", " << (int)pkt.definition; + + cv::cuda::GpuMat gframe(cv::Size(ftl::codecs::getWidth(pkt.definition),ftl::codecs::getHeight(pkt.definition)), (spkt.channel == Channel::Depth) ? CV_32F : CV_8UC3); + cv::Mat frame; + createDecoder(spkt.channel, pkt); + + try { + decoders[spkt.channel]->decode(pkt, gframe); + gframe.download(frame); + } catch (std::exception &e) { + LOG(INFO) << "Decoder exception: " << e.what(); + } - //LOG(INFO) << "Reading packet: (" << (int)spkt.streamID << "," << (int)spkt.channel << ") " << (int)pkt.codec << ", " << (int)pkt.definition; + if (screenshot) { + if (!screenshot_depth.empty() && !screenshot_color.empty()) { + std::string fname = time_now_string(); + LOG(INFO) << "Screenshot saved: " << fname; + cv::imwrite(fname + "-depth.tiff", screenshot_depth); + cv::imwrite(fname + "-color.tiff", screenshot_color); + screenshot = false; + screenshot_color = cv::Mat(); + screenshot_depth = cv::Mat(); + screenshot_ts = 0; + } + else { + if (screenshot_ts != ts) { + screenshot_ts = ts; + screenshot_color = cv::Mat(); + screenshot_depth = cv::Mat(); + } + if (spkt.channel == Channel::Colour) { + frame.copyTo(screenshot_color); + } + else if (spkt.channel == Channel::Depth) { + frame.copyTo(screenshot_depth); + } + } + } - cv::cuda::GpuMat gframe(cv::Size(ftl::codecs::getWidth(pkt.definition),ftl::codecs::getHeight(pkt.definition)), (spkt.channel == Channel::Depth) ? CV_32F : CV_8UC3); - cv::Mat frame; - createDecoder(pkt); + if (spkt.channel != channel) return; - try { - decoder->decode(pkt, gframe); - gframe.download(frame); - } catch (std::exception &e) { - LOG(INFO) << "Decoder exception: " << e.what(); + if (!frame.empty()) { + if (spkt.channel == Channel::Depth) { + visualizeDepthMap(frame, frame, 8.0f); } + double time = (double)(spkt.timestamp - r.getStartTime()) / 1000.0; + cv::putText(frame, std::string("Time: ") + std::to_string(time) + std::string("s"), cv::Point(10,20), cv::FONT_HERSHEY_PLAIN, 1, cv::Scalar(0,0,255)); - if (!frame.empty()) { - if (spkt.channel == Channel::Depth) { - visualizeDepthMap(frame, frame, 8.0f); - } - double time = (double)(spkt.timestamp - r.getStartTime()) / 1000.0; - cv::putText(frame, std::string("Time: ") + std::to_string(time) + std::string("s"), cv::Point(10,20), cv::FONT_HERSHEY_PLAIN, 1, cv::Scalar(0,0,255)); - cv::imshow("Player", frame); - } else { - frame.create(cv::Size(600,600), CV_8UC3); - cv::imshow("Player", frame); + // hotkey help text + for (int i = 0; i < std::size(help); i += 2) { + cv::putText(frame, help[i], cv::Point(10, 40+(i/2)*14), cv::FONT_HERSHEY_PLAIN, 1, cv::Scalar(64,64,255)); + cv::putText(frame, help[i+1], cv::Point(50, 40+(i/2)*14), cv::FONT_HERSHEY_PLAIN, 1, cv::Scalar(64,64,255)); } - int key = cv::waitKey(1); - if (key >= 48 && key <= 57) { - current_stream = key - 48; - } else if (key == 'd') { - current_channel = (current_channel == 0) ? 1 : 0; - } else if (key == 'r') { - current_channel = (current_channel == 0) ? 2 : 0; - } else if (key == 27) { - ftl::timer::stop(false); + + cv::imshow("Player", frame); + } else { + frame.create(cv::Size(600,600), CV_8UC3); + cv::imshow("Player", frame); + } + int key = cv::waitKey(1); + if (key >= 48 && key <= 57) { + int new_stream = key - 48; + if ((0 <= new_stream) && (new_stream < channel_mask.size())) { + current_stream = new_stream; } + } else if (key == 'd') { + current_channel = (current_channel == 0) ? 1 : 0; + } else if (key == 'r') { + current_channel = (current_channel == 0) ? 2 : 0; + } else if (key == 27) { + ftl::timer::stop(false); + } else if (key == 115) { + screenshot = true; } }); if (!res) ftl::timer::stop(false); @@ -153,7 +211,7 @@ int main(int argc, char **argv) { ftl::timer::start(true); - r.end(); + r.end(); ftl::running = false; return 0; -- GitLab