diff --git a/Application/src/commons/common/gui/FileChooser.cpp b/Application/src/commons/common/gui/FileChooser.cpp index 1ba01818f61351110667f362807e62bcde66a1c8..cf0fc52c52f781fca16aae8b09fe9b7989ce9c37 100644 --- a/Application/src/commons/common/gui/FileChooser.cpp +++ b/Application/src/commons/common/gui/FileChooser.cpp @@ -32,6 +32,7 @@ FileChooser::FileChooser(const file::Path& start, const std::string& extension, _graph->wrap_object(*_overall); if(_on_update) _on_update(*_graph); + _graph->draw_log_messages(); if(!_selected_file.empty()) { @@ -174,6 +175,7 @@ void FileChooser::set_tabs(const std::vector<Settings>& tabs) { _tabs[tab.name] = tab; auto button = new Button(tab.name, Bounds(0, 0, Base::default_text_bounds(tab.name).width + 20, 33)); + button->set_fill_clr(Color(100, 100, 100, 255)); button->set_toggleable(true); button->on_click([this, button](auto e){ if(button->toggled()) { @@ -209,6 +211,10 @@ void FileChooser::set_tabs(const std::vector<Settings>& tabs) { set_tab(""); } +void FileChooser::deselect() { + file_selected(0, ""); +} + void FileChooser::set_tab(std::string tab) { if(tab != _current_tab.name) { } else @@ -219,7 +225,7 @@ void FileChooser::set_tab(std::string tab) { if(_on_tab_change) _on_tab_change(_current_tab.name); - file_selected(0, ""); + deselect(); } else if(!_tabs.count(tab)) { auto str = Meta::toStr(_tabs); @@ -228,15 +234,17 @@ void FileChooser::set_tab(std::string tab) { _current_tab = _tabs.at(tab); if(_on_tab_change) _on_tab_change(_current_tab.name); - file_selected(0, ""); + deselect(); } for(auto &ptr : tabs_elements) { if(static_cast<Button*>(ptr.get())->txt() != tab) { static_cast<Button*>(ptr.get())->set_toggle(false); static_cast<Button*>(ptr.get())->set_clickable(true); - } else + } else { + static_cast<Button*>(ptr.get())->set_toggle(true); static_cast<Button*>(ptr.get())->set_clickable(false); + } } change_folder(_path); diff --git a/Application/src/commons/common/gui/FileChooser.h b/Application/src/commons/common/gui/FileChooser.h index 4310e21cda5ab806899b78b80d74802b453edea9..5cfe6d01662702971f579f9e1a93f7f5eead0a41 100644 --- a/Application/src/commons/common/gui/FileChooser.h +++ b/Application/src/commons/common/gui/FileChooser.h @@ -87,6 +87,7 @@ public: void on_open(std::function<void(file::Path)>&& fn) { _on_open = std::move(fn); } void on_tab_change(std::function<void(std::string)>&& fn) { _on_tab_change = std::move(fn); } void set_validity_check(std::function<bool(file::Path)>&& fn) { _validity = std::move(fn); } + void deselect(); private: void file_selected(size_t i, file::Path path); diff --git a/Application/src/commons/common/gui/types/Button.cpp b/Application/src/commons/common/gui/types/Button.cpp index 084cfcce0de58a666c21603594f6e9e3cc6c5d6c..067a43ac425f57efe902ceb7a1ea8a8ede2ba26c 100644 --- a/Application/src/commons/common/gui/types/Button.cpp +++ b/Application/src/commons/common/gui/types/Button.cpp @@ -44,7 +44,7 @@ namespace gui { if(hovered()) { clr = clr.brighten(0.7); } else - clr = clr.brighten(0.5); + clr = clr.brighten(0.3); } else if(hovered()) { clr = clr.brighten(1.5); diff --git a/Application/src/commons/common/gui/types/Layout.cpp b/Application/src/commons/common/gui/types/Layout.cpp index 8a8b4d8a4cde32445ff4592ba3515824ca338a95..e85bf4127391aec490958b60f6c8dcbfca2d92dd 100644 --- a/Application/src/commons/common/gui/types/Layout.cpp +++ b/Application/src/commons/common/gui/types/Layout.cpp @@ -89,11 +89,10 @@ namespace gui { auto it = std::find(_objects.begin(), _objects.end(), ptr); if(it == _objects.end()) return; + _objects.erase(it); Entangled::remove_child(ptr.get()); - _objects.erase(it); - set_content_changed(true); update(); } diff --git a/Application/src/commons/common/video/Video.cpp b/Application/src/commons/common/video/Video.cpp index 9943a8027f39ccf21b542afae2526a93c836e9ac..462f66d2f44e167b94813e8dfe6f86197a00cc4a 100644 --- a/Application/src/commons/common/video/Video.cpp +++ b/Application/src/commons/common/video/Video.cpp @@ -108,8 +108,8 @@ int Video::framerate() const { * Length (in frames) of the current video. * @return int */ -int Video::length() const { - return (int)_cap->get(cv::CAP_PROP_FRAME_COUNT); +int64_t Video::length() const { + return (int64_t)_cap->get(cv::CAP_PROP_FRAME_COUNT); } /** @@ -137,7 +137,7 @@ const cv::Size& Video::size() const { * @param index * @return cv::Mat */ -void Video::frame(long_t index, cv::Mat& frame, bool lazy) { +void Video::frame(int64_t index, cv::Mat& frame, bool lazy) { /*if(_frames.count(index)) { return _frames.at(index); }*/ diff --git a/Application/src/commons/common/video/Video.h b/Application/src/commons/common/video/Video.h index 7611f0657d0a8419b5521526243280d6bae44a29..21a623f756d23e85c3d54ef4c7b204dcc9f91399 100644 --- a/Application/src/commons/common/video/Video.h +++ b/Application/src/commons/common/video/Video.h @@ -56,7 +56,7 @@ public: /** * Length (in frames) of the current video. */ - int length() const; + int64_t length() const; /** * True if a video is loaded. @@ -78,7 +78,7 @@ public: * will be set instead */ //void frame(long_t index, cv::Mat& output, bool lazy = false); - void frame(long_t index, cv::Mat& output, bool lazy = false); + void frame(int64_t index, cv::Mat& output, bool lazy = false); /** * Sets a callback function for video playback. If a new frame is ready, this @@ -143,7 +143,7 @@ public: void clear(); private: - long_t _last_index; + int64_t _last_index; /** * The intrinsic parameters of the camera the video was recorded with. diff --git a/Application/src/tracker/VideoOpener.cpp b/Application/src/tracker/VideoOpener.cpp index 341c8856b26e06c91f23c1c503825f49b2642791..8fd00be25f29bc126ab39f6ba4ef76eb9c2da5d4 100644 --- a/Application/src/tracker/VideoOpener.cpp +++ b/Application/src/tracker/VideoOpener.cpp @@ -132,8 +132,14 @@ VideoOpener::VideoOpener() { _raw_settings->set_children(objects); + _loading_text = std::make_shared<gui::Text>("generating average", Vec2(100,0), Cyan, gui::Font(0.5)); + _raw_description = std::make_shared<gui::StaticText>("Info", Vec2(), Size2(400, -1), Font(0.6)); - _raw_info->set_children({Layout::Ptr(std::make_shared<Text>("Preview", Vec2(), White, gui::Font(0.8, Style::Bold))), _screenshot, _raw_description}); + _raw_info->set_children({ + Layout::Ptr(std::make_shared<Text>("Preview", Vec2(), White, gui::Font(0.8, Style::Bold))), + _screenshot, + _raw_description + }); _horizontal_raw->set_children({_raw_settings, _raw_info}); _horizontal_raw->set_policy(gui::HorizontalLayout::TOP); @@ -247,7 +253,6 @@ VideoOpener::VideoOpener() { const double max_width = 500; auto ratio = max_width / _screenshot_previous_size; - Debug("%f (%f / %f)", ratio, max_width, _screenshot_previous_size); _screenshot->set_scale(Vec2(ratio)); _raw_info->auto_size(Margin{0, 0}); @@ -255,6 +260,16 @@ VideoOpener::VideoOpener() { _horizontal_raw->auto_size(Margin{0, 0}); } } + + if(!_buffer->_terminated_background_task) { + if(!contains(_raw_info->children(), (Drawable*)_loading_text.get())) + _raw_info->add_child(2, _loading_text); + //_loading_text->set_pos(_screenshot->pos()); + _loading_text->set_txt("generating average ("+Meta::toStr(min(TEMP_SETTING(average_samples).value<int>(), (int)_buffer->_number_samples.load()))+"/"+TEMP_SETTING(average_samples).get().valueString()+")"); + + } else if(contains(_raw_info->children(), (Drawable*)_loading_text.get())) { + _raw_info->remove_child(_loading_text); + } } }); @@ -305,43 +320,35 @@ void VideoOpener::BufferedVideo::restart_background() { resize_image(img, 500 / double(max(img.cols, img.rows))); img.convertTo(_background_image, CV_32FC1); - _accumulator = std::make_unique<AveragingAccumulator<>>(TEMP_SETTING(averaging_method).value<averaging_method_t::Class>()); - _accumulator->add(img); - //_background_image.copyTo(_accumulator); - //_background_samples = 1; _background_video_index = 0; - //_accumulator = cv::Mat::zeros(img.rows, img.cols, CV_32FC1); + _accumulator = std::make_unique<AveragingAccumulator<>>(TEMP_SETTING(averaging_method).value<averaging_method_t::Class>()); + _accumulator->add(img); _background_thread = std::make_unique<std::thread>([this](){ + _terminated_background_task = false; + int step = max(1, int(_background_video->length() / max(2.0, double(TEMP_SETTING(average_samples).value<int>())))); - Debug("Start calculating background in %d steps", step); cv::Mat flt, img; + _number_samples = 0; while(!_terminate_background && _background_video_index+1+step < _background_video->length()) { _background_video_index += step; + _number_samples += 1; _background_video->frame(_background_video_index, img); if(max(img.cols, img.rows) > 500) resize_image(img, 500 / double(max(img.cols, img.rows))); - /*img.convertTo(flt, CV_32FC1); - if(!_accumulator.empty()) - cv::add(_accumulator, flt, _accumulator); - else - flt.copyTo(_accumulator); - ++_background_samples;*/ - _accumulator->add(img); - Debug("%d/%d (%d)", _background_video_index, _background_video->length(), step); auto image = _accumulator->finalize(); std::lock_guard guard(_frame_mutex); _background_copy = std::move(image); } - Debug("Done calculating background"); + _terminated_background_task = true; }); } @@ -370,15 +377,7 @@ void VideoOpener::BufferedVideo::open() { if(dt < _seconds_between_frames) continue; - _playback_index = _playback_index + 1; // loading is too slow... - - if((uint32_t)_playback_index.load() % 100 == 0) - Debug("Playback %.2fms / %.2fms ...", dt * 1000, _seconds_between_frames * 1000); - - if(dt > _seconds_between_frames) { - - } //else - //_playback_index = _playback_index + dt / _seconds_between_frames; + _playback_index = _playback_index + 1; _video_timer.reset(); if(_playback_index+1 >= _video->length()) @@ -458,11 +457,6 @@ void VideoOpener::select_file(const file::Path &p) { filename = filename.filename(); TEMP_SETTING(output_name) = filename; - if(TEMP_SETTING(output_name).value<file::Path>().empty()) { - Warning("No output filename given. Defaulting to 'video'."); - } else - Warning("Given empty filename, the program will default to using input basename '%S'.", &filename.str()); - _text_fields["output_name"]->update(); } @@ -490,7 +484,6 @@ void VideoOpener::select_file(const file::Path &p) { } auto ratio = max_width / _screenshot->size().max(); - Debug("%f (%f / %f)", ratio, max_width, _screenshot->size().max()); _screenshot->set_scale(Vec2(ratio)); _raw_info->auto_size(Margin{0, 0}); @@ -505,6 +498,7 @@ void VideoOpener::select_file(const file::Path &p) { cv::putText(img, "Cannot open video.", Vec2(50, 220), cv::FONT_HERSHEY_PLAIN, 1, White); _screenshot->set_source(std::make_unique<Image>(img)); _screenshot->set_scale(Vec2(1)); + _file_chooser->deselect(); _buffer = nullptr; } return; @@ -628,7 +622,7 @@ void VideoOpener::select_file(const file::Path &p) { _load_results_checkbox = nullptr; auto path = Output::TrackingResults::expected_filename(); if(path.exists()) { - children.push_back( Layout::Ptr(std::make_shared<Checkbox>(Vec2(), "load results", false, gui::Font(0.7, Style::Bold))) ); + children.push_back( Layout::Ptr(std::make_shared<Checkbox>(Vec2(), "load results", false, gui::Font(0.6))) ); _load_results_checkbox = dynamic_cast<Checkbox*>(children.back().get()); } else children.push_back( Layout::Ptr(std::make_shared<Text>("No loadable results found.", Vec2(), Gray, gui::Font(0.7, Style::Bold))) ); diff --git a/Application/src/tracker/VideoOpener.h b/Application/src/tracker/VideoOpener.h index 5e86854a6fae95068503d87909b251118bcdedc2..a1bc47d955654241255a3a2174d8125159c33489 100644 --- a/Application/src/tracker/VideoOpener.h +++ b/Application/src/tracker/VideoOpener.h @@ -36,6 +36,9 @@ public: //uint64_t _background_samples = 0; uint64_t _background_video_index = 0; + std::atomic<bool> _terminated_background_task; + std::atomic<size_t> _number_samples; + std::mutex _frame_mutex; std::mutex _video_mutex; @@ -72,6 +75,7 @@ public: gui::derived_ptr<gui::VerticalLayout> _extra, _infos, _raw_info, _raw_settings; gui::derived_ptr<gui::HorizontalLayout> _horizontal, _horizontal_raw; gui::derived_ptr<gui::ExternalImage> _screenshot; + gui::derived_ptr<gui::Text> _loading_text; gui::derived_ptr<gui::StaticText> _raw_description; double _screenshot_previous_size;