From 849e57fbf882aebdc3557d51a8e6a578678863dc Mon Sep 17 00:00:00 2001 From: Tristan Walter <twalter@orn.mpg.de> Date: Tue, 10 Nov 2020 17:35:06 +0100 Subject: [PATCH] * bump version to 1.0.5 * idx_t -> Idx_t and replacing all uint32_t/long_t I could find --- .../src/commons/common/gui/CrossPlatform.h | 8 +- Application/src/commons/common/gui/GLImpl.cpp | 4 +- .../src/commons/common/gui/IMGUIBase.cpp | 2 +- .../src/commons/common/gui/MetalImpl.mm | 6 +- .../src/commons/common/misc/metastring.h | 20 ++- Application/src/commons/common/types.h | 1 - Application/src/grabber/default_config.cpp | 2 +- Application/src/grabber/main.cpp | 6 +- Application/src/tracker/gui/DrawDataset.cpp | 22 +-- Application/src/tracker/gui/DrawDataset.h | 9 +- Application/src/tracker/gui/DrawFish.cpp | 4 +- Application/src/tracker/gui/DrawFish.h | 2 +- Application/src/tracker/gui/DrawMenu.cpp | 16 +-- Application/src/tracker/gui/GUICache.cpp | 24 ++-- Application/src/tracker/gui/GUICache.h | 32 ++--- .../src/tracker/gui/IdentityHeatmap.cpp | 6 +- Application/src/tracker/gui/InfoCard.cpp | 2 +- .../src/tracker/gui/RecognitionSummary.cpp | 4 +- Application/src/tracker/gui/Timeline.cpp | 58 ++++---- Application/src/tracker/gui/Timeline.h | 4 +- Application/src/tracker/gui/gui.cpp | 60 ++++---- Application/src/tracker/gui/gui.h | 2 +- Application/src/tracker/main.cpp | 8 +- Application/src/tracker/misc/MemoryStats.cpp | 10 +- Application/src/tracker/misc/MemoryStats.h | 9 +- Application/src/tracker/misc/Output.cpp | 10 +- Application/src/tracker/misc/Output.h | 2 +- .../src/tracker/misc/default_config.cpp | 9 +- Application/src/tracker/misc/idx_t.cpp | 14 ++ Application/src/tracker/misc/idx_t.h | 50 +++++++ .../src/tracker/python/GPURecognition.h | 9 +- .../src/tracker/tracking/Accumulation.cpp | 129 +++++++++--------- .../src/tracker/tracking/Accumulation.h | 14 +- .../src/tracker/tracking/DatasetQuality.cpp | 6 +- .../src/tracker/tracking/DatasetQuality.h | 10 +- Application/src/tracker/tracking/Export.cpp | 2 +- .../src/tracker/tracking/Individual.cpp | 26 ++-- Application/src/tracker/tracking/Individual.h | 15 +- .../src/tracker/tracking/Recognition.cpp | 24 ++-- .../src/tracker/tracking/Recognition.h | 32 ++--- Application/src/tracker/tracking/Tracker.cpp | 90 ++++++------ Application/src/tracker/tracking/Tracker.h | 30 ++-- .../src/tracker/tracking/TrainingData.cpp | 78 ++++++----- .../src/tracker/tracking/TrainingData.h | 47 +++---- .../src/tracker/tracking/VisualField.cpp | 14 +- .../src/tracker/tracking/VisualField.h | 6 +- docs/parameters_trex.rst | 8 +- 47 files changed, 520 insertions(+), 426 deletions(-) create mode 100644 Application/src/tracker/misc/idx_t.cpp create mode 100644 Application/src/tracker/misc/idx_t.h diff --git a/Application/src/commons/common/gui/CrossPlatform.h b/Application/src/commons/common/gui/CrossPlatform.h index 1618e22..4d424d4 100644 --- a/Application/src/commons/common/gui/CrossPlatform.h +++ b/Application/src/commons/common/gui/CrossPlatform.h @@ -11,10 +11,10 @@ namespace gui { struct PlatformTexture { void* ptr = nullptr ; std::function<void(void**)> deleter; - int width; - int height; - int image_width; - int image_height; + uint width = 0; + uint height = 0; + uint image_width = 0; + uint image_height = 0; PlatformTexture() = default; ~PlatformTexture() { diff --git a/Application/src/commons/common/gui/GLImpl.cpp b/Application/src/commons/common/gui/GLImpl.cpp index ea86c3a..903df07 100644 --- a/Application/src/commons/common/gui/GLImpl.cpp +++ b/Application/src/commons/common/gui/GLImpl.cpp @@ -426,8 +426,8 @@ TexturePtr GLImpl::texture(const Image * ptr) { *ptr = nullptr; }, - static_cast<int>(width), static_cast<int>(height), - static_cast<int>(ptr->cols), static_cast<int>(ptr->rows) + static_cast<uint>(width), static_cast<uint>(height), + ptr->cols, ptr->rows }); } diff --git a/Application/src/commons/common/gui/IMGUIBase.cpp b/Application/src/commons/common/gui/IMGUIBase.cpp index d0eb29d..03562bd 100644 --- a/Application/src/commons/common/gui/IMGUIBase.cpp +++ b/Application/src/commons/common/gui/IMGUIBase.cpp @@ -452,7 +452,7 @@ void clear_cache() { if (!ptr) { Warning("Cannot load font '%S' with index %d.", &path.str(), config.FontNo); ptr = io.Fonts->AddFontDefault(); - im_font_scale = max(1, dpi_scale) * 0.5; + im_font_scale = max(1, dpi_scale) * 0.5f; } ptr->FontSize = base_scale * im_font_scale; diff --git a/Application/src/commons/common/gui/MetalImpl.mm b/Application/src/commons/common/gui/MetalImpl.mm index 63a5593..e24bd46 100644 --- a/Application/src/commons/common/gui/MetalImpl.mm +++ b/Application/src/commons/common/gui/MetalImpl.mm @@ -354,8 +354,8 @@ bool MetalImpl::open_files(const std::vector<file::Path> &paths) { TexturePtr MetalImpl::texture(const Image * ptr) { GLIMPL_CHECK_THREAD_ID(); - int width = next_pow2(ptr->cols); - int height = next_pow2(ptr->rows); + uint width = next_pow2(ptr->cols); + uint height = next_pow2(ptr->rows); auto input_format = MTLPixelFormatRGBA8Unorm; if(ptr->dims == 1) { @@ -399,7 +399,7 @@ bool MetalImpl::open_files(const std::vector<file::Path> &paths) { *ptr = nullptr; //id<MTLTexture> texture = (__bridge id<MTLTexture>)ptr; //[texture release]; - }, width, height, static_cast<int>(ptr->cols), static_cast<int>(ptr->rows)}); + }, width, height, ptr->cols, ptr->rows}); } void MetalImpl::clear_texture(TexturePtr&& tex) { diff --git a/Application/src/commons/common/misc/metastring.h b/Application/src/commons/common/misc/metastring.h index 35a3384..70e7934 100644 --- a/Application/src/commons/common/misc/metastring.h +++ b/Application/src/commons/common/misc/metastring.h @@ -257,6 +257,9 @@ namespace cmn { template <typename T> struct has_tostr_method; + template <typename T> + struct has_classname_method; + template <typename T> struct has_internal_tostr_method; @@ -303,7 +306,7 @@ namespace cmn { template<class Q> std::string name(const typename std::enable_if< std::is_same<DurationUS, typename std::remove_cv<Q>::type>::value, Q >::type* =nullptr) { return "time"; } template<class Q> - std::string name(const typename std::enable_if< std::is_convertible<Q, MetaObject>::value, Q >::type* =nullptr) { + std::string name(const typename std::enable_if< std::is_convertible<Q, MetaObject>::value || Meta::has_classname_method<Q>::value, Q >::type* =nullptr) { //MetaObject obj = Q(); //return obj.class_name(); return Q::class_name(); @@ -1002,6 +1005,21 @@ namespace cmn { static const bool value = std::is_same<std::true_type, decltype(test<T, dummy>(nullptr))>::value; }; + template <typename T> + struct has_classname_method + { + struct dummy { }; + + template <typename C, typename P> + static auto test(C * p) -> decltype(static_cast<void>(sizeof(decltype(C::class_name()))), std::true_type()); + + template <typename, typename> + static std::false_type test(...); + + typedef decltype(test<T, dummy>(nullptr)) type; + static const bool value = std::is_same<std::true_type, decltype(test<T, dummy>(nullptr))>::value; + }; + template <typename T> struct has_internal_tostr_method { diff --git a/Application/src/commons/common/types.h b/Application/src/commons/common/types.h index 2be9394..c31e929 100644 --- a/Application/src/commons/common/types.h +++ b/Application/src/commons/common/types.h @@ -35,7 +35,6 @@ namespace gui { namespace track { using namespace cmn; - typedef long_t idx_t; } #include <misc/vec2.h> diff --git a/Application/src/grabber/default_config.cpp b/Application/src/grabber/default_config.cpp index 3afaf62..9c2fac0 100644 --- a/Application/src/grabber/default_config.cpp +++ b/Application/src/grabber/default_config.cpp @@ -72,7 +72,7 @@ namespace default_config { #endif CONFIG("app_name", std::string("TGrabs"), "Name of the application.", SYSTEM); - CONFIG("version", std::string("1.0.4"), "Version of the application.", SYSTEM); + CONFIG("version", std::string("1.0.5"), "Version of the application.", SYSTEM); CONFIG("color_channel", size_t(1), "Index (0-2) of the color channel to be used during video conversion, if more than one channel is present in the video file."); CONFIG("system_memory_limit", uint64_t(0), "Custom override of how many bytes of system RAM the program is allowed to fill. If `approximate_length_minutes` or `stop_after_minutes` are set, this might help to increase the resulting RAW video footage frame_rate."); diff --git a/Application/src/grabber/main.cpp b/Application/src/grabber/main.cpp index 26860c0..b421109 100644 --- a/Application/src/grabber/main.cpp +++ b/Application/src/grabber/main.cpp @@ -636,11 +636,11 @@ int main(int argc, char** argv) Debug("Logging to '%S'.", &path.str()); } - if(SETTING(manual_identities).value<std::set<uint32_t>>().empty() && SETTING(track_max_individuals).value<uint32_t>() != 0) + if(SETTING(manual_identities).value<std::set<track::Idx_t>>().empty() && SETTING(track_max_individuals).value<uint32_t>() != 0) { - std::set<uint32_t> vector; + std::set<track::Idx_t> vector; for(uint32_t i=0; i<SETTING(track_max_individuals).value<uint32_t>(); ++i) { - vector.insert(i); + vector.insert(track::Idx_t(i)); } SETTING(manual_identities) = vector; } diff --git a/Application/src/tracker/gui/DrawDataset.cpp b/Application/src/tracker/gui/DrawDataset.cpp index d689407..f385989 100644 --- a/Application/src/tracker/gui/DrawDataset.cpp +++ b/Application/src/tracker/gui/DrawDataset.cpp @@ -65,7 +65,7 @@ namespace gui { return; } - using dataset_t = std::tuple<std::map<track::idx_t, DatasetQuality::Single>, DatasetQuality::Quality>; + using dataset_t = std::tuple<std::map<track::Idx_t, DatasetQuality::Single>, DatasetQuality::Quality>; //_current_quality = dataset ? dataset->quality(frame) : -1; for(auto id : FAST_SETTINGS(manual_identities)) { @@ -119,7 +119,7 @@ namespace gui { auto && [per_fish, quality] = dataset ? dataset_t{ dataset->per_fish(consec), dataset->quality(consec) } - : dataset_t{ std::map<track::idx_t, DatasetQuality::Single>{}, DatasetQuality::Quality() }; + : dataset_t{ std::map<track::Idx_t, DatasetQuality::Single>{}, DatasetQuality::Quality() }; _meta = per_fish; _last_consecutive_frames = consec; @@ -145,16 +145,16 @@ namespace gui { * is available for given individual. */ - std::set<long_t> identities_found; - std::set<long_t> double_identities; - std::map<long_t, std::tuple<size_t, long_t, float>> max_identity; + std::set<Idx_t> identities_found; + std::set<Idx_t> double_identities; + std::map<Idx_t, std::tuple<size_t, Idx_t, float>> max_identity; for(auto && [id, tup] : _cache) { auto & [samples, map] = tup; float max_p = 0; - long_t max_id = -1; + Idx_t max_id; for(auto & [id, p] : map) { - if(p > max_p) { + if(!max_id.valid() || p > max_p) { max_p = p; max_id = id; } @@ -162,7 +162,7 @@ namespace gui { max_identity[id] = { samples, max_id, max_p }; - if(max_id != -1) { + if(max_id.valid()) { if(identities_found.find(max_id) != identities_found.end() && double_identities.find(max_id) == double_identities.end()) { @@ -173,7 +173,7 @@ namespace gui { identities_found.insert(max_id); } - std::map<long_t, std::tuple<float, float>> fish_offset; + std::map<Idx_t, std::tuple<float, float>> fish_offset; float y = 10, max_w = 0; Font font(0.75); @@ -191,7 +191,7 @@ namespace gui { color = Yellow.alpha(200); Drawable *secondary; - if(max_id != -1) + if(max_id.valid()) secondary = advance(new Text(Meta::toStr(max_id)+" ("+Meta::toStr(max_p)+", "+Meta::toStr(samples)+" samples)", text->pos() + Vec2(text->width(), 0), color, font)); else secondary = advance(new Text("N/A ("+Meta::toStr(samples)+" samples)", text->pos() + Vec2(text->width(), 0), DarkCyan.brightenHSL(1.5).alpha(200), font)); @@ -278,7 +278,7 @@ namespace gui { advance(new Line(Vec2(x - 10, 5), Vec2(x - 10, y + 5), White.alpha(150))); if(index < _texts.size()) - _texts.erase(_texts.begin() + index, _texts.end()); + _texts.erase(_texts.begin() + (int64_t)index, _texts.end()); end(); diff --git a/Application/src/tracker/gui/DrawDataset.h b/Application/src/tracker/gui/DrawDataset.h index b8f5e0d..bbbf969 100644 --- a/Application/src/tracker/gui/DrawDataset.h +++ b/Application/src/tracker/gui/DrawDataset.h @@ -3,6 +3,7 @@ #include <gui/DrawStructure.h> #include <gui/types/Entangled.h> #include <tracking/DatasetQuality.h> +#include <misc/idx_t.h> namespace gui { class DrawDataset : public Entangled { @@ -10,12 +11,12 @@ namespace gui { Rangel _last_consecutive_frames, _last_current_frames; track::DatasetQuality::Quality _quality, _current_quality; - std::map<long_t, std::tuple<size_t, std::map<long_t, float>>> _cache; - std::map<long_t, std::string> _names; + std::map<track::Idx_t, std::tuple<size_t, std::map<track::Idx_t, float>>> _cache; + std::map<track::Idx_t, std::string> _names; std::vector<std::shared_ptr<StaticText>> _texts; - std::map<track::idx_t, track::DatasetQuality::Single> _meta; - std::map<track::idx_t, track::DatasetQuality::Single> _meta_current; + std::map<track::Idx_t, track::DatasetQuality::Single> _meta; + std::map<track::Idx_t, track::DatasetQuality::Single> _meta_current; bool _initial_pos_set; public: diff --git a/Application/src/tracker/gui/DrawFish.cpp b/Application/src/tracker/gui/DrawFish.cpp index e35ce05..4f221d6 100644 --- a/Application/src/tracker/gui/DrawFish.cpp +++ b/Application/src/tracker/gui/DrawFish.cpp @@ -39,7 +39,7 @@ CREATE_STRUCT(CachedGUIOptions, { CachedGUIOptions::init(); - assert(_obj.identity().ID() < std::numeric_limits<idx_t>::max()); + assert(_obj.identity().ID().valid()); auto ID = _obj.identity().ID(); set_clickable(true); _circle.set_clickable(true); @@ -49,7 +49,7 @@ CREATE_STRUCT(CachedGUIOptions, GUI::cache().set_tracking_dirty(); }); on_click([ID, this](auto) { - std::vector<uint32_t> selections = SETTING(gui_focus_group); + std::vector<Idx_t> selections = SETTING(gui_focus_group); if(stage() && !(stage()->is_key_pressed(gui::LShift) || stage()->is_key_pressed(gui::RShift))) { if(!selections.empty() && selections.front() == ID) diff --git a/Application/src/tracker/gui/DrawFish.h b/Application/src/tracker/gui/DrawFish.h index 97a3bef..1fd0edf 100644 --- a/Application/src/tracker/gui/DrawFish.h +++ b/Application/src/tracker/gui/DrawFish.h @@ -17,7 +17,7 @@ namespace gui { const track::PPFrame* _frame; GETTER(long_t, idx) long_t _safe_idx; - float _time; + double _time; std::unique_ptr<ExternalImage> _image; Midline::Ptr _cached_midline; MinimalOutline::Ptr _cached_outline; diff --git a/Application/src/tracker/gui/DrawMenu.cpp b/Application/src/tracker/gui/DrawMenu.cpp index 5f85a8c..a1dd54b 100644 --- a/Application/src/tracker/gui/DrawMenu.cpp +++ b/Application/src/tracker/gui/DrawMenu.cpp @@ -40,17 +40,17 @@ public: class ItemIndividual : public gui::List::Item { protected: GETTER_SETTER(std::string, name) - GETTER_SETTER(long_t, ptr) + GETTER_SETTER(Idx_t, ptr) GETTER_SETTER(long_t, selected_blob_id) public: - ItemIndividual(long_t fish = -1, long_t blob = -1) + ItemIndividual(Idx_t fish = Idx_t(), long_t blob = -1) : gui::List::Item(fish), _ptr(fish), _selected_blob_id(blob) { - if(fish != -1) { - Identity id((idx_t)_ptr); + if(fish.valid()) { + Identity id(_ptr); _name = id.name(); } } @@ -140,7 +140,7 @@ public: [this](List*, const List::Item& item) { Debug("%d %d", item.ID(), item.selected()); if(!item.selected() && item.ID() >= 0) { - GUI::instance()->add_manual_match(GUI::instance()->frameinfo().frameIndex, _list->selected_item() >= 0 ? (idx_t)_list->selected_item() : std::numeric_limits<idx_t>::max(), item.ID()); + GUI::instance()->add_manual_match(GUI::instance()->frameinfo().frameIndex, _list->selected_item() >= 0 ? Idx_t(_list->selected_item()) : Idx_t(), item.ID()); } } ); @@ -286,10 +286,10 @@ public: * Try and match the last displayed fish items to the currently existing ones */ struct FishAndBlob { - idx_t fish; + Idx_t fish; long_t blob; - FishAndBlob(idx_t fish = 0, long_t blob = -1) : fish(fish), blob(blob) + FishAndBlob(Idx_t fish = Idx_t(), long_t blob = -1) : fish(fish), blob(blob) {} void convert(std::shared_ptr<List::Item> ptr) { @@ -408,7 +408,7 @@ public: tooltip = new Tooltip(nullptr, 300); } - if((overall.id == -1 || memory_timer.elapsed() > 10) && GUI::cache().tracked_frames.end != last_end_frame) { + if((!overall.id.valid() || memory_timer.elapsed() > 10) && GUI::cache().tracked_frames.end != last_end_frame) { Tracker::LockGuard guard("memory_stats", 100); if(guard.locked()) { overall.clear(); diff --git a/Application/src/tracker/gui/GUICache.cpp b/Application/src/tracker/gui/GUICache.cpp index a516986..d0b7b59 100644 --- a/Application/src/tracker/gui/GUICache.cpp +++ b/Application/src/tracker/gui/GUICache.cpp @@ -80,18 +80,18 @@ namespace gui { selected.clear(); } - bool GUICache::is_selected(uint32_t id) const { + bool GUICache::is_selected(Idx_t id) const { return contains(selected, id); } - void GUICache::do_select(uint32_t id) { + void GUICache::do_select(Idx_t id) { if(!is_selected(id)) { selected.push_back(id); SETTING(gui_focus_group) = selected; } } - void GUICache::deselect(uint32_t id) { + void GUICache::deselect(Idx_t id) { auto it = std::find(selected.begin(), selected.end(), id); if(it != selected.end()) { selected.erase(it); @@ -99,7 +99,7 @@ namespace gui { } } - void GUICache::deselect_all_select(uint32_t id) { + void GUICache::deselect_all_select(Idx_t id) { selected.clear(); selected.push_back(id); @@ -152,7 +152,7 @@ namespace gui { Tracker::instance()->thread_pool().enqueue([this](){ Debug("Percentiles..."); - auto percentiles = GUI::instance()->video_source()->calculate_percentiles({0.05, 0.95}); + auto percentiles = GUI::instance()->video_source()->calculate_percentiles({0.05f, 0.95f}); if(GUI::instance()) { std::lock_guard<std::recursive_mutex> guard(GUI::instance()->gui().lock()); @@ -178,7 +178,7 @@ namespace gui { if(properties) { active = _tracker.active_individuals(frameIndex); individuals = _tracker.individuals(); - selected = SETTING(gui_focus_group).value<std::vector<uint32_t>>(); + selected = SETTING(gui_focus_group).value<std::vector<Idx_t>>(); active_blobs.clear(); inactive_ids.clear(); active_ids.clear(); @@ -189,7 +189,7 @@ namespace gui { auto delete_callback = [this](Individual* fish) { std::lock_guard<std::recursive_mutex> guard(GUI::instance()->gui().lock()); - auto id = narrow_cast<int32_t>(fish->identity().ID()); + auto id = fish->identity().ID(); auto it = individuals.find(id); if(it != individuals.end()) individuals.erase(it); @@ -221,7 +221,7 @@ namespace gui { } else { for(auto id : FAST_SETTINGS(manual_identities)) { - auto it = individuals.find((idx_t)id); + auto it = individuals.find(id); if(it != individuals.end()) { it->second->register_delete_callback((void*)12341337, delete_callback); } @@ -286,7 +286,7 @@ namespace gui { } else { // display blobs that are selected for(auto id : selected) { - auto it = individuals.find((idx_t)id); + auto it = individuals.find(id); if(it != individuals.end()) { auto blob = it->second->compressed_blob(frameIndex); if(blob) @@ -448,7 +448,7 @@ namespace gui { } } - bool GUICache::has_probs(uint32_t fdx) { + bool GUICache::has_probs(Idx_t fdx) { if(checked_probs.find(fdx) != checked_probs.end()) { return probabilities.find(fdx) != probabilities.end(); } @@ -456,7 +456,7 @@ namespace gui { return probs(fdx) != nullptr; } - const std::map<uint32_t, Individual::Probability>* GUICache::probs(uint32_t fdx) { + const std::map<uint32_t, Individual::Probability>* GUICache::probs(Idx_t fdx) { if(checked_probs.find(fdx) != checked_probs.end()) { auto it = probabilities.find(fdx); if(it != probabilities.end()) @@ -472,7 +472,7 @@ namespace gui { if(it != processed_frame.cached_individuals.end()) { auto && [fdx, cache] = *it; for(auto blob : processed_frame.blobs) { - auto p = individuals.count((idx_t)fdx) ? individuals.at((idx_t)fdx)->probability(cache, frame_idx, blob) : Individual::Probability{0,0,0,0}; + auto p = individuals.count(fdx) ? individuals.at(fdx)->probability(cache, frame_idx, blob) : Individual::Probability{0,0,0,0}; if(p.p >= FAST_SETTINGS(matching_probability_threshold)) probabilities[fdx][blob->blob_id()] = p; } diff --git a/Application/src/tracker/gui/GUICache.h b/Application/src/tracker/gui/GUICache.h index 83e56bb..87fcf1b 100644 --- a/Application/src/tracker/gui/GUICache.h +++ b/Application/src/tracker/gui/GUICache.h @@ -28,7 +28,7 @@ namespace gui { int last_threshold; long_t last_frame; Bounds boundary; - std::vector<uint32_t> previous_active_fish; + std::vector<Idx_t> previous_active_fish; std::set<uint32_t> previous_active_blobs, active_blobs; Vec2 previous_mouse_position; bool _dirty; @@ -60,16 +60,16 @@ namespace gui { std::map<uint32_t, long_t> automatic_assignments; - std::unordered_map<idx_t, Individual*> individuals; - std::set<uint32_t> active_ids; - std::set<uint32_t> inactive_ids; - std::set<uint32_t> recognized_ids; - std::map<uint32_t, std::shared_ptr<gui::Circle>> recognition_circles; - std::map<uint32_t, Timer> recognition_timer; + std::unordered_map<Idx_t, Individual*> individuals; + std::set<Idx_t> active_ids; + std::set<Idx_t> inactive_ids; + std::set<Idx_t> recognized_ids; + std::map<Idx_t, std::shared_ptr<gui::Circle>> recognition_circles; + std::map<Idx_t, Timer> recognition_timer; Tracker::set_of_individuals_t _registered_callback; - std::map<uint32_t, long_t> fish_selected_blobs; + std::map<Idx_t, long_t> fish_selected_blobs; Tracker::set_of_individuals_t active; //std::vector<std::shared_ptr<gui::ExternalImage>> blob_images; std::vector<std::shared_ptr<SimpleBlob>> raw_blobs; @@ -79,7 +79,7 @@ namespace gui { std::vector<Vec2> inactive_estimates; protected: - std::map<uint32_t, std::map<uint32_t, Individual::Probability>> probabilities; + std::map<Idx_t, std::map<uint32_t, Individual::Probability>> probabilities; std::set<uint32_t> checked_probs; public: @@ -90,20 +90,20 @@ namespace gui { std::vector<float> connectivity_matrix; PPFrame processed_frame; - std::vector<uint32_t> selected; + std::vector<Idx_t> selected; public: bool has_selection() const; Individual * primary_selection() const; void deselect_all(); - bool is_selected(uint32_t id) const; - void do_select(uint32_t id); + bool is_selected(Idx_t id) const; + void do_select(Idx_t id); - void deselect(uint32_t id); - void deselect_all_select(uint32_t id); + void deselect(Idx_t id); + void deselect_all_select(Idx_t id); - const std::map<uint32_t, Individual::Probability>* probs(uint32_t fdx); - bool has_probs(uint32_t fdx); + const std::map<uint32_t, Individual::Probability>* probs(Idx_t fdx); + bool has_probs(Idx_t fdx); void set_tracking_dirty(); void set_blobs_dirty(); diff --git a/Application/src/tracker/gui/IdentityHeatmap.cpp b/Application/src/tracker/gui/IdentityHeatmap.cpp index 38943f6..5a16dbc 100644 --- a/Application/src/tracker/gui/IdentityHeatmap.cpp +++ b/Application/src/tracker/gui/IdentityHeatmap.cpp @@ -429,7 +429,7 @@ HeatmapController::UpdatedStats HeatmapController::update_data(long_t current_fr auto &range = updated.add_range; for(auto [id, fish] : Tracker::individuals()) { - auto frame = max(Tracker::start_frame(), range.start); + auto frame = max((long_t)Tracker::start_frame(), range.start); if(fish->end_frame() < frame) continue; if(fish->start_frame() > range.end) @@ -472,7 +472,7 @@ HeatmapController::UpdatedStats HeatmapController::update_data(long_t current_fr // Debug("Cannot find segment for frame %d in fish %d", frame, fish->identity().ID()); Output::Library::LibInfo info(fish, _mods); - for(; frame < min(Tracker::end_frame(), range.end); ++frame) { + for(; frame < min((long_t)Tracker::end_frame(), range.end); ++frame) { if(_grid.root()->frame_range().contains(frame)) continue; //break; @@ -500,7 +500,7 @@ HeatmapController::UpdatedStats HeatmapController::update_data(long_t current_fr auto bid = (*kit)->basic_stuff(frame); if(bid != -1) { - auto &basic = fish->basic_stuff()[bid]; + auto &basic = fish->basic_stuff()[(uint32_t)bid]; auto pos = basic->centroid->pos(Units::PX_AND_SECONDS); //auto speed = basic->centroid->speed(Units::PX_AND_SECONDS); diff --git a/Application/src/tracker/gui/InfoCard.cpp b/Application/src/tracker/gui/InfoCard.cpp index 1ef7300..ea9b482 100644 --- a/Application/src/tracker/gui/InfoCard.cpp +++ b/Application/src/tracker/gui/InfoCard.cpp @@ -296,7 +296,7 @@ void InfoCard::update() { auto blob_id = _fish->compressed_blob(_frameNr)->blob_id(); auto && [valid, segment] = _fish->has_processed_segment(_frameNr); - std::map<long_t, float> raw; + std::map<Idx_t, float> raw; std::string title = "recognition"; if(valid) { diff --git a/Application/src/tracker/gui/RecognitionSummary.cpp b/Application/src/tracker/gui/RecognitionSummary.cpp index 24cbcbc..f4f005f 100644 --- a/Application/src/tracker/gui/RecognitionSummary.cpp +++ b/Application/src/tracker/gui/RecognitionSummary.cpp @@ -17,7 +17,7 @@ namespace gui { Font bottom_font(0.8f / interface_scale, Align::Center); auto manual_identities = FAST_SETTINGS(manual_identities); - std::set<uint32_t> sorted(manual_identities.begin(), manual_identities.end()); + std::set<Idx_t> sorted(manual_identities.begin(), manual_identities.end()); for(auto id : manual_identities) { if(cache.individuals.find(id) == cache.individuals.end()) sorted.erase(id); @@ -49,7 +49,7 @@ namespace gui { base.advance(new Text("recognition summary", Vec2(obj.width() * 0.5f, margin + (title_height - margin) * 0.5f), White, title_font)); size_t counter = 0, j = 0; - std::map<long_t, size_t> fdx_to_idx; + std::map<Idx_t, size_t> fdx_to_idx; std::map<size_t, long_t> idx_to_fdx; outputs.resize(output_size * sorted.size()); diff --git a/Application/src/tracker/gui/Timeline.cpp b/Application/src/tracker/gui/Timeline.cpp index 39c3b2d..74330b6 100644 --- a/Application/src/tracker/gui/Timeline.cpp +++ b/Application/src/tracker/gui/Timeline.cpp @@ -30,11 +30,11 @@ namespace gui { _visible(true), _mOverFrame(-1), _title_layout({}, Vec2(20, 20), Bounds(0, 0, 17, 0)), - _status_text("", Vec2(), White, 0.8), - _status_text2("", Vec2(), White, 0.8), - _status_text3("", Vec2(), White, 0.8), - _raw_text("[RAW]", Vec2(), Black, Font(0.8, Style::Bold)), - _auto_text("", Vec2(), Black, Font(0.8, Style::Bold)), + _status_text("", Vec2(), White, 0.8f), + _status_text2("", Vec2(), White, 0.8f), + _status_text3("", Vec2(), White, 0.8f), + _raw_text("[RAW]", Vec2(), Black, Font(0.8f, Style::Bold)), + _auto_text("", Vec2(), Black, Font(0.8f, Style::Bold)), _pause("pause", Size2(100,27)) { _instance = this; @@ -83,7 +83,7 @@ void Timeline::update_consecs(float max_w, const Range<long_t>& consec, const st static Range<long_t> previous_consec(-1, -1); static std::vector<Rangel> previous_other_consec = {}; static float previous_scale = 0; - const double scale = max(1, min(_scale, CV_MAX_THICKNESS)); + const float scale = max(1, min(_scale, CV_MAX_THICKNESS)); float new_height = roundf(bar_height) + 5 * scale; if(consec == previous_consec @@ -221,7 +221,7 @@ void Timeline::update_consecs(float max_w, const Range<long_t>& consec, const st consec_color = Green; if(_status_text2.hovered()) - consec_color = consec_color.brightenHSL(0.9); + consec_color = consec_color.brightenHSL(0.9f); _status_text2.set_color(consec_color); _status_text2.set_txt(number.str()); @@ -289,14 +289,14 @@ void Timeline::update_consecs(float max_w, const Range<long_t>& consec, const st base.wrap_object(*_bar); if(FAST_SETTINGS(recognition_enable)) { - update_consecs(max_w, consec, other_consec, use_scale.y * 0.75); + update_consecs(max_w, consec, other_consec, use_scale.y * 0.75f); if(_consecutives) { - _consecutives->set_pos(pos - Vec2(0,5) * max(1, use_scale.y * 0.75)); + _consecutives->set_pos(pos - Vec2(0,5) * max(1, use_scale.y * 0.75f)); base.wrap_object(*_consecutives); } } - base.add_object(new Text(Meta::toStr(tracker_endframe.load()), pos + Vec2(max_w * tracker_endframe / float(_frame_info.video_length) + 5, bar_height * 0.5), Black, Font(0.5), Vec2(1), Vec2(0,0.5))); + base.add_object(new Text(Meta::toStr(tracker_endframe.load()), pos + Vec2(max_w * tracker_endframe / float(_frame_info.video_length) + 5, bar_height * 0.5f), Black, Font(0.5), Vec2(1), Vec2(0,0.5))); // display hover sign with frame number if(_mOverFrame != -1) { @@ -304,19 +304,19 @@ void Timeline::update_consecs(float max_w, const Range<long_t>& consec, const st //if(it != _proximity_bar.changed_frames.end() || _mOverFrame >= _proximity_bar.end) { std::string t = "Frame "+std::to_string(_mOverFrame); - auto dims = Base::text_dimensions(t, &_title_layout, Font(0.7)); + auto dims = Base::text_dimensions(t, &_title_layout, Font(0.7f)); - Vec2 pp(max_w / float(_frame_info.video_length) * _mOverFrame, _bar->pos().y + _bar->global_bounds().height / use_scale.y + dims.height * 0.5 + 2); + Vec2 pp(max_w / float(_frame_info.video_length) * _mOverFrame, _bar->pos().y + _bar->global_bounds().height / use_scale.y + dims.height * 0.5f + 2); - if(pp.x < dims.width * 0.5) - pp.x = dims.width * 0.5; - if(pp.x + dims.width * 0.5 > max_w) - pp.x = max_w - dims.width * 0.5; + if(pp.x < dims.width * 0.5f) + pp.x = dims.width * 0.5f; + if(pp.x + dims.width * 0.5f > max_w) + pp.x = max_w - dims.width * 0.5f; pp -= offset; - base.rect(pp - dims * 0.5 - Vec2(5, 2), dims + Vec2(10, 4), Black.alpha(125)); - base.text(t, pp, gui::White, Font(0.7, Align::Center)); + base.rect(pp - dims * 0.5f - Vec2(5, 2), dims + Vec2(10, 4), Black.alpha(125)); + base.text(t, pp, gui::White, Font(0.7f, Align::Center)); } } } @@ -385,7 +385,7 @@ void Timeline::update_consecs(float max_w, const Range<long_t>& consec, const st //Vec2 pp(max_w / float(_frame_info.video_length) * idx.first, 50); //float dis = abs(e.hover.x - pp.x); static Timing timing("Scrubbing", 0.01); - long_t idx = roundf(e.hover.x / max_w_ * float(_frame_info.video_length)); + int64_t idx = roundf(e.hover.x / max_w_ * float(_frame_info.video_length)); auto it = _proximity_bar.changed_frames.find(idx); if(it != _proximity_bar.changed_frames.end()) { framemOver = idx; @@ -707,7 +707,7 @@ void Timeline::update_consecs(float max_w, const Range<long_t>& consec, const st } } - void Timeline::next_poi(long_t _s_fdx) { + void Timeline::next_poi(Idx_t _s_fdx) { auto frame = GUI::frame(); long_t next_frame = frame; std::set<FOI::fdx_t> fdx; @@ -715,7 +715,7 @@ void Timeline::update_consecs(float max_w, const Range<long_t>& consec, const st { std::lock_guard<std::mutex> guard(_proximity_bar.mutex); for(auto && [idx, number] : _proximity_bar.changed_frames) { - if(_s_fdx != -1) { + if(_s_fdx.valid()) { if(number.find(FOI::fdx_t(_s_fdx)) == number.end()) continue; } @@ -731,20 +731,20 @@ void Timeline::update_consecs(float max_w, const Range<long_t>& consec, const st if(frame != next_frame) { SETTING(gui_frame) = next_frame; - if(_s_fdx == -1) { + if(_s_fdx.valid()) { auto &cache = GUI::instance()->cache(); if(!fdx.empty()) { cache.deselect_all(); for(auto id : fdx) { - if(!cache.is_selected(id.id)) - cache.do_select(id.id); + if(!cache.is_selected(Idx_t(id.id))) + cache.do_select(Idx_t(id.id)); } } } } } - void Timeline::prev_poi(long_t _s_fdx) { + void Timeline::prev_poi(Idx_t _s_fdx) { auto frame = GUI::frame(); long_t next_frame = frame; std::set<FOI::fdx_t> fdx; @@ -752,7 +752,7 @@ void Timeline::update_consecs(float max_w, const Range<long_t>& consec, const st { std::lock_guard<std::mutex> guard(_proximity_bar.mutex); for(auto && [idx, number] : MakeReverse(_proximity_bar.changed_frames)) { - if(_s_fdx != -1) { + if(_s_fdx.valid()) { if(number.find(FOI::fdx_t(_s_fdx)) == number.end()) continue; } @@ -768,13 +768,13 @@ void Timeline::update_consecs(float max_w, const Range<long_t>& consec, const st if(frame != next_frame && next_frame != -1) { SETTING(gui_frame) = next_frame; - if(_s_fdx == -1) { + if(_s_fdx.valid()) { auto &cache = GUI::instance()->cache(); if(!fdx.empty()) { cache.deselect_all(); for(auto id : fdx) { - if(!cache.is_selected(id.id)) - cache.do_select(id.id); + if(!cache.is_selected(Idx_t(id.id))) + cache.do_select(Idx_t(id.id)); } } } diff --git a/Application/src/tracker/gui/Timeline.h b/Application/src/tracker/gui/Timeline.h index 6d11eec..0035552 100644 --- a/Application/src/tracker/gui/Timeline.h +++ b/Application/src/tracker/gui/Timeline.h @@ -106,8 +106,8 @@ namespace gui { void update_thread(); void reset_events(long_t after_frame = -1); //void update_border(); - void next_poi(long_t fdx = -1); - void prev_poi(long_t fdx = -1); + void next_poi(Idx_t fdx = Idx_t()); + void prev_poi(Idx_t fdx = Idx_t()); static std::tuple<Vec2, float> timeline_offsets(); private: diff --git a/Application/src/tracker/gui/gui.cpp b/Application/src/tracker/gui/gui.cpp index 2d4f86e..f01c267 100644 --- a/Application/src/tracker/gui/gui.cpp +++ b/Application/src/tracker/gui/gui.cpp @@ -611,7 +611,7 @@ void GUI::run_loop(gui::DrawStructure&) { if(inc >= 1) { auto before = image_index; - image_index = min(_tracker.end_frame(), image_index + inc); + image_index = min((float)_tracker.end_frame(), image_index + inc); t = 0; if(before != image_index) { @@ -1687,30 +1687,30 @@ std::tuple<Vec2, Vec2> GUI::gui_scale_with_boundary(Bounds& boundary, Section* s #ifndef NDEBUG Debug("target_pos.x = %f target_scale.x = %f", target_pos.x, target_scale.x); #endif - target_pos.x = -mw * target_scale.x * 0.95; + target_pos.x = -mw * target_scale.x * 0.95f; } - if(target_pos.y / target_scale.y < -mh * 0.95) - target_pos.y = -mh * target_scale.y * 0.95; + if(target_pos.y / target_scale.y < -mh * 0.95f) + target_pos.y = -mh * target_scale.y * 0.95f; - if(target_pos.x / target_scale.x > mw * 0.95) { + if(target_pos.x / target_scale.x > mw * 0.95f) { #ifndef NDEBUG Debug("target_pos.x = %f target_scale.x = %f screen_center.x = %f screen_dimensions.x = %f window_dimensions.x = %f", target_pos.x, target_scale.x, screen_center.width, screen_dimensions.width, base()->window_dimensions().width); #endif - target_pos.x = mw * target_scale.x * 0.95; + target_pos.x = mw * target_scale.x * 0.95f; } - if(target_pos.y / target_scale.y > mh * 0.95) - target_pos.y = mh * target_scale.y * 0.95; + if(target_pos.y / target_scale.y > mh * 0.95f) + target_pos.y = mh * target_scale.y * 0.95f; _cache.set_zoom_level(target_scale.x); static Timer timer; - float e = _recording ? cache().dt() : timer.elapsed(); //_recording ? (1 / float(FAST_SETTINGS(frame_rate))) : timer.elapsed(); + auto e = _recording ? cache().dt() : timer.elapsed(); //_recording ? (1 / float(FAST_SETTINGS(frame_rate))) : timer.elapsed(); //e = cache().dt(); e = min(0.1, e); e *= 3; - auto check_target = [](const Vec2& start, const Vec2& target, float e) { + auto check_target = [](const Vec2& start, const Vec2& target, double e) { Vec2 direction = target - start; double speed = direction.length(); if(speed > 0) @@ -1803,7 +1803,7 @@ void GUI::label_fish(gui::DrawStructure &base, track::Individual *fish, long_t f //L = SQR(L) * 0.5; auto text_offset = Vec2(0, Base::default_line_spacing(font)); - auto offset_from_blob = blob->calculate_bounds().height * 0.25; + auto offset_from_blob = blob->calculate_bounds().height * 0.25f; auto line_start = offset_from_blob; auto line_end = L + line_start; text_pos = blob_center - factor * (line_end + Base::default_line_spacing(Font(0.5f))); @@ -2077,7 +2077,7 @@ void GUI::draw_tracking(DrawStructure& base, long_t frameNr, bool draw_graph) { std::vector<std::vector<float>> all; std::vector<float> lengths; - std::map<track::idx_t, Individual*> search; + std::map<track::Idx_t, Individual*> search; if(FAST_SETTINGS(manual_identities).empty()) { for(auto fish : _cache.active) { @@ -2152,14 +2152,14 @@ void GUI::draw_tracking(DrawStructure& base, long_t frameNr, bool draw_graph) { _cache.connectivity_reload = false; _cache.connectivity_last_frame = frameIndex; - const idx_t number_fish = FAST_SETTINGS(track_max_individuals); - for (idx_t i=0; i<number_fish; ++i) { - if(!_cache.individuals.count(i)) { + const auto number_fish = FAST_SETTINGS(track_max_individuals); + for (uint32_t i=0; i<number_fish; ++i) { + if(!_cache.individuals.count(Idx_t(i))) { Except("Individuals seem to be named differently than 0-%d. Cannot find %d.", FAST_SETTINGS(track_max_individuals), i); continue; } - auto fish0 = _cache.individuals.at(i); + auto fish0 = _cache.individuals.at(Idx_t(i)); Vec2 p0(infinity<Float2_t>()); if(!fish0->has(frameIndex)) { @@ -2174,13 +2174,13 @@ void GUI::draw_tracking(DrawStructure& base, long_t frameNr, bool draw_graph) { if(cmn::isinf(p0.x)) continue; - for(idx_t j=i+1; j<number_fish; ++j) { - if(!_cache.individuals.count(j)) { + for(uint32_t j=i+1; j<number_fish; ++j) { + if(!_cache.individuals.count(Idx_t(j))) { Except("Individuals seem to be named differently than 0-%d. Cannot find %d.", FAST_SETTINGS(track_max_individuals), j); continue; } - auto fish1 = _cache.individuals.at(j); + auto fish1 = _cache.individuals.at(Idx_t(j)); Vec2 p1(infinity<Float2_t>()); if(!fish1->has(frameIndex)) { @@ -2255,7 +2255,7 @@ void GUI::draw_tracking(DrawStructure& base, long_t frameNr, bool draw_graph) { if(SETTING(gui_show_uniqueness)) { static Graph graph(Bounds(50, 100, 800, 400), "uniqueness"); static std::mutex mutex; - static std::map<uint32_t, float> estimated_uniqueness; + static std::map<Frame_t, float> estimated_uniqueness; static std::vector<Vec2> uniquenesses; static bool running = false; @@ -2311,7 +2311,7 @@ void GUI::draw_tracking(DrawStructure& base, long_t frameNr, bool draw_graph) { if(graph.empty()) { graph.add_function(Graph::Function("raw", Graph::Type::DISCRETE, [uq = &estimated_uniqueness](float x) -> float { std::lock_guard<std::mutex> guard(mutex); - auto it = uq->upper_bound(x); + auto it = uq->upper_bound(Frame_t(narrow_cast<long_t>(x))); if(!uq->empty() && it != uq->begin()) --it; if(it != uq->end() && it->second <= x) { @@ -3722,7 +3722,7 @@ void GUI::debug_binary(DrawStructure &base, long_t frameIndex) { SETTING(manual_splits) = copy; }); } else { - auto it = _cache.individuals.find(item.ID() - 1); + auto it = _cache.individuals.find(Idx_t(item.ID() - 1)); if(it != _cache.individuals.end()) { auto fish = it->second; auto id = it->first; @@ -3928,7 +3928,7 @@ void GUI::key_event(const gui::Event &event) { if(key.code >= Codes::Num0 && key.code <= Codes::Num9) { std::lock_guard<std::recursive_mutex> lock(_gui.lock()); Identity id(int(key.code - Codes::Num0)); - SETTING(gui_focus_group) = std::vector<uint32_t>{id.ID()}; + SETTING(gui_focus_group) = std::vector<Idx_t>{id.ID()}; set_redraw(); return; } @@ -3943,8 +3943,8 @@ void GUI::key_event(const gui::Event &event) { if(!cache._current_foi.foi.fdx().empty()) { cache.deselect_all(); for(auto id : cache._current_foi.foi.fdx()) { - if(!cache.is_selected(id.id)) - cache.do_select(id.id); + if(!cache.is_selected(Idx_t(id.id))) + cache.do_select(Idx_t(id.id)); } } } @@ -4109,7 +4109,7 @@ void GUI::key_event(const gui::Event &event) { } else break; - SETTING(gui_focus_group) = std::vector<uint32_t>{id.ID()}; + SETTING(gui_focus_group) = std::vector<Idx_t>{id.ID()}; break; } @@ -4134,7 +4134,7 @@ void GUI::key_event(const gui::Event &event) { } else break; - SETTING(gui_focus_group) = std::vector<uint32_t>{id.ID()}; + SETTING(gui_focus_group) = std::vector<Idx_t>{id.ID()}; break; } @@ -4194,8 +4194,8 @@ void GUI::key_event(const gui::Event &event) { if(!cache._current_foi.foi.fdx().empty()) { cache.deselect_all(); for(auto id : cache._current_foi.foi.fdx()) { - if(!cache.is_selected(id.id)) - cache.do_select(id.id); + if(!cache.is_selected(Idx_t(id.id))) + cache.do_select(Idx_t(id.id)); } } } @@ -5053,7 +5053,7 @@ void GUI::generate_training_data_faces(const file::Path& path) { } } -void GUI::add_manual_match(long_t frameIndex, idx_t fish_id, long_t blob_id) { +void GUI::add_manual_match(long_t frameIndex, Idx_t fish_id, long_t blob_id) { Debug("Requesting change of fish %d to blob %d in frame %d", fish_id, blob_id, frameIndex); auto matches = FAST_SETTINGS(manual_matches); diff --git a/Application/src/tracker/gui/gui.h b/Application/src/tracker/gui/gui.h index c966c27..cf96bed 100644 --- a/Application/src/tracker/gui/gui.h +++ b/Application/src/tracker/gui/gui.h @@ -266,7 +266,7 @@ private: std::map<long_t, long_t> check_additional_range(const Rangel& range, TrainingData& data); public: - void add_manual_match(long_t frameIndex, idx_t fish_id, long_t blob_id); + void add_manual_match(long_t frameIndex, Idx_t fish_id, long_t blob_id); private: void selected_setting(long_t index, const std::string& name, gui::Textfield& textfield, gui::Dropdown& settings_dropdown, gui::Layout& layout, gui::DrawStructure& base); diff --git a/Application/src/tracker/main.cpp b/Application/src/tracker/main.cpp index 1ce40a2..6752dbd 100644 --- a/Application/src/tracker/main.cpp +++ b/Application/src/tracker/main.cpp @@ -936,11 +936,11 @@ int main(int argc, char** argv) Tracker::auto_calculate_parameters(video); - if(SETTING(manual_identities).value<std::set<uint32_t>>().empty() && SETTING(track_max_individuals).value<uint32_t>() != 0) + if(SETTING(manual_identities).value<std::set<track::Idx_t>>().empty() && SETTING(track_max_individuals).value<uint32_t>() != 0) { - std::set<uint32_t> vector; + std::set<track::Idx_t> vector; for(uint32_t i=0; i<SETTING(track_max_individuals).value<uint32_t>(); ++i) { - vector.insert(i); + vector.insert(track::Idx_t(i)); } SETTING(manual_identities) = vector; } @@ -1131,7 +1131,7 @@ int main(int argc, char** argv) analysis = std::make_shared<ConnectedTasks>(tasks); analysis->start(// main thread [&]() { - auto endframe = tracker.end_frame(); + auto endframe = (long_t)tracker.end_frame(); if(currentID > endframe + cache_size || currentID == -1 || (analysis->stage_empty(0) && analysis->stage_empty(1)) diff --git a/Application/src/tracker/misc/MemoryStats.cpp b/Application/src/tracker/misc/MemoryStats.cpp index 882a082..3b92a82 100644 --- a/Application/src/tracker/misc/MemoryStats.cpp +++ b/Application/src/tracker/misc/MemoryStats.cpp @@ -5,6 +5,10 @@ namespace mem { +uint64_t memory_selector(MemoryStats& stats, const Idx_t& obj, const std::string& name) { + return sizeof(Idx_t); +} + template <typename K, typename V> uint64_t memory_selector(MemoryStats& stats, const std::map<K, V>& map, const std::string& name) { //using map_t = typename remove_cvref<decltype(map)>::type; @@ -227,7 +231,7 @@ TrackerMemoryStats::TrackerMemoryStats() { sizes["fois"] = foi_bytes; bytes += foi_bytes; - id = -2; + id = Idx_t(std::numeric_limits<uint32_t>::max()-1); } IndividualMemoryStats::IndividualMemoryStats(Individual *fish) { @@ -306,7 +310,7 @@ OutputLibraryMemoryStats::OutputLibraryMemoryStats(Output::LibraryCache::Ptr ptr } bytes += sizeof(decltype(cache)::element_type); - id = -2; + id = Idx_t(std::numeric_limits<uint32_t>::max()-1); } void IndividualMemoryStats::print() const { @@ -336,7 +340,7 @@ void MemoryStats::print() const { auto str = prettify_array(Meta::toStr(vec)); auto overall = Meta::toStr(FileSize{bytes}); - auto id_str = id == -2 ? std::string("overall") : (id == -1 ? "<empty>" : Meta::toStr(id)); + auto id_str = id == Idx_t(std::numeric_limits<uint32_t>::max()-1) ? std::string("overall") : (!id.valid() ? "<empty>" : Meta::toStr(id)); Debug("%S: %S\n%S", &id_str, &overall, &str); } diff --git a/Application/src/tracker/misc/MemoryStats.h b/Application/src/tracker/misc/MemoryStats.h index 9ab7b5d..f9ec704 100644 --- a/Application/src/tracker/misc/MemoryStats.h +++ b/Application/src/tracker/misc/MemoryStats.h @@ -3,6 +3,7 @@ #include <types.h> #include <tracking/Individual.h> #include <misc/OutputLibrary.h> +#include <misc/idx_t.h> namespace mem { using namespace track; @@ -10,7 +11,7 @@ using namespace track; struct MemoryStats { MemoryStats(); - idx_t id; + Idx_t id; uint64_t bytes; std::map<std::string, uint64_t> sizes; std::map<std::string, std::map<std::string, uint64_t>> details; @@ -21,7 +22,7 @@ struct MemoryStats { } void operator +=(const MemoryStats& other) { - if(id == -1) { + if(!id.valid()) { *this = other; return; } @@ -37,12 +38,12 @@ struct MemoryStats { } } - id = -2; + id = Idx_t(std::numeric_limits<uint32_t>::max()-1); } void clear() { bytes = 0; - id = -1; + id = Idx_t(); sizes.clear(); } virtual void print() const; diff --git a/Application/src/tracker/misc/Output.cpp b/Application/src/tracker/misc/Output.cpp index fc09645..4e54773 100644 --- a/Application/src/tracker/misc/Output.cpp +++ b/Application/src/tracker/misc/Output.cpp @@ -1036,7 +1036,7 @@ namespace Output { return pack_size; } - void ResultsFormat::write_file(const std::vector<track::FrameProperties> &frames, const std::unordered_map<long_t, Tracker::set_of_individuals_t > &active_individuals_frame, const std::unordered_map<idx_t, Individual *> &individuals, const std::vector<std::string>& exclude_settings) + void ResultsFormat::write_file(const std::vector<track::FrameProperties> &frames, const std::unordered_map<long_t, Tracker::set_of_individuals_t > &active_individuals_frame, const std::unordered_map<Idx_t, Individual *> &individuals, const std::vector<std::string>& exclude_settings) { estimated_size = sizeof(uint64_t)*3 + frames.size() * (sizeof(data_long_t)+sizeof(CompatibilityFrameProperties)) + active_individuals_frame.size() * (sizeof(data_long_t)+sizeof(uint64_t)+(active_individuals_frame.empty() ? individuals.size() : active_individuals_frame.begin()->second.size())*sizeof(data_long_t)); @@ -1166,7 +1166,7 @@ void TrackingResults::update_fois(const std::function<void(const std::string&, f const track::FrameProperties* prev_props = nullptr; data_long_t prev_frame = -1; - std::unordered_map<long_t, Individual::segment_map::const_iterator> iterator_map; + std::unordered_map<Idx_t, Individual::segment_map::const_iterator> iterator_map; for(const auto &props : _tracker._added_frames) { prev_time = props.time; @@ -1338,7 +1338,7 @@ void TrackingResults::update_fois(const std::function<void(const std::string&, f if(biggest_id < fish->identity().ID()) biggest_id = fish->identity().ID(); map_id_ptr[fish->identity().ID()] = fish; - _tracker._individuals[(long_t)fish->identity().ID()] = fish; + _tracker._individuals[fish->identity().ID()] = fish; } } @@ -1429,9 +1429,9 @@ void TrackingResults::update_fois(const std::function<void(const std::string&, f } if(config.has("gui_focus_group")) { - SETTING(gui_focus_group) = config["gui_focus_group"].value<std::vector<uint32_t>>(); + SETTING(gui_focus_group) = config["gui_focus_group"].value<std::vector<Idx_t>>(); } else - SETTING(gui_focus_group) = std::vector<uint32_t>{}; + SETTING(gui_focus_group) = std::vector<Idx_t>{}; SETTING(gui_frame).value<long_t>() = (long_t)file.header().gui_frame; } diff --git a/Application/src/tracker/misc/Output.h b/Application/src/tracker/misc/Output.h index 4a33e92..6591193 100644 --- a/Application/src/tracker/misc/Output.h +++ b/Application/src/tracker/misc/Output.h @@ -152,7 +152,7 @@ namespace Output { uint64_t write_data(uint64_t num_bytes, const char* buffer) override; static uint64_t estimate_individual_size(const Individual& val); - void write_file(const std::vector<track::FrameProperties>& frames, const std::unordered_map<long_t, Tracker::set_of_individuals_t>& active_individuals_frame, const std::unordered_map<idx_t, Individual*>& individuals, const std::vector<std::string>& exclude_settings); + void write_file(const std::vector<track::FrameProperties>& frames, const std::unordered_map<long_t, Tracker::set_of_individuals_t>& active_individuals_frame, const std::unordered_map<Idx_t, Individual*>& individuals, const std::vector<std::string>& exclude_settings); Individual* read_individual(Data& ref, const CacheHints* cache); Midline::Ptr read_midline(Data& ref); diff --git a/Application/src/tracker/misc/default_config.cpp b/Application/src/tracker/misc/default_config.cpp index fbcd285..14adffc 100644 --- a/Application/src/tracker/misc/default_config.cpp +++ b/Application/src/tracker/misc/default_config.cpp @@ -2,6 +2,7 @@ #include <misc/SpriteMap.h> #include <file/Path.h> #include <misc/BlobSizeRange.h> +#include <misc/idx_t.h> #include "GitSHA1.h" #ifndef WIN32 @@ -238,7 +239,7 @@ file::Path conda_environment_path() { Adding adding(config, docs, fn); CONFIG<std::string>("app_name", "TRex", "Name of the application.", SYSTEM); - CONFIG("version", std::string("1.0.4"), "Current application version.", SYSTEM); + CONFIG("version", std::string("1.0.5"), "Current application version.", SYSTEM); CONFIG("build_type", std::string(g_TREX_BUILD_TYPE), "The mode the application was built in.", SYSTEM); CONFIG("build_is_debug", std::string(is_ndebug_enabled()), "If built in debug mode, this will show 'debug'.", SYSTEM); CONFIG("build_cxx_options", std::string(g_TREX_BUILD_CXX_OPTIONS), "The mode the application was built in.", SYSTEM); @@ -370,7 +371,7 @@ file::Path conda_environment_path() { CONFIG("midline_start_with_head", false, "If enabled, the midline is going to be estimated starting at the head instead of the tail."); CONFIG("midline_invert", false, "If enabled, all midlines will be inverted (tail/head swapped)."); CONFIG("peak_mode", peak_mode_t::pointy, "This determines whether the tail of an individual should be expected to be pointy or broad."); - CONFIG("manual_matches", std::map<long_t, std::map<idx_t, int64_t>>{ }, "A map of manually defined matches (also updated by GUI menu for assigning manual identities). {{frame: {fish0: blob2, fish1: blob0}}, ...}"); + CONFIG("manual_matches", std::map<long_t, std::map<track::Idx_t, int64_t>>{ }, "A map of manually defined matches (also updated by GUI menu for assigning manual identities). {{frame: {fish0: blob2, fish1: blob0}}, ...}"); CONFIG("manual_splits", std::map<long_t, std::set<int64_t>>{}, "This map contains {frame: [blobid1,blobid2,...]} where frame and blobid are integers. When this is read during tracking for a frame, the tracker will attempt to force-split the given blob ids."); CONFIG("match_mode", matching_mode_t::accurate, "Changes the default algorithm to be used for matching blobs in one frame to blobs in the next frame. The accurate algorithm performs best, but also scales less well for more individuals than the approximate one. However, if it is too slow (temporarily) in a few frames, the program falls back to using the approximate one that doesnt slow down."); CONFIG("matching_probability_threshold", float(0.1), "The probability below which a possible connection between blob and identity is considered too low. The probability depends largely upon settings like `track_max_speed`."); @@ -399,7 +400,7 @@ file::Path conda_environment_path() { CONFIG("enable_absolute_difference", true, "If set to true, the threshold values will be applied to abs(image - background). Otherwise max(0, image - background)."); CONFIG("track_time_probability_enabled", bool(true), ""); CONFIG("track_max_reassign_time", float(0.5), "Distance in time (seconds) where the matcher will stop trying to reassign an individual based on previous position. After this time runs out, depending on the settings, the tracker will try to find it based on other criteria, or generate a new individual."); - CONFIG("manual_identities", std::set<uint32_t>{}, "", SYSTEM); + CONFIG("manual_identities", std::set<track::Idx_t>{}, "", SYSTEM); CONFIG("pixel_grid_cells", size_t(25), ""); CONFIG("web_quality", int(75), "JPEG quality of images transferred over the web interface."); @@ -538,7 +539,7 @@ file::Path conda_environment_path() { CONFIG("terminate_training", bool(false), "Setting this to true aborts the training in progress."); CONFIG("manually_approved", std::map<long_t,long_t>(), "A list of ranges of manually approved frames that may be used for generating training datasets {232:232,5555:5560}."); - CONFIG("gui_focus_group", std::vector<uint32_t>(), "Focus on this group of individuals."); + CONFIG("gui_focus_group", std::vector<Idx_t>(), "Focus on this group of individuals."); CONFIG("track_ignore", std::vector<std::vector<Vec2>>(), "If this is not empty, objects within the given rectangles or polygons (>= 3 points) [[x0,y0],[x1,y1](, ...)], ...] will be ignored during tracking."); CONFIG("track_include", std::vector<std::vector<Vec2>>(), "If this is not empty, objects within the given rectangles or polygons (>= 3 points) [[x0,y0],[x1,y1](, ...)], ...] will be the only objects being tracked. (overwrites `track_ignore`)"); diff --git a/Application/src/tracker/misc/idx_t.cpp b/Application/src/tracker/misc/idx_t.cpp new file mode 100644 index 0000000..82dcdf4 --- /dev/null +++ b/Application/src/tracker/misc/idx_t.cpp @@ -0,0 +1,14 @@ +#include "idx_t.h" +#include <misc/metastring.h> + +namespace track { + +/*Idx_t::operator std::string() const { + return Meta::toStr(_identity); +}*/ + +Idx_t Idx_t::fromStr(const std::string& str) { + return Idx_t(Meta::fromStr<uint32_t>(str)); +} + +} diff --git a/Application/src/tracker/misc/idx_t.h b/Application/src/tracker/misc/idx_t.h new file mode 100644 index 0000000..e2a2d87 --- /dev/null +++ b/Application/src/tracker/misc/idx_t.h @@ -0,0 +1,50 @@ +#pragma once +#include <commons.pc.h> +#include <misc/checked_casts.h> + +namespace track { + +struct Idx_t { + uint32_t _identity = infinity<uint32_t>(); + constexpr Idx_t() = default; + template<typename T> + explicit constexpr Idx_t(T ID) : _identity(cmn::narrow_cast<uint32_t>(ID)) {} + constexpr operator uint32_t() const { return _identity; } + constexpr bool valid() const { return _identity != infinity<uint32_t>(); } + + static std::string class_name() { return "Idx_t"; } + //operator std::string() const; + static Idx_t fromStr(const std::string&); +}; + +struct Frame_t { + long_t _frame = infinity<long_t>(); + constexpr Frame_t() = default; + explicit constexpr Frame_t(long_t frame) : _frame(frame) {} + constexpr operator long_t() const { return _frame; } + constexpr bool valid() const { return _frame != infinity<long_t>(); } + constexpr Frame_t& operator+=(Frame_t&& other) { + assert(valid() && other.valid()); + _frame += other._frame; + return *this; + } + constexpr Frame_t& operator+=(long_t&& other) { + assert(valid() && other != infinity<long_t>()); + _frame += other; + return *this; + } +}; + +} + +namespace std +{ + template<> + struct hash<track::Idx_t> + { + size_t operator()(const track::Idx_t& k) const + { + return std::hash<uint32_t>{}((uint32_t)k); + } + }; +} diff --git a/Application/src/tracker/python/GPURecognition.h b/Application/src/tracker/python/GPURecognition.h index d21ec6d..795e2bb 100644 --- a/Application/src/tracker/python/GPURecognition.h +++ b/Application/src/tracker/python/GPURecognition.h @@ -15,16 +15,17 @@ #include <misc/Image.h> #include <misc/SoftException.h> #include <misc/GlobalSettings.h> +#include <misc/idx_t.h> namespace track { using namespace cmn; class TREX_EXPORT PythonIntegration { std::atomic_bool _terminate; - std::map<idx_t, std::deque<std::tuple<long_t, Image::Ptr>>> _classes; - std::map<idx_t, std::set<long_t>> _received; - std::map<idx_t, std::set<long_t>> _sent_to_training; - std::map<idx_t, std::vector<Image::Ptr>> _test_data; + std::map<Idx_t, std::deque<std::tuple<long_t, Image::Ptr>>> _classes; + std::map<Idx_t, std::set<long_t>> _received; + std::map<Idx_t, std::set<long_t>> _sent_to_training; + std::map<Idx_t, std::vector<Image::Ptr>> _test_data; std::queue<std::packaged_task<bool()>> tasks; diff --git a/Application/src/tracker/tracking/Accumulation.cpp b/Application/src/tracker/tracking/Accumulation.cpp index 5bd8295..5365840 100644 --- a/Application/src/tracker/tracking/Accumulation.cpp +++ b/Application/src/tracker/tracking/Accumulation.cpp @@ -111,9 +111,9 @@ Accumulation* Accumulation::current() { return _current_accumulation; } -std::map<long_t, std::set<long_t>> Accumulation::generate_individuals_per_frame(const Rangel& range, TrainingData* data, std::map<long_t, std::set<std::shared_ptr<Individual::SegmentInformation>>>* coverage) { +std::map<Frame_t, std::set<Idx_t>> Accumulation::generate_individuals_per_frame(const Rangel& range, TrainingData* data, std::map<Idx_t, std::set<std::shared_ptr<Individual::SegmentInformation>>>* coverage) { Tracker::LockGuard guard("Accumulation::generate_individuals_per_frame"); - std::map<long_t, std::set<long_t>> individuals_per_frame; + std::map<Frame_t, std::set<Idx_t>> individuals_per_frame; const bool calculate_posture = FAST_SETTINGS(calculate_posture); for(auto id : FAST_SETTINGS(manual_identities)) { @@ -143,7 +143,7 @@ std::map<long_t, std::set<long_t>> Accumulation::generate_individuals_per_frame( it->second->iterate_frames(overall_range, [&individuals_per_frame, id, &used_segments, ¤t_segment, calculate_posture](long_t frame, const std::shared_ptr<Individual::SegmentInformation>& segment, const std::shared_ptr<Individual::BasicStuff> & basic, const std::shared_ptr<Individual::PostureStuff> & posture) -> bool { if(basic && (posture || !calculate_posture)) { - individuals_per_frame[frame].insert(id); + individuals_per_frame[Frame_t(frame)].insert(Idx_t(id)); if(segment != current_segment) { used_segments.insert(segment); current_segment = segment; @@ -159,12 +159,12 @@ std::map<long_t, std::set<long_t>> Accumulation::generate_individuals_per_frame( if(data) { for(auto &segment : used_segments) { - data->filters().set(id, *segment, Tracker::recognition()->local_midline_length(it->second, segment->range, false)); + data->filters().set(Idx_t(id), *segment, Tracker::recognition()->local_midline_length(it->second, segment->range, false)); } } if(coverage) - (*coverage)[id].insert(used_segments.begin(), used_segments.end()); + (*coverage)[Idx_t(id)].insert(used_segments.begin(), used_segments.end()); } /*std::map<long_t, long_t> lengths; @@ -178,7 +178,7 @@ std::map<long_t, std::set<long_t>> Accumulation::generate_individuals_per_frame( return individuals_per_frame; } -std::tuple<bool, std::map<long_t, long_t>> Accumulation::check_additional_range(const Rangel& range, TrainingData& data, bool check_length, DatasetQuality::Quality quality) { +std::tuple<bool, std::map<Idx_t, Idx_t>> Accumulation::check_additional_range(const Rangel& range, TrainingData& data, bool check_length, DatasetQuality::Quality quality) { const float pure_chance = 1.f / FAST_SETTINGS(manual_identities).size(); // data.set_normalized(SETTING(recognition_normalization).value<default_config::recognition_normalization_t::Class>()); @@ -186,18 +186,18 @@ std::tuple<bool, std::map<long_t, long_t>> Accumulation::check_additional_range( Tracker::LockGuard guard("Accumulation::generate_training_data"); GUI::work().set_progress("generating images", 0); - std::map<long_t, std::set<std::shared_ptr<Individual::SegmentInformation>>> segments; + std::map<Idx_t, std::set<std::shared_ptr<Individual::SegmentInformation>>> segments; auto coverage = generate_individuals_per_frame(range, &data, &segments); if(check_length) { - std::map<long_t, size_t> counts; + std::map<Idx_t, size_t> counts; for(auto && [frame, ids] : coverage) { for(auto id : ids) ++counts[id]; } size_t min_size = std::numeric_limits<size_t>::max(), max_size = 0; - long_t min_id = -1; + Idx_t min_id; for(auto && [id, count] : counts) { if(count < min_size) { @@ -228,13 +228,13 @@ std::tuple<bool, std::map<long_t, long_t>> Accumulation::check_additional_range( Tracker::LockGuard guard("Accumulation::generate_training_data"); - std::map<long_t, std::tuple<float, std::vector<float>>> averages; + std::map<Idx_t, std::tuple<float, std::vector<float>>> averages; for(auto id : FAST_SETTINGS(manual_identities)) { - std::get<1>(averages[id]).resize(FAST_SETTINGS(manual_identities).size()); - std::get<0>(averages[id]) = 0; + std::get<1>(averages[Idx_t(id)]).resize(FAST_SETTINGS(manual_identities).size()); + std::get<0>(averages[Idx_t(id)]) = 0; } - std::set<long_t> added_ids, not_added_ids; + std::set<Idx_t> added_ids, not_added_ids; for(size_t i=0; i<images.size(); ++i) { auto & ps = probabilities[i]; @@ -253,9 +253,9 @@ std::tuple<bool, std::map<long_t, long_t>> Accumulation::check_additional_range( auto str1 = Meta::toStr(not_added_ids); Debug("\tCalculated assignments for range %d-%d based on previous training (ids %S / missing %S):", range.start, range.end, &str, &str1); - std::map<long_t, long_t> max_indexes; - std::map<long_t, float> max_probs; - std::map<long_t, std::tuple<long_t, float>> print_out; + std::map<Idx_t, Idx_t> max_indexes; + std::map<Idx_t, float> max_probs; + std::map<Idx_t, std::tuple<long_t, float>> print_out; for(auto && [id, tup] : averages) { auto & [samples, values] = tup; @@ -274,9 +274,11 @@ std::tuple<bool, std::map<long_t, long_t>> Accumulation::check_additional_range( } } + assert(max_index >= 0); + auto str = Meta::toStr(values); Debug("\t\t%d: %S (%f, %d = %f)", id, &str, samples, max_index, max_p); - max_indexes[id] = max_index; + max_indexes[id] = Idx_t((uint32_t)max_index); max_probs[id] = max_p; print_out[id] = {max_index, max_p}; } @@ -284,7 +286,7 @@ std::tuple<bool, std::map<long_t, long_t>> Accumulation::check_additional_range( str = Meta::toStr(print_out); Debug("%S", &str); - std::set<long_t> unique_ids; + std::set<Idx_t> unique_ids; float min_prob = std::numeric_limits<float>::infinity(); for(auto && [my_id, p] : max_probs) min_prob = min(min_prob, p); @@ -294,7 +296,9 @@ std::tuple<bool, std::map<long_t, long_t>> Accumulation::check_additional_range( if(unique_ids.size() == FAST_SETTINGS(manual_identities).size() - 1 && min_prob > pure_chance * 1.5) { Debug("\tOnly one missing id in predicted ids. Guessing solution..."); - long_t missing_predicted_id=0; + + //! Searching for consecutive numbers, finding the gap + Idx_t missing_predicted_id(0); for(auto id : unique_ids) { if(id != missing_predicted_id) { // missing id i @@ -302,12 +306,12 @@ std::tuple<bool, std::map<long_t, long_t>> Accumulation::check_additional_range( break; } - ++missing_predicted_id; + missing_predicted_id = Idx_t((uint32_t)missing_predicted_id + 1u); } // find out which one is double - long_t original_id0 = -1, original_id1 = -1; - std::map<long_t, long_t> assign; + Idx_t original_id0, original_id1; + std::map<Idx_t, Idx_t> assign; for(auto && [my_id, pred_id] : max_indexes) { if(assign.count(pred_id)) { original_id0 = my_id; @@ -318,7 +322,7 @@ std::tuple<bool, std::map<long_t, long_t>> Accumulation::check_additional_range( assign[pred_id] = my_id; } } - assert(original_id1 != -1); + assert(original_id1.valid()); Debug("\tPossible choices are %d (%f) and %d (%f).", original_id0, max_probs.at(original_id0), original_id1, max_probs.at(original_id1)); @@ -407,7 +411,7 @@ void Accumulation::update_coverage(const TrainingData &data) { }); } -std::tuple<std::shared_ptr<TrainingData>, std::vector<Image::Ptr>, std::map<long_t, Range<size_t>>> Accumulation::generate_discrimination_data(const std::shared_ptr<TrainingData>& source) +std::tuple<std::shared_ptr<TrainingData>, std::vector<Image::Ptr>, std::map<Frame_t, Range<size_t>>> Accumulation::generate_discrimination_data(const std::shared_ptr<TrainingData>& source) { auto data = std::make_shared<TrainingData>(); @@ -423,9 +427,9 @@ std::tuple<std::shared_ptr<TrainingData>, std::vector<Image::Ptr>, std::map<long auto analysis_range = Tracker::analysis_range(); auto &individuals = Tracker::individuals(); - std::map<long_t, std::set<long_t>> disc_individuals_per_frame; + std::map<Frame_t, std::set<Idx_t>> disc_individuals_per_frame; - for(long_t frame = analysis_range.start; frame <= analysis_range.end; frame += max(1, analysis_range.length() / 333)) + for(Frame_t frame(analysis_range.start); frame <= analysis_range.end; frame += max(1, analysis_range.length() / 333)) { if(frame < Tracker::start_frame()) continue; @@ -444,10 +448,10 @@ std::tuple<std::shared_ptr<TrainingData>, std::vector<Image::Ptr>, std::map<long { auto frange = fish->get_segment(frame); if(frange.contains(frame)) { - if(!data->filters().has(id, frange)) { - data->filters().set(id, frange, Tracker::recognition()->local_midline_length(fish, frame, false)); + if(!data->filters().has(Idx_t(id), frange)) { + data->filters().set(Idx_t(id), frange, Tracker::recognition()->local_midline_length(fish, frame, false)); } - disc_individuals_per_frame[frame].insert(id); + disc_individuals_per_frame[frame].insert(Idx_t(id)); } } } @@ -468,7 +472,7 @@ std::tuple<std::shared_ptr<TrainingData>, std::vector<Image::Ptr>, std::map<long return {data, disc_images, disc_frame_map}; } -std::tuple<float, std::map<uint32_t, float>, float> Accumulation::calculate_uniqueness(bool internal, const std::vector<Image::Ptr>& images, const std::map<long_t, Range<size_t>>& map_indexes) +std::tuple<float, std::map<Frame_t, float>, float> Accumulation::calculate_uniqueness(bool internal, const std::vector<Image::Ptr>& images, const std::map<Frame_t, Range<size_t>>& map_indexes) { std::vector<std::vector<float>> predictions; if(internal) { @@ -513,18 +517,18 @@ std::tuple<float, std::map<uint32_t, float>, float> Accumulation::calculate_uniq size_t good_frames = 0; size_t bad_frames = 0; double percentages = 0, rpercentages = 0; - std::map<uint32_t, float> unique_percent; - std::map<uint32_t, float> unique_percent_raw; + std::map<Frame_t, float> unique_percent; + std::map<Frame_t, float> unique_percent_raw; - std::map<uint32_t, float> unique_percent_per_identity; - std::map<uint32_t, float> per_identity_samples; + std::map<Idx_t, float> unique_percent_per_identity; + std::map<Idx_t, float> per_identity_samples; for(auto && [frame, range] : map_indexes) { - std::set<uint32_t> unique_ids; - std::map<uint32_t, float> probs; + std::set<Idx_t> unique_ids; + std::map<Idx_t, float> probs; for (auto i = range.start; i < range.end; ++i) { - int64_t max_id = -1; + Idx_t max_id; float max_p = 0; if(predictions.at(i).size() < FAST_SETTINGS(manual_identities).size()) { @@ -536,13 +540,13 @@ std::tuple<float, std::map<uint32_t, float>, float> Accumulation::calculate_uniq auto p = predictions.at(i).at(id); if(p > max_p) { max_p = p; - max_id = id; + max_id = Idx_t(id); } } - if(max_id != -1) { - unique_ids.insert((uint32_t)max_id); - probs[(uint32_t)max_id] = max(probs[(uint32_t)max_id], max_p); + if(max_id.valid()) { + unique_ids.insert(max_id); + probs[max_id] = max(probs[max_id], max_p); } } @@ -555,19 +559,19 @@ std::tuple<float, std::map<uint32_t, float>, float> Accumulation::calculate_uniq } auto logic_regression = [](float x) { - static const float NORMAL = (1+expf(-1*M_PI*1)); + static const float NORMAL = (1+expf(-1*float(M_PI)*1)); return 1/(1+exp(-x*M_PI*1))*NORMAL; //return 1.f/(1.f+expf(-x*10)); }; - unique_percent_raw[frame] = p; + unique_percent_raw[frame] = float(p); rpercentages += p; if(!probs.empty()) p = logic_regression(accum_p / float(probs.size())) * p; //p = (accum_p / float(probs.size()) + p) * 0.5; - unique_percent[frame] = p; + unique_percent[frame] = float(p); percentages += p; if(unique_ids.size() == range.length() - 1) { @@ -658,7 +662,8 @@ bool Accumulation::start() { Accumulation::setup(); auto data = std::make_shared<TrainingData>(); - data->set_classes(FAST_SETTINGS(manual_identities)); + auto manual = FAST_SETTINGS(manual_identities); + data->set_classes(std::set<Idx_t>(manual.begin(), manual.end())); auto result = Recognition::train(data, FrameRange(), TrainingMode::Apply, -1, true); if(result) { @@ -768,7 +773,7 @@ bool Accumulation::start() { auto ranges_path = pv::DataLocation::parse("output", Path(SETTING(filename).value<file::Path>().filename()+"_validation_data.npz")); const Size2 dims = SETTING(recognition_image_size); - FileSize size((data.validation_images.size() + data.training_images.size()) * dims.width * dims.height); + FileSize size((data.validation_images.size() + data.training_images.size()) * size_t(dims.width * dims.height)); std::vector<uchar> all_images; all_images.resize(size.bytes); @@ -876,9 +881,9 @@ bool Accumulation::start() { range_distance = min(r.start - range.end, range_distance); } - const long frames_around_center = max(1, analysis_range.length() * 0.1); + const long frames_around_center = max(1, analysis_range.length() / 10); - auto center = range.length() * 0.5 + range.start; + auto center = range.length() / 2 + range.start; FrameRange extended_range(Rangel( max(analysis_range.start, center - frames_around_center), min(analysis_range.end, center + frames_around_center)) @@ -901,7 +906,7 @@ bool Accumulation::start() { if(distance < min_distance) min_distance = distance; //distance = roundf((1 - SQR(average)) * 10) * 10; - range_distance = next_pow2(range_distance); + range_distance = narrow_cast<int64_t>(next_pow2(range_distance)); copied_sorted.insert({distance, range_distance, q, cached, range, extended_range, samples}); } else { @@ -1085,7 +1090,7 @@ bool Accumulation::start() { //} } - if(acceptance) { + if(acceptance > 0) { _added_ranges.push_back(range); auto str = Meta::toStr(*second_data); @@ -1153,7 +1158,7 @@ bool Accumulation::start() { return {false, success ? second_data : nullptr}; }; - auto update_meta_start_acc = [&](std::string prefix, Rangel next_range, DatasetQuality::Quality quality, float average_unique) { + auto update_meta_start_acc = [&](std::string prefix, Rangel next_range, DatasetQuality::Quality quality, double average_unique) { Debug(""); auto qual_str = Meta::toStr(quality); Debug("[Accumulation %d%S] %d ranges remaining for accumulation (%d cached that did not predict unique ids yet), range %d-%d (%S, %f unique weight).", steps, &prefix, sorted.size(), tried_ranges.size(), next_range.start, next_range.end, &qual_str, average_unique); @@ -1172,12 +1177,12 @@ bool Accumulation::start() { return false; } - std::map<long_t, size_t> sizes; + std::map<Idx_t, int64_t> sizes; for(auto id : FAST_SETTINGS(manual_identities)) { - sizes[id] = 0; + sizes[Idx_t(id)] = 0; } - std::map<long_t, std::set<FrameRange>> assigned_ranges; + std::map<Idx_t, std::set<FrameRange>> assigned_ranges; for(auto & d : _collected_data->data()) { /*for(auto && [id, per] : d->mappings) { @@ -1193,8 +1198,8 @@ bool Accumulation::start() { } } - std::map<long_t, std::set<FrameRange>> gaps; - std::map<long_t, long_t> frame_gaps; + std::map<Idx_t, std::set<FrameRange>> gaps; + std::map<Idx_t, long_t> frame_gaps; for(auto && [id, ranges] : assigned_ranges) { long_t previous_frame = analysis_range.start; @@ -1367,7 +1372,7 @@ bool Accumulation::start() { } if(!GUI::work().item_aborted() && SETTING(gpu_accumulation_enable_final_step)) { - std::map<long_t, size_t> images_per_class; + std::map<Idx_t, size_t> images_per_class; size_t overall_images = 0; for(auto &d : _collected_data->data()) { for(auto &image : d->images) { @@ -1463,8 +1468,8 @@ bool Accumulation::start() { Collect all frames for all individuals. Then generate all frames for all normalization methods. */ - std::map<long_t, std::set<long_t>> frames_collected; - std::map<long_t, std::map<long_t, long_t>> frames_assignment; + std::map<long_t, std::set<Idx_t>> frames_collected; + std::map<long_t, std::map<Idx_t, Idx_t>> frames_assignment; for(auto &data : _collected_data->data()) { for(auto && [id, per] : data->mappings) { auto org = data->unmap(id); @@ -1477,7 +1482,7 @@ bool Accumulation::start() { for(auto method : default_config::recognition_normalization_t::values) { - std::map<long_t, std::vector<Image::Ptr>> images; + std::map<Idx_t, std::vector<Image::Ptr>> images; PPFrame video_frame; auto &video_file = *GUI::instance()->video_source(); @@ -1538,7 +1543,7 @@ bool Accumulation::start() { using namespace default_config; auto midline = posture ? fish->calculate_midline_for(basic, posture) : nullptr; - Recognition::ImageData image_data(Recognition::ImageData::Blob{blob->num_pixels(), blob->blob_id(), -1, blob->parent_id(), blob->bounds()}, frame, (FrameRange)(*it->get()), fish, fish->identity().ID(), midline ? midline->transform(method) : gui::Transform()); + Recognition::ImageData image_data(Recognition::ImageData::Blob{blob->num_pixels(), blob->blob_id(), -1, blob->parent_id(), blob->bounds()}, frame, (FrameRange)(*it->get()), fish, Idx_t(fish->identity().ID()), midline ? midline->transform(method) : gui::Transform()); image_data.filters = std::make_shared<TrainingFilterConstraints>(filters); image = Recognition::calculate_diff_image_with_settings(method, blob, image_data, output_size); @@ -1560,7 +1565,7 @@ bool Accumulation::start() { const Size2 dims = SETTING(recognition_image_size); - std::vector<long_t> ids; + std::vector<Idx_t> ids; size_t total_images = 0; for(auto && [id, img]: images) { ids.insert(ids.end(), img.size(), id); diff --git a/Application/src/tracker/tracking/Accumulation.h b/Application/src/tracker/tracking/Accumulation.h index 215cdfe..8a61f70 100644 --- a/Application/src/tracker/tracking/Accumulation.h +++ b/Application/src/tracker/tracking/Accumulation.h @@ -45,9 +45,9 @@ class Accumulation { std::shared_ptr<TrainingData> _collected_data, _generated_data; std::shared_ptr<TrainingData> _discrimination_data; std::vector<Image::Ptr> _disc_images; - std::map<long_t, Range<size_t>> _disc_frame_map; + std::map<Frame_t, Range<size_t>> _disc_frame_map; std::vector<long_t> _checked_ranges_output; - std::map<uint32_t, float> unique_map, temp_unique; + std::map<Frame_t, float> unique_map, temp_unique; std::map<Rangel, std::tuple<double, FrameRange>> assigned_unique_averages; size_t _accumulation_step; size_t _counted_steps, _last_step; @@ -84,13 +84,13 @@ public: bool start(); static float good_uniqueness(); - std::map<long_t, std::set<long_t>> generate_individuals_per_frame(const Rangel& range, TrainingData* data, std::map<long_t, std::set<std::shared_ptr<Individual::SegmentInformation>>>*); - std::tuple<bool, std::map<long_t, long_t>> check_additional_range(const Rangel& range, TrainingData& data, bool check_length, DatasetQuality::Quality); + std::map<Frame_t, std::set<Idx_t>> generate_individuals_per_frame(const Rangel& range, TrainingData* data, std::map<Idx_t, std::set<std::shared_ptr<Individual::SegmentInformation>>>*); + std::tuple<bool, std::map<Idx_t, Idx_t>> check_additional_range(const Rangel& range, TrainingData& data, bool check_length, DatasetQuality::Quality); void confirm_weights(); void update_coverage(const TrainingData& data); - static std::tuple<float, std::map<uint32_t, float>, float> calculate_uniqueness(bool internal, const std::vector<Image::Ptr>&, const std::map<long_t, Range<size_t>>&); - static std::tuple<std::shared_ptr<TrainingData>, std::vector<Image::Ptr>, std::map<long_t, Range<size_t>>> generate_discrimination_data(const std::shared_ptr<TrainingData>& source = nullptr); + static std::tuple<float, std::map<Frame_t, float>, float> calculate_uniqueness(bool internal, const std::vector<Image::Ptr>&, const std::map<Frame_t, Range<size_t>>&); + static std::tuple<std::shared_ptr<TrainingData>, std::vector<Image::Ptr>, std::map<Frame_t, Range<size_t>>> generate_discrimination_data(const std::shared_ptr<TrainingData>& source = nullptr); static void setup(); static void unsetup(); static Accumulation* current(); @@ -98,7 +98,7 @@ public: private: Rangel _initial_range; - std::map<long_t, std::set<long_t>> individuals_per_frame; + std::map<Frame_t, std::set<Idx_t>> individuals_per_frame; //std::map<long_t, std::set<std::shared_ptr<Individual::SegmentInformation>>> overall_coverage; std::vector<Rangel> _added_ranges; std::vector<Rangel> _next_ranges; diff --git a/Application/src/tracker/tracking/DatasetQuality.cpp b/Application/src/tracker/tracking/DatasetQuality.cpp index 310d48f..1f4a534 100644 --- a/Application/src/tracker/tracking/DatasetQuality.cpp +++ b/Application/src/tracker/tracking/DatasetQuality.cpp @@ -125,7 +125,7 @@ bool DatasetQuality::calculate_segment(const Rangel &consec, const long_t video_ Tracker::instance()->thread_pool().wait(); - if(num_average) + if(num_average != 0) average_samples /= num_average; /*std::set<float> values; @@ -233,7 +233,7 @@ Rangel DatasetQuality::best_range() const { return Rangel(-1,-1); } -std::map<idx_t, DatasetQuality::Single> DatasetQuality::per_fish(const Rangel &range) const { +std::map<Idx_t, DatasetQuality::Single> DatasetQuality::per_fish(const Rangel &range) const { auto it = _cache.find(range); if(it == _cache.end()) return {}; @@ -245,7 +245,7 @@ bool DatasetQuality::has(const Rangel& range) const { return it != _cache.end() && !it->second.empty(); } -DatasetQuality::Single DatasetQuality::evaluate_single(idx_t id, Individual* fish, const Rangel &_consec, const Tracker::LockGuard&) +DatasetQuality::Single DatasetQuality::evaluate_single(Idx_t id, Individual* fish, const Rangel &_consec, const Tracker::LockGuard&) { //assert(Tracker::individuals().find(id) != Tracker::individuals().end()); diff --git a/Application/src/tracker/tracking/DatasetQuality.h b/Application/src/tracker/tracking/DatasetQuality.h index 6a25928..5beb26e 100644 --- a/Application/src/tracker/tracking/DatasetQuality.h +++ b/Application/src/tracker/tracking/DatasetQuality.h @@ -8,7 +8,7 @@ namespace track { class DatasetQuality { public: struct Single { - idx_t id; + Idx_t id; float midline_len; float midline_std; @@ -26,7 +26,7 @@ namespace track { long_t number_frames; - Single(idx_t id = infinity<idx_t>()) + Single(Idx_t id = Idx_t()) : id(id), midline_len(0), midline_std(0), distance_travelled(0), grid_cells_visited(0), median_angle_var(0), number_frames(0) { } @@ -65,7 +65,7 @@ namespace track { private: Rangel _manually_selected; - std::map<Rangel, std::map<idx_t, Single>> _cache; + std::map<Rangel, std::map<Idx_t, Single>> _cache; std::map<Rangel, Quality> _quality; Rangel _last_seen; std::set<Rangel> _previous_selected; @@ -81,13 +81,13 @@ namespace track { //Quality quality(float frame) const; bool has(const Rangel& range) const; Rangel best_range() const; - std::map<idx_t, Single> per_fish(const Rangel&) const; + std::map<Idx_t, Single> per_fish(const Rangel&) const; void print_info() const; private: void remove_segment(const Rangel& range); bool calculate_segment(const Rangel&, const long_t video_length, const Tracker::LockGuard&); - Single evaluate_single(idx_t id, Individual* fish, const Rangel& consec, const Tracker::LockGuard& guard); + Single evaluate_single(Idx_t id, Individual* fish, const Rangel& consec, const Tracker::LockGuard& guard); }; } diff --git a/Application/src/tracker/tracking/Export.cpp b/Application/src/tracker/tracking/Export.cpp index fd37d75..2f09abc 100644 --- a/Application/src/tracker/tracking/Export.cpp +++ b/Application/src/tracker/tracking/Export.cpp @@ -678,7 +678,7 @@ void export_data(Tracker& tracker, long_t fdx, const Rangel& range) { temporary_save(final_path, [&](file::Path path){ Debug("Generating memory stats..."); mem::IndividualMemoryStats overall; - std::map<track::idx_t, mem::IndividualMemoryStats> indstats; + std::map<track::Idx_t, mem::IndividualMemoryStats> indstats; for(auto && [fdx, fish] : tracker.individuals()) { mem::IndividualMemoryStats stats(fish); indstats[fdx] = stats; diff --git a/Application/src/tracker/tracking/Individual.cpp b/Application/src/tracker/tracking/Individual.cpp index 6718570..1ef71fc 100644 --- a/Application/src/tracker/tracking/Individual.cpp +++ b/Application/src/tracker/tracking/Individual.cpp @@ -2602,7 +2602,7 @@ void Individual::calculate_average_recognition() { _average_recognition_samples = 0; _average_recognition.clear(); - std::map<long_t, size_t> samples; + std::map<Idx_t, size_t> samples; const float frame_limit = FAST_SETTINGS(frame_rate) * 2; for(auto & segment : _frame_segments) { @@ -2707,7 +2707,7 @@ const decltype(Individual::average_recognition_segment)::mapped_type Individual: return {0, {}}; } - std::map<long_t, std::tuple<long_t, float>> samples; + std::map<Idx_t, std::tuple<long_t, float>> samples; size_t overall = 0; for(long_t i = segment.start; i < segment.end; ++i) { @@ -2720,14 +2720,14 @@ const decltype(Individual::average_recognition_segment)::mapped_type Individual: ++overall; for (auto && [fdx, p] : raw) { - ++std::get<0>(samples[fdx]); - std::get<1>(samples[fdx]) += p; + ++std::get<0>(samples[Idx_t(fdx)]); + std::get<1>(samples[Idx_t(fdx)]) += p; } } } if(overall > 0) { - std::map<long_t, float> average; + std::map<Idx_t, float> average; float s = 0; for (auto && [key, value] : samples) { float n = std::get<0>(value); @@ -2767,7 +2767,7 @@ const decltype(Individual::average_recognition_segment)::mapped_type Individual: return {0, {}}; } - std::map<long_t, std::tuple<long_t, float>> samples; + std::map<Idx_t, std::tuple<long_t, float>> samples; size_t overall = 0; for(long_t i = segment.start; i < segment.end; ++i) { @@ -2780,14 +2780,14 @@ const decltype(Individual::average_recognition_segment)::mapped_type Individual: ++overall; for (auto && [fdx, p] : raw) { - ++std::get<0>(samples[fdx]); - std::get<1>(samples[fdx]) += p; + ++std::get<0>(samples[Idx_t(fdx)]); + std::get<1>(samples[Idx_t(fdx)]) += p; } } } if(overall > 0) { - std::map<long_t, float> average; + std::map<Idx_t, float> average; float s = 0; for (auto && [key, value] : samples) { float n = std::get<0>(value); @@ -2808,17 +2808,17 @@ const decltype(Individual::average_recognition_segment)::mapped_type Individual: return average_recognition_segment.at(segment_start); } -std::tuple<size_t, long_t, float> Individual::average_recognition_identity(long_t segment_start) const { +std::tuple<size_t, Idx_t, float> Individual::average_recognition_identity(long_t segment_start) const { auto it = average_recognition_segment.find(segment_start); if(it == average_recognition_segment.end()) { - return {0, -1, 0}; + return {0, Idx_t(), 0}; } - long_t mdx = -1; + Idx_t mdx; float mdx_p = 0; for(auto && [fdx, p] : std::get<1>(it->second)) { - if(p > mdx_p) { + if(!mdx.valid() || p > mdx_p) { mdx_p = p; mdx = fdx; } diff --git a/Application/src/tracker/tracking/Individual.h b/Application/src/tracker/tracking/Individual.h index fdd1e0a..59171bd 100644 --- a/Application/src/tracker/tracking/Individual.h +++ b/Application/src/tracker/tracking/Individual.h @@ -2,6 +2,7 @@ #define _FISHP_H #include <types.h> +#include <tracker/misc/idx_t.h> #include <gui/colors.h> #include <misc/Blob.h> #include "Posture.h" @@ -92,7 +93,7 @@ namespace track { std::vector<std::shared_ptr<pv::Blob>> blobs, original_blobs; std::vector<std::shared_ptr<pv::Blob>> filtered_out; - std::map<uint32_t, IndividualCache> cached_individuals; + std::map<Idx_t, IndividualCache> cached_individuals; std::map<uint32_t, std::set<long_t>> blob_cliques, fish_cliques; std::set<uint32_t> split_blobs; std::map<uint32_t, pv::BlobPtr> bdx_to_ptr; @@ -118,7 +119,7 @@ namespace track { protected: GETTER_SETTER(gui::Color, color) - uint32_t _myID; + Idx_t _myID; std::string _name; GETTER_SETTER(bool, manual) @@ -129,7 +130,7 @@ namespace track { decltype(_myID) ID() const { return _myID; } void set_ID(uint32_t val) { _color = ColorWheel(val).next(); - _myID = val; + _myID = Idx_t(val); _name = Meta::toStr(_myID); } const std::string& raw_name(); @@ -276,12 +277,12 @@ namespace track { //! Contains a map with individual -> probability for the blob that has been // assigned to this individual. - std::map<long_t, std::tuple<size_t, std::map<long_t, float>>> average_recognition_segment; - std::map<long_t, std::tuple<size_t, std::map<long_t, float>>> average_processed_segment; + std::map<long_t, std::tuple<size_t, std::map<Idx_t, float>>> average_recognition_segment; + std::map<long_t, std::tuple<size_t, std::map<Idx_t, float>>> average_processed_segment; //! Contains a map from fish id to probability that averages over // all available segments when "check identities" was last clicked - std::map<long_t, float> _average_recognition; + std::map<Idx_t, float> _average_recognition; GETTER(size_t, average_recognition_samples) long_t _startFrame = -1, _endFrame = -1; @@ -390,7 +391,7 @@ namespace track { //const decltype(average_recognition_segment)::mapped_type& average_recognition(long_t segment_start) const; const decltype(average_recognition_segment)::mapped_type average_recognition(long_t segment_start); const decltype(average_recognition_segment)::mapped_type processed_recognition(long_t segment_start); - std::tuple<size_t, long_t, float> average_recognition_identity(long_t segment_start) const; + std::tuple<size_t, Idx_t, float> average_recognition_identity(long_t segment_start) const; //! Properties based on centroid: const PhysicalProperties* centroid(long_t frameIndex) const; diff --git a/Application/src/tracker/tracking/Recognition.cpp b/Application/src/tracker/tracking/Recognition.cpp index 244b508..5f91a54 100644 --- a/Application/src/tracker/tracking/Recognition.cpp +++ b/Application/src/tracker/tracking/Recognition.cpp @@ -270,15 +270,15 @@ std::unique_ptr<Image> Recognition::calculate_diff_image_with_settings(const def return false; }*/ - std::map<long_t, float> Recognition::ps_raw(long_t frame, uint32_t blob_id) { + std::map<Idx_t, float> Recognition::ps_raw(long_t frame, uint32_t blob_id) { std::lock_guard<std::mutex> probs_guard(_mutex); auto entry = probs.find(frame); if (entry != probs.end()) { auto it = entry->second.find(blob_id); if(it != entry->second.end()) { - std::map<long_t, float> map; + std::map<Idx_t, float> map; for (size_t i=0; i<it->second.size(); i++) { - map[fish_idx_to_id.empty() ? i : fish_idx_to_id.at(i)] = it->second[i]; + map[fish_idx_to_id.empty() ? Idx_t(i) : fish_idx_to_id.at(Idx_t(i))] = it->second[i]; } return map; } @@ -778,7 +778,7 @@ std::unique_ptr<Image> Recognition::calculate_diff_image_with_settings(const def _fish_last_frame.clear(); for(auto id : identities) - _fish_last_frame[id] = FishInfo(); + _fish_last_frame[Idx_t(id)] = FishInfo(); } auto str = Meta::toStr(_fish_last_frame); @@ -1076,19 +1076,19 @@ std::unique_ptr<Image> Recognition::calculate_diff_image_with_settings(const def return obj; } - void Recognition::Detail::inproc_frame(long_t frame, long_t fdx) { + void Recognition::Detail::inproc_frame(long_t frame, Idx_t fdx) { std::lock_guard<std::mutex> guard(lock); auto & [add, inp, proc] = added_individuals_per_frame[frame]; inp.insert(fdx); } - void Recognition::Detail::add_frame(long_t frame, long_t fdx) { + void Recognition::Detail::add_frame(long_t frame, Idx_t fdx) { std::lock_guard<std::mutex> guard(lock); auto & [add, inp, proc] = added_individuals_per_frame[frame]; add.insert(fdx); } - void Recognition::Detail::failed_frame(long_t frame, long_t fdx) { + void Recognition::Detail::failed_frame(long_t frame, Idx_t fdx) { std::lock_guard<std::mutex> guard(lock); auto & [add, inp, proc] = added_individuals_per_frame[frame]; add.insert(fdx); @@ -1096,7 +1096,7 @@ std::unique_ptr<Image> Recognition::calculate_diff_image_with_settings(const def proc.insert(fdx); } - void Recognition::Detail::finished_frames(const std::map<long_t, std::set<idx_t> > &individuals_per_frame) { + void Recognition::Detail::finished_frames(const std::map<long_t, std::set<Idx_t> > &individuals_per_frame) { size_t added_frames; Rangel analysis_range; long_t end_frame, video_length; @@ -1206,7 +1206,7 @@ std::unique_ptr<Image> Recognition::calculate_diff_image_with_settings(const def _last_checked_frame = min(_last_checked_frame, after); } - void Recognition::Detail::remove_individual(idx_t fdx) { + void Recognition::Detail::remove_individual(Idx_t fdx) { std::lock_guard<std::mutex> guard(lock); std::set<long_t> frames; for (auto & [frame, tup] : added_individuals_per_frame) { @@ -1289,7 +1289,7 @@ std::unique_ptr<Image> Recognition::calculate_diff_image_with_settings(const def std::vector<ImageData> data; std::vector<Image::Ptr> images; - std::map<long_t, std::set<idx_t>> uploaded_frames; + std::map<long_t, std::set<Idx_t>> uploaded_frames; { //! TODO: only exit if this is not the end of the video @@ -1451,7 +1451,7 @@ void Recognition::check_learning_module(bool force) { auto result = PythonIntegration::check_module("learn_static"); if(result || force || py::is_none("classes", "learn_static")) { size_t N = FAST_SETTINGS(track_max_individuals) ? (size_t)FAST_SETTINGS(track_max_individuals) : 1u; - std::vector<idx_t> ids; + std::vector<int32_t> ids; ids.resize(N); for(size_t i=0; i<N; ++i) @@ -1881,7 +1881,7 @@ void Recognition::load_weights(std::string postfix) { auto joined_data = data->join_split_data(); if(FAST_SETTINGS(manual_identities).size() > classes.size()) { - std::set<idx_t> missing; + std::set<Idx_t> missing; for(auto id : FAST_SETTINGS(manual_identities)) { if(std::find(classes.begin(), classes.end(), id) == classes.end()) missing.insert(id); diff --git a/Application/src/tracker/tracking/Recognition.h b/Application/src/tracker/tracking/Recognition.h index cd58778..091a129 100644 --- a/Application/src/tracker/tracking/Recognition.h +++ b/Application/src/tracker/tracking/Recognition.h @@ -51,10 +51,10 @@ namespace track { std::map<long_t, std::map<uint32_t, std::vector<float>>> probs; //std::set<long_t> identities; //std::map<long_t, long_t> fish_id_to_idx; - std::map<long_t, long_t> fish_idx_to_id; + std::map<Idx_t, Idx_t> fish_idx_to_id; std::set<Rangel> gui_last_trained_ranges; - typedef long_t fdx_t; + typedef Idx_t fdx_t; typedef long_t frame_t; struct FishInfo { @@ -71,7 +71,7 @@ namespace track { std::map<frame_t, std::set<fdx_t>> _last_frames; std::map<fdx_t, FishInfo> _fish_last_frame; - std::map<long_t, std::map<Rangel, TrainingFilterConstraints>> custom_midline_lengths; + std::map<Idx_t, std::map<Rangel, TrainingFilterConstraints>> custom_midline_lengths; public: struct ImageData { @@ -88,10 +88,10 @@ namespace track { long_t frame; FrameRange segment; Individual *fish; - idx_t fdx; + Idx_t fdx; gui::Transform midline_transform; - ImageData(Blob blob = Blob{0,0,-1,-1}, long_t frame = -1, const FrameRange& segment = FrameRange(), Individual * fish = NULL, idx_t fdx = -1, const gui::Transform& transform = gui::Transform()) + ImageData(Blob blob = Blob{0,0,-1,-1}, long_t frame = -1, const FrameRange& segment = FrameRange(), Individual * fish = NULL, Idx_t fdx = Idx_t(), const gui::Transform& transform = gui::Transform()) : image(nullptr), filters(nullptr), blob(blob), frame(frame), segment(segment), fish(fish), fdx(fdx), midline_transform(transform) {} }; @@ -123,13 +123,13 @@ namespace track { size_t processed; float _percent; - std::map<long_t, std::tuple<std::set<idx_t>, std::set<idx_t>, std::set<idx_t>>> added_individuals_per_frame; + std::map<long_t, std::tuple<std::set<Idx_t>, std::set<Idx_t>, std::set<Idx_t>>> added_individuals_per_frame; std::vector<std::function<void()>> registered_callbacks; GETTER_SETTER(long_t, last_checked_frame) GETTER_SETTER(float, processing_percent) - std::map<idx_t, long_t> _max_pre_frame; - std::map<idx_t, long_t> _max_pst_frame; + std::map<Idx_t, long_t> _max_pre_frame; + std::map<Idx_t, long_t> _max_pst_frame; float _last_percent; GETTER(size_t, unavailable_blobs) @@ -147,8 +147,8 @@ namespace track { size_t added, processed, N, max_frame, inproc; float percent; long_t last_frame; - std::map<idx_t, long_t> max_pre_frame; - std::map<idx_t, long_t> max_pst_frame; + std::map<Idx_t, long_t> max_pre_frame; + std::map<Idx_t, long_t> max_pst_frame; size_t failed_blobs; Info() : added(0), processed(0), N(0), max_frame(0), inproc(0), percent(0), last_frame(-1), failed_blobs(0) { @@ -175,13 +175,13 @@ namespace track { } void remove_frames(long_t after); - void remove_individual(idx_t fdx); + void remove_individual(Idx_t fdx); - void add_frame(long_t, long_t); - void inproc_frame(long_t, long_t); - void failed_frame(long_t, long_t); + void add_frame(long_t, Idx_t); + void inproc_frame(long_t, Idx_t); + void failed_frame(long_t, Idx_t); - void finished_frames(const std::map<long_t, std::set<idx_t>>& individuals_per_frame); + void finished_frames(const std::map<long_t, std::set<Idx_t>>& individuals_per_frame); void register_finished_callback(std::function<void()>&& fn); void clear(); }; @@ -196,7 +196,7 @@ namespace track { static void fix_python(); //float p(long_t frame, uint32_t blob_id, const Individual *fish); - std::map<long_t, float> ps_raw(long_t frame, uint32_t blob_id); + std::map<Idx_t, float> ps_raw(long_t frame, uint32_t blob_id); //bool has(long_t frame, uint32_t blob_id); //bool has(long_t frame, const Individual* fish); //std::map<long_t, std::map<long_t, long_t>> check_identities(long_t frame, const std::vector<pv::BlobPtr>& blobs); diff --git a/Application/src/tracker/tracking/Tracker.cpp b/Application/src/tracker/tracking/Tracker.cpp index da35ba5..a476053 100644 --- a/Application/src/tracker/tracking/Tracker.cpp +++ b/Application/src/tracker/tracking/Tracker.cpp @@ -70,11 +70,11 @@ namespace track { } //std::map<long_t, std::map<uint32_t, long_t>> automatically_assigned_blobs; - std::map<long_t, std::map<Rangel, std::vector<long_t>>> automatically_assigned_ranges; + std::map<Idx_t, std::map<Rangel, std::vector<int64_t>>> automatically_assigned_ranges; - inline std::map<long_t, long_t> automatically_assigned(long_t frame) { + inline std::map<Idx_t, long_t> automatically_assigned(long_t frame) { //LockGuard guard; - std::map<long_t, long_t> blob_for_fish; + std::map<Idx_t, long_t> blob_for_fish; for(auto && [fdx, bff] : automatically_assigned_ranges) { blob_for_fish[fdx] = -1; @@ -82,7 +82,7 @@ namespace track { for(auto && [range, blob_ids] : bff) { if(range.contains(frame)) { assert(frame >= range.start && range.end >= frame); - blob_for_fish[fdx] = blob_ids.at(frame - range.start); + blob_for_fish[fdx] = blob_ids.at(sign_cast<size_t>(frame - range.start)); break; } } @@ -208,7 +208,7 @@ const FrameProperties* Tracker::properties(long_t frameIndex, const CacheHints* stats.print(); } - void Tracker::delete_automatic_assignments(long_t fish_id, const FrameRange& frame_range) { + void Tracker::delete_automatic_assignments(Idx_t fish_id, const FrameRange& frame_range) { auto it = automatically_assigned_ranges.find(fish_id); if(it == automatically_assigned_ranges.end()) { Except("Cannot find fish %d in automatic assignments"); @@ -249,7 +249,7 @@ void Tracker::analysis_state(AnalysisState pause) { _startFrame(-1), _endFrame(-1), _max_individuals(0), _background(NULL), _recognition(NULL), _approximative_enabled_in_frame(std::numeric_limits<long_t>::lowest()), - _inactive_individuals([this](long_t A, long_t B){ + _inactive_individuals([this](Idx_t A, Idx_t B){ auto it = _individuals.find(A); assert(it != _individuals.end()); const Individual* a = it->second; @@ -1681,7 +1681,7 @@ bool operator<(long_t frame, const FrameProperties& props) { } } - Individual* Tracker::create_individual(idx_t ID, Tracker::set_of_individuals_t& active_individuals) { + Individual* Tracker::create_individual(Idx_t ID, Tracker::set_of_individuals_t& active_individuals) { if(_individuals.find(ID) != _individuals.end()) U_EXCEPTION("Cannot assign identity (%d) twice.", ID); @@ -1976,9 +1976,9 @@ void Tracker::clear_properties() { // prepare active_individuals array and assign fixed matches for which // the individuals already exist - std::map<uint32_t, std::set<idx_t>> cannot_find; - std::map<uint32_t, std::set<idx_t>> double_find; - std::map<uint32_t, idx_t> actually_assign; + std::map<uint32_t, std::set<Idx_t>> cannot_find; + std::map<uint32_t, std::set<Idx_t>> double_find; + std::map<uint32_t, Idx_t> actually_assign; for(auto && [fdx, bdx] : current_fixed_matches) { auto it = _individuals.find(fdx); @@ -2077,7 +2077,7 @@ void Tracker::clear_properties() { } if(!cannot_find.empty()) { - std::map<uint32_t, std::vector<std::tuple<idx_t, Vec2, uint32_t>>> assign_blobs; + std::map<uint32_t, std::vector<std::tuple<Idx_t, Vec2, uint32_t>>> assign_blobs; for(auto && [bdx, fdxs] : cannot_find) { assert(bdx >= 0); @@ -2098,7 +2098,7 @@ void Tracker::clear_properties() { //auto str = prettify_array(Meta::toStr(assign_blobs)); //Debug("replacing blobids / potentially splitting:\n%S", &str); - std::map<idx_t, uint32_t> actual_assignments; + std::map<Idx_t, uint32_t> actual_assignments; for(auto && [bdx, clique] : assign_blobs) { //if(clique.size() > 1) @@ -2240,21 +2240,21 @@ void Tracker::clear_properties() { // create correct identities //assert(_individuals.empty()); - uint32_t max_id = Identity::running_id(); + Idx_t max_id(Identity::running_id()); for (auto m : manual_identities) { if(_individuals.find(m) == _individuals.end()) { - Individual *fish = new Individual(m); + Individual *fish = new Individual((uint32_t)m); //fish->identity().set_ID(m); assert(fish->identity().ID() == m); - max_id = max(max_id, m); + max_id = Idx_t(max((uint32_t)max_id, (uint32_t)m)); _individuals[m] = fish; //active_individuals.push_back(fish); } } - if(max_id > -1) { + if(max_id.valid()) { Identity::set_running_id(max_id + 1); } } @@ -2866,7 +2866,7 @@ void Tracker::clear_properties() { #ifndef NDEBUG if(!number_fish) { - static std::set<idx_t> lost_ids; + static std::set<Idx_t> lost_ids; for(auto && [fdx, fish] : _individuals) { if(active_individuals.find(fish) == active_individuals.end() && _inactive_individuals.find(fdx) == _inactive_individuals.end()) { if(lost_ids.find(fdx) != lost_ids.end()) @@ -3004,7 +3004,7 @@ void Tracker::clear_properties() { _statistics[frameIndex].posture_seconds = posture_seconds; } -void Tracker::update_iterator_maps(long_t frame, const Tracker::set_of_individuals_t& active_individuals, std::unordered_map<long_t, Individual::segment_map::const_iterator>& individual_iterators) +void Tracker::update_iterator_maps(long_t frame, const Tracker::set_of_individuals_t& active_individuals, std::unordered_map<Idx_t, Individual::segment_map::const_iterator>& individual_iterators) { for(auto fish : active_individuals) { auto fit = individual_iterators.find(fish->identity().ID()); @@ -3039,7 +3039,7 @@ void Tracker::update_iterator_maps(long_t frame, const Tracker::set_of_individua } } - void Tracker::update_warnings(long_t frameIndex, double time, long_t /*number_fish*/, long_t n_found, long_t n_prev, const FrameProperties *props, const FrameProperties *prev_props, const Tracker::set_of_individuals_t& active_individuals, std::unordered_map<long_t, Individual::segment_map::const_iterator>& individual_iterators) { + void Tracker::update_warnings(long_t frameIndex, double time, long_t /*number_fish*/, long_t n_found, long_t n_prev, const FrameProperties *props, const FrameProperties *prev_props, const Tracker::set_of_individuals_t& active_individuals, std::unordered_map<Idx_t, Individual::segment_map::const_iterator>& individual_iterators) { std::map<std::string, std::set<FOI::fdx_t>> merge; if(n_found < n_prev-1) { @@ -3082,11 +3082,11 @@ void Tracker::update_iterator_maps(long_t frame, const Tracker::set_of_individua if(it != fish->frame_segments().end() && (*it)->contains(frameIndex - 1)) { // prev auto idx = (*it)->basic_stuff(frameIndex - 1); - property.prev = idx != -1 ? fish->basic_stuff()[idx]->centroid : nullptr; + property.prev = idx != -1 ? fish->basic_stuff()[uint32_t(idx)]->centroid : nullptr; // current idx = (*it)->basic_stuff(frameIndex); - property.current = idx != -1 ? fish->basic_stuff()[idx]->centroid : nullptr; + property.current = idx != -1 ? fish->basic_stuff()[uint32_t(idx)]->centroid : nullptr; } else property.prev = property.current = nullptr; @@ -3094,7 +3094,7 @@ void Tracker::update_iterator_maps(long_t frame, const Tracker::set_of_individua #ifndef NDEBUG for(auto &fish : active_individuals) { - if((long_t)_warn_individual_status.size() <= fish->identity().ID()) { + if(_warn_individual_status.size() <= fish->identity().ID()) { assert(!fish->has(frameIndex-1)); continue; } @@ -3151,11 +3151,11 @@ void Tracker::update_iterator_maps(long_t frame, const Tracker::set_of_individua #ifndef NDEBUG for(auto id : segment_end) { - assert(individuals().at(id.id)->segment_for(frameIndex) != individuals().at(id.id)->segment_for(frameIndex-1)); + assert(individuals().at(Idx_t(id.id))->segment_for(frameIndex) != individuals().at(Idx_t(id.id))->segment_for(frameIndex-1)); } for(auto id : fdx) { - assert(!individuals().at(id.id)->has(frameIndex)); - assert(frameIndex != start_frame() && _individuals.at(id.id)->has(frameIndex-1)); + assert(!individuals().at(Idx_t(id.id))->has(frameIndex)); + assert(frameIndex != start_frame() && _individuals.at(Idx_t(id.id))->has(frameIndex-1)); } #endif @@ -3335,7 +3335,7 @@ void Tracker::update_iterator_maps(long_t frame, const Tracker::set_of_individua } auto manual_identities = FAST_SETTINGS(manual_identities); - std::vector<idx_t> to_delete; + std::vector<Idx_t> to_delete; std::vector<Individual*> ptrs; for(auto && [fdx, fish] : _individuals) { fish->remove_frame(frameIndex); @@ -3623,7 +3623,7 @@ void Tracker::update_iterator_maps(long_t frame, const Tracker::set_of_individua recognition_pool.wait(); - using fdx_t = long_t; + using fdx_t = Idx_t; using range_t = FrameRange; using namespace Match; @@ -3631,10 +3631,10 @@ void Tracker::update_iterator_maps(long_t frame, const Tracker::set_of_individua std::set<range_t> segments; std::map<range_t, Match::prob_t> probs; std::map<range_t, size_t> samples; - std::map<Rangel, idx_t> track_ids; + std::map<Rangel, Idx_t> track_ids; }; - std::map<long_t, std::map<track::idx_t, int64_t>> automatic_matches; + std::map<long_t, std::map<Idx_t, int64_t>> automatic_matches; std::map<fdx_t, VirtualFish> virtual_fish; // wrong fish -> set of unassigned ranges @@ -3648,7 +3648,7 @@ void Tracker::update_iterator_maps(long_t frame, const Tracker::set_of_individua return pair0.second < pair1.second; };*/ - static const auto compare_greatest = [](const std::pair<long_t, Match::prob_t>& pair0, const std::pair<long_t, Match::prob_t>& pair1) + static const auto compare_greatest = [](const std::pair<Idx_t, Match::prob_t>& pair0, const std::pair<Idx_t, Match::prob_t>& pair1) { return pair0.second > pair1.second; }; @@ -3675,7 +3675,7 @@ void Tracker::update_iterator_maps(long_t frame, const Tracker::set_of_individua if(n >= n_lower_bound || (segment.start() == fish->start_frame() && n > 0)) { log(f, "fish %d: segment %d-%d has %d samples", fdx, segment.start(), segment.end(), n); - std::set<std::pair<long_t, Match::prob_t>, decltype(compare_greatest)> sorted(compare_greatest); + std::set<std::pair<Idx_t, Match::prob_t>, decltype(compare_greatest)> sorted(compare_greatest); sorted.insert(average.begin(), average.end()); // check if the values for this segment are too close, this probably @@ -3755,7 +3755,7 @@ void Tracker::update_iterator_maps(long_t frame, const Tracker::set_of_individua virtual_fish[it->first].segments.insert(segment); virtual_fish[it->first].probs[segment] = it->second; virtual_fish[it->first].samples[segment] = n; - virtual_fish[it->first].track_ids[segment.range] = (idx_t)fdx; + virtual_fish[it->first].track_ids[segment.range] = fdx; assigned_ranges[fdx][segment.range] = it->first; } @@ -3817,7 +3817,7 @@ void Tracker::update_iterator_maps(long_t frame, const Tracker::set_of_individua if(blob && blob->split() && blob->parent_id != -1) manual_splits[segment.start()].insert(blob->parent_id); - std::vector<long_t> blob_ids; + std::vector<int64_t> blob_ids; for(long_t frame=segment.start(); frame<=segment.end(); ++frame) { blob = track->compressed_blob(frame); if(blob) { @@ -3851,7 +3851,7 @@ void Tracker::update_iterator_maps(long_t frame, const Tracker::set_of_individua tmp_assigned_ranges[fdx].erase(range); auto str = Meta::toStr(remove_from); - Warning("While assigning %d,%d to %d -> same fish already assigned in ranges %S", frame, blob ? (long_t)blob->blob_id() : -1, fdx, &str); + Warning("While assigning %d,%d to %d -> same fish already assigned in ranges %S", frame, blob ? (int64_t)blob->blob_id() : -1, fdx, &str); } } @@ -3892,7 +3892,7 @@ void Tracker::update_iterator_maps(long_t frame, const Tracker::set_of_individua } if(next != fish->recognition_segments().end() && /*previous.start() != -1 &&*/ next->second.start() != -1) { - fdx_t prev_id = -1, next_id = -1; + Idx_t prev_id, next_id; PhysicalProperties *prev_pos = nullptr, *next_pos = nullptr; long_t prev_blob = -1; @@ -3950,7 +3950,7 @@ void Tracker::update_iterator_maps(long_t frame, const Tracker::set_of_individua } } - if(next_id != -1 && prev_id != -1 && next_id == prev_id && prev_pos && next_pos) { + if(next_id.valid() && prev_id.valid() && next_id == prev_id && prev_pos && next_pos) { //Debug("Fish %d: virtual prev_id %d == virtual next_id %d, assigning...", fdx, prev_id, next_id); Vec2 pos_start(FLT_MAX), pos_end(FLT_MAX); auto blob_start = fish->centroid_weighted(segment.start()); @@ -3963,7 +3963,7 @@ void Tracker::update_iterator_maps(long_t frame, const Tracker::set_of_individua if(blob_start && blob_end) { auto dprev = euclidean_distance(prev_pos->pos(), pos_start) / Tracker::time_delta(blob_start->frame(), prev_pos->frame()); auto dnext = euclidean_distance(next_pos->pos(), pos_end) / Tracker::time_delta(next_pos->frame(), blob_end->frame()); - long_t chosen_id = -1; + Idx_t chosen_id; if(dnext < dprev) { if(dprev < FAST_SETTINGS(track_max_speed) * 0.1) @@ -3971,18 +3971,18 @@ void Tracker::update_iterator_maps(long_t frame, const Tracker::set_of_individua } else if(dnext < FAST_SETTINGS(track_max_speed) * 0.1) chosen_id = prev_id; - if(chosen_id != -1) { + if(chosen_id.valid()) { if(segment.start() == 0) { log(f, "Fish %d: chosen_id %d, assigning %d-%d (%f / %f)...", fdx, chosen_id, segment.start(), segment.end(), dprev, dnext); } - if(prev_blob != -1 && prev_id != -1) { + if(prev_blob != -1 && prev_id.valid()) { // we found the previous blob/segment quickly: - auto range = _individuals.at((idx_t)prev_id)->get_segment_safe(prev_blob); + auto range = _individuals.at(prev_id)->get_segment_safe(prev_blob); if(!range.empty()) { long_t frame = range.end(); while(frame >= range.start()) { - auto blob = _individuals.at((idx_t)prev_id)->compressed_blob(frame); + auto blob = _individuals.at(prev_id)->compressed_blob(frame); if(blob->split()) { if(blob->parent_id != -1) { //manual_splits[frame].insert(blob->parent_id()); @@ -4013,7 +4013,7 @@ void Tracker::update_iterator_maps(long_t frame, const Tracker::set_of_individua std::set<Rangel> remove_from; - std::vector<long_t> blob_ids; + std::vector<int64_t> blob_ids; for(long_t frame=segment.start(); frame<=segment.end(); ++frame) { auto blob = fish->compressed_blob(frame); @@ -4039,9 +4039,9 @@ void Tracker::update_iterator_maps(long_t frame, const Tracker::set_of_individua // automatically_assigned_ranges[chosen_id].erase(range); auto str = Meta::toStr(remove_from); - Warning("[ignore] While assigning %d-%d to %d -> same fish already assigned in ranges %S", segment.range.start, segment.range.end, chosen_id, &str); + Warning("[ignore] While assigning %d-%d to %d -> same fish already assigned in ranges %S", segment.range.start, segment.range.end, (uint32_t)chosen_id, &str); } else { - assert((long_t)blob_ids.size() == segment.range.end - segment.range.start + 1); + assert((int64_t)blob_ids.size() == segment.range.end - segment.range.start + 1); tmp_assigned_ranges[chosen_id][segment.range] = blob_ids; auto blob = fish->blob(segment.start()); @@ -4182,7 +4182,7 @@ pv::BlobPtr Tracker::find_blob_noisy(std::map<uint32_t, pv::BlobPtr>& blob_to_id std::vector<uchar> image_data; Size2 shape; - printf("tags for %d: ", fish->identity().ID()); + printf("tags for %u: ", (uint32_t)fish->identity().ID()); for(auto && [var, bid, ptr, frame] : *set) { shape = Size2(ptr->cols, ptr->rows); // had previous frame, lost in this frame (finalize segment) diff --git a/Application/src/tracker/tracking/Tracker.h b/Application/src/tracker/tracking/Tracker.h index 58dd021..131ee84 100644 --- a/Application/src/tracker/tracking/Tracker.h +++ b/Application/src/tracker/tracking/Tracker.h @@ -10,7 +10,7 @@ #include <tracking/Border.h> #include <misc/Timer.h> #include <misc/BlobSizeRange.h> - +#include <misc/idx_t.h> #include <misc/create_struct.h> namespace Output { @@ -34,7 +34,7 @@ namespace track { IndividualStatus() : prev(nullptr), current(nullptr) {} }; -using mmatches_t = std::map<long_t, std::map<idx_t, int64_t>>; +using mmatches_t = std::map<long_t, std::map<Idx_t, int64_t>>; using msplits_t = std::map<long_t, std::set<int64_t>>; using inames_t = std::map<uint32_t, std::string>; using mapproved_t = std::map<long_t,long_t>; @@ -68,7 +68,7 @@ CREATE_STRUCT(Settings, (float, matching_probability_threshold), (size_t, posture_direction_smoothing), (file::Path, tags_path), - (std::set<uint32_t>, manual_identities), + (std::set<Idx_t>, manual_identities), (std::vector<Vec2>, grid_points), (std::vector<std::vector<Vec2>>, recognition_shapes), (float, grid_points_scaling), @@ -125,7 +125,7 @@ CREATE_STRUCT(Settings, uint32_t _current_midline_errors, _overall_midline_errors; //! All the individuals that have been detected and are being maintained - std::unordered_map<idx_t, Individual*> _individuals; + std::unordered_map<Idx_t, Individual*> _individuals; friend class Individual; set_of_individuals_t _active_individuals; @@ -139,8 +139,8 @@ CREATE_STRUCT(Settings, GETTER_PTR(StaticBackground*, background) Recognition* _recognition; - std::unordered_map<long_t, Individual::segment_map::const_iterator> _individual_add_iterator_map; - std::unordered_map<long_t, size_t> _segment_map_known_capacity; + std::unordered_map<Idx_t, Individual::segment_map::const_iterator> _individual_add_iterator_map; + std::unordered_map<Idx_t, size_t> _segment_map_known_capacity; std::vector<IndividualStatus> _warn_individual_status; public: @@ -187,7 +187,7 @@ CREATE_STRUCT(Settings, long_t _approximative_enabled_in_frame; GETTER(std::deque<Range<long_t>>, consecutive) - std::set<long_t, std::function<bool(long_t,long_t)>> _inactive_individuals; + std::set<Idx_t, std::function<bool(Idx_t,Idx_t)>> _inactive_individuals; public: Tracker(); @@ -231,8 +231,8 @@ CREATE_STRUCT(Settings, static const FrameProperties* add_next_frame(const FrameProperties&); static void clear_properties(); - static long_t start_frame() { return (long_t)instance()->_startFrame; } - static long_t end_frame() { return (long_t)instance()->_endFrame; } + static Frame_t start_frame() { return Frame_t(instance()->_startFrame.load()); } + static Frame_t end_frame() { return Frame_t(instance()->_endFrame.load()); } static size_t number_frames() { return instance()->_added_frames.size(); } static bool blob_matches_shapes(const pv::BlobPtr&, const std::vector<std::vector<Vec2>>&); @@ -240,7 +240,7 @@ CREATE_STRUCT(Settings, static void preprocess_frame(PPFrame &frame, const std::unordered_set<Individual*>& active_individuals, GenericThreadPool* pool, std::ostream* = NULL, bool do_history_split = true); friend class VisualField; - static const std::unordered_map<idx_t, Individual*>& individuals() { + static const std::unordered_map<Idx_t, Individual*>& individuals() { LockGuard guard("individuals()"); return instance()->_individuals; } @@ -265,7 +265,7 @@ CREATE_STRUCT(Settings, void update_history_log(); - long_t update_with_manual_matches(const std::map<long_t, std::map<idx_t, int64_t>>& manual_matches); + long_t update_with_manual_matches(const std::map<long_t, std::map<Idx_t, int64_t>>& manual_matches); void check_segments_identities(bool auto_correct, std::function<void(float)> callback, const std::function<void(const std::string&, const std::function<void()>&, const std::string&)>& add_to_queue = [](auto,auto,auto){}, long_t after_frame = -1); void clear_segments_identities(); void prepare_shutdown(); @@ -282,7 +282,7 @@ CREATE_STRUCT(Settings, static void global_segment_order_changed(); static void auto_calculate_parameters(pv::File& video, bool quiet = false); static void emergency_finish(); - static void delete_automatic_assignments(long_t fish_id, const FrameRange& frame_range); + static void delete_automatic_assignments(Idx_t fish_id, const FrameRange& frame_range); enum class AnalysisState { PAUSED, @@ -298,7 +298,7 @@ CREATE_STRUCT(Settings, } void update_consecutive(const set_of_individuals_t& active, long_t frameIndex, bool update_dataset = false); - void update_warnings(long_t frameIndex, double time, long_t number_fish, long_t n_found, long_t n_prev, const FrameProperties *props, const FrameProperties *prev_props, const set_of_individuals_t& active_individuals, std::unordered_map<long_t, Individual::segment_map::const_iterator>& individual_iterators); + void update_warnings(long_t frameIndex, double time, long_t number_fish, long_t n_found, long_t n_prev, const FrameProperties *props, const FrameProperties *prev_props, const set_of_individuals_t& active_individuals, std::unordered_map<Idx_t, Individual::segment_map::const_iterator>& individual_iterators); private: static void filter_blobs(PPFrame& frame, GenericThreadPool *pool); @@ -326,7 +326,7 @@ CREATE_STRUCT(Settings, void generate_pairdistances(long_t frameIndex); void check_save_tags(long_t frameIndex, const std::unordered_map<uint32_t, Individual*>&, const std::vector<tags::blob_pixel>&, const std::vector<tags::blob_pixel>&, const file::Path&); - Individual* create_individual(idx_t ID, set_of_individuals_t& active_individuals); + Individual* create_individual(Idx_t ID, set_of_individuals_t& active_individuals); struct PrefilterBlobs { std::vector<pv::BlobPtr> filtered; @@ -350,7 +350,7 @@ CREATE_STRUCT(Settings, static void prefilter(std::shared_ptr<PrefilterBlobs>, std::vector<pv::BlobPtr>::const_iterator it, std::vector<pv::BlobPtr>::const_iterator end); - void update_iterator_maps(long_t frame, const set_of_individuals_t& active_individuals, std::unordered_map<long_t, Individual::segment_map::const_iterator>& individual_iterators); + void update_iterator_maps(long_t frame, const set_of_individuals_t& active_individuals, std::unordered_map<Idx_t, Individual::segment_map::const_iterator>& individual_iterators); }; } diff --git a/Application/src/tracker/tracking/TrainingData.cpp b/Application/src/tracker/tracking/TrainingData.cpp index 8d758d5..aa5f6f5 100644 --- a/Application/src/tracker/tracking/TrainingData.cpp +++ b/Application/src/tracker/tracking/TrainingData.cpp @@ -107,7 +107,7 @@ TrainingData::DataRange::operator MetaObject() const { return MetaObject(ss.str(), "DataRange"); } -void TrainingData::add_frame(std::shared_ptr<TrainingData::DataRange> data, long_t frame_index, long_t id, long_t original_id, Image::Ptr image, const Vec2 & pos, size_t px, const FrameRange& from_range) +void TrainingData::add_frame(std::shared_ptr<TrainingData::DataRange> data, long_t frame_index, Idx_t id, int64_t original_id, Image::Ptr image, const Vec2 & pos, size_t px, const FrameRange& from_range) { /*auto it = original_ids_check.find(image.get()); if(it == original_ids_check.end()) @@ -175,7 +175,7 @@ void TrainingData::add_frame(std::shared_ptr<TrainingData::DataRange> data, long _all_classes.insert(id); } -void TrainingData::apply_mapping(const std::map<long_t, long_t>& mapping) { +void TrainingData::apply_mapping(const std::map<Idx_t, Idx_t>& mapping) { bool found = false; for(auto && [id, ID] : mapping) { if(id != ID) { @@ -201,7 +201,7 @@ void TrainingData::apply_mapping(const std::map<long_t, long_t>& mapping) { Debug("Changed mapping with %S for %d-%d", &str, data->frames.start, data->frames.end); } - std::map<long_t, DataRange::PerIndividual> map; + std::map<Idx_t, DataRange::PerIndividual> map; for(auto && [from, to] : mapping) { auto it = data->mappings.find(from); if(it != data->mappings.end()) @@ -237,11 +237,11 @@ void TrainingData::apply_mapping(const std::map<long_t, long_t>& mapping) { } } -void TrainingData::set_classes(const std::set<uint32_t>& classes) { +void TrainingData::set_classes(const std::set<Idx_t>& classes) { _all_classes = classes; } -std::unique_ptr<Image> TrainingData::draw_coverage(const std::map<uint32_t, float>& unique_percentages, const std::vector<Rangel>& next_ranges, const std::vector<Rangel>& added_ranges, const std::map<uint32_t, float>& uniquenesses_temp, std::shared_ptr<TrainingData::DataRange> current_salt, const std::map<Rangel, std::tuple<double, FrameRange>>& assigned_unique_averages) const +std::unique_ptr<Image> TrainingData::draw_coverage(const std::map<Frame_t, float>& unique_percentages, const std::vector<Rangel>& next_ranges, const std::vector<Rangel>& added_ranges, const std::map<Frame_t, float>& uniquenesses_temp, std::shared_ptr<TrainingData::DataRange> current_salt, const std::map<Rangel, std::tuple<double, FrameRange>>& assigned_unique_averages) const { auto analysis_range = Tracker::analysis_range(); auto image = std::make_unique<Image>(500, 1800, 4); @@ -255,7 +255,7 @@ std::unique_ptr<Image> TrainingData::draw_coverage(const std::map<uint32_t, floa float row_height = float(image->rows) / float(rows); float column_width = float(image->cols) / float(analysis_range.length()); - auto draw_range = [column_width, row_height, analysis_range, &colors](cv::Mat& mat, const Rangel& range, long_t id, uint8_t alpha = 200){ + auto draw_range = [column_width, row_height, analysis_range, &colors](cv::Mat& mat, const Rangel& range, Idx_t id, uint8_t alpha = 200){ Vec2 topleft((range.start - analysis_range.start) * column_width, row_height * id); Vec2 bottomright((range.end - analysis_range.start) * column_width, row_height * (id + 1)); cv::rectangle(mat, topleft, bottomright, colors[id].alpha(alpha * 0.5), cv::FILLED); @@ -538,9 +538,9 @@ size_t TrainingData::size() const { return n; } -std::tuple<std::vector<Image::Ptr>, std::vector<long_t>> TrainingData::join_arrays() const { +std::tuple<std::vector<Image::Ptr>, std::vector<Idx_t>> TrainingData::join_arrays() const { std::vector<Image::Ptr> images; - std::vector<long_t> ids; + std::vector<Idx_t> ids; const size_t L = size(); ids.reserve(L); @@ -621,12 +621,12 @@ typename std::vector<T>::iterator ); } -long_t TrainingData::DataRange::map(long_t id) const { +Idx_t TrainingData::DataRange::map(Idx_t id) const { if(applied_mapping.empty()) return id; return applied_mapping.at(id); } -long_t TrainingData::DataRange::unmap(long_t id) const { +Idx_t TrainingData::DataRange::unmap(Idx_t id) const { if(applied_mapping.empty()) return id; for (auto && [original, mapped] : applied_mapping) { if(mapped == id) { @@ -647,7 +647,7 @@ void TrainingData::DataRange::reverse_mapping() { auto str = Meta::toStr(applied_mapping); Debug("Reversing mapping with %S for %d-%d", &str, frames.start, frames.end); - std::map<long_t, DataRange::PerIndividual> map; + std::map<Idx_t, DataRange::PerIndividual> map; for(auto && [to, from] : applied_mapping) { auto it = mappings.find(from); if(it != mappings.end()) { @@ -664,12 +664,12 @@ void TrainingData::DataRange::reverse_mapping() { std::shared_ptr<TrainingData::DataRange> TrainingData::add_salt(const std::shared_ptr<TrainingData>& source, const std::string& purpose) { const size_t Nmax = 1000; - std::map<long_t, std::set<FrameRange>> individual_ranges; - std::map<long_t, std::tuple<size_t, size_t>> individual_samples; + std::map<Idx_t, std::set<FrameRange>> individual_ranges; + std::map<Idx_t, std::tuple<size_t, size_t>> individual_samples; - std::map<long_t, std::vector<FrameRange>> combined_ranges_per_individual; + std::map<Idx_t, std::vector<FrameRange>> combined_ranges_per_individual; - auto add_combined_range = [&combined_ranges_per_individual](const FrameRange& range, long_t id) { + auto add_combined_range = [&combined_ranges_per_individual](const FrameRange& range, Idx_t id) { auto& combined_ranges = combined_ranges_per_individual[id]; bool found = false; @@ -747,8 +747,8 @@ std::shared_ptr<TrainingData::DataRange> TrainingData::add_salt(const std::share maximum_samples_per_individual = sum; } - std::map<long_t, std::set<std::tuple<FrameRange, const DataRange::PerIndividual*, const DataRange*, long_t>>> ranges_to_add; - std::map<long_t, std::set<long_t>> source_frames_per_individual; + std::map<Idx_t, std::set<std::tuple<FrameRange, const DataRange::PerIndividual*, const DataRange*, long_t>>> ranges_to_add; + std::map<Idx_t, std::set<long_t>> source_frames_per_individual; auto add_range = std::make_shared<DataRange>(true); for(auto &d : data()) { @@ -778,8 +778,8 @@ std::shared_ptr<TrainingData::DataRange> TrainingData::add_salt(const std::share } // add maximum of Nmax images per individual - std::map<long_t, std::tuple<size_t, size_t, size_t, size_t>> individual_added_salt; - std::map<long_t, std::tuple<size_t, size_t>> individual_samples_before_after; + std::map<Idx_t, std::tuple<size_t, size_t, size_t, size_t>> individual_added_salt; + std::map<Idx_t, std::tuple<size_t, size_t>> individual_samples_before_after; const double number_classes = SETTING(track_max_individuals).value<uint32_t>(); const double gpu_max_sample_mb = double(SETTING(gpu_max_sample_gb).value<float>()) * 1000; @@ -817,7 +817,7 @@ std::shared_ptr<TrainingData::DataRange> TrainingData::add_salt(const std::share size_t actually_added = 0; for(auto && [range, ptr, d, ID] : ranges) { - long_t step_size = max(1, ceil(SR / (max_images_per_class * double(range.length()) / double(N)))); + size_t step_size = max(1u, (size_t)ceil(SR / (max_images_per_class * double(range.length()) / double(N)))); std::vector<std::tuple<long_t, Image::Ptr, Vec2, size_t>> frames; for(size_t i=0; i<ptr->frame_indexes.size(); ++i) { @@ -865,7 +865,7 @@ std::shared_ptr<TrainingData::DataRange> TrainingData::add_salt(const std::share return add_range; } -bool TrainingData::generate(const std::string& step_description, pv::File & video_file, std::map<long_t, std::set<long_t> > individuals_per_frame, const std::function<void(float)>& callback, const TrainingData* source) { +bool TrainingData::generate(const std::string& step_description, pv::File & video_file, std::map<Frame_t, std::set<Idx_t> > individuals_per_frame, const std::function<void(float)>& callback, const TrainingData* source) { auto frames = extract_keys(individuals_per_frame); Tracker::LockGuard guard("generate_training_data"); @@ -873,8 +873,7 @@ bool TrainingData::generate(const std::string& step_description, pv::File & vide const Size2 output_size = SETTING(recognition_image_size); const auto& custom_midline_lengths = filters(); - std::map<long_t, std::set<long_t>> illegal_frames; - //std::map<long_t, std::set<long_t>> add_from_source; + std::map<Idx_t, std::set<Frame_t>> illegal_frames; for(auto && [frame, ids] : individuals_per_frame) { for(auto id : ids) { @@ -901,13 +900,13 @@ bool TrainingData::generate(const std::string& step_description, pv::File & vide } } - std::map<long_t, long_t> lengths; + std::map<Idx_t, double> lengths; for(auto && [frame, ids] : individuals_per_frame) { for(auto id : ids) ++lengths[id]; } - long_t fewest_samples = std::numeric_limits<long_t>::max(), most_samples = 0; + double fewest_samples = std::numeric_limits<double>::max(), most_samples = 0; for(auto && [id, L] : lengths) { if(L < fewest_samples) fewest_samples = L; @@ -915,7 +914,7 @@ bool TrainingData::generate(const std::string& step_description, pv::File & vide most_samples = L; } - if(fewest_samples == std::numeric_limits<long_t>::max()) + if(fewest_samples == std::numeric_limits<size_t>::max()) fewest_samples = most_samples = 0; const double number_classes = FAST_SETTINGS(manual_identities).size(); @@ -935,7 +934,7 @@ bool TrainingData::generate(const std::string& step_description, pv::File & vide // sub-sample any classes that need sub-sampling for(auto && [id, L] : lengths) { if(L > percentile) { - float step_size = percentile / L; + auto step_size = percentile / L; //if(step_size == 1) // continue; @@ -943,9 +942,9 @@ bool TrainingData::generate(const std::string& step_description, pv::File & vide // collect all frames where this individual is present - std::set<long_t> empty_frames; - long_t count = 0, after = 0; - float acc = 0; + std::set<Frame_t> empty_frames; + size_t count = 0, after = 0; + double acc = 0; for(auto && [frame, ids] : individuals_per_frame) { if(ids.find(id) != ids.end()) { @@ -985,10 +984,9 @@ bool TrainingData::generate(const std::string& step_description, pv::File & vide Size2 minmum_size(FLT_MAX), maximum_size(0); Median<Float2_t> median_size_x, median_size_y; long_t inserted_start = std::numeric_limits<long_t>::max(), inserted_end = -1; - std::map<long_t, std::set<FrameRange>> added_from_source; // copy available images to map for easy access - std::map<long_t, std::map<long_t, std::tuple<long_t, Image::Ptr>>> available_images; + std::map<Idx_t, std::map<long_t, std::tuple<long_t, Image::Ptr>>> available_images; if(source) { for(auto & data : source->data()) { for(auto && [id, per] : data->mappings) { @@ -1027,7 +1025,7 @@ bool TrainingData::generate(const std::string& step_description, pv::File & vide size_t N_validation_images = 0, N_training_images = 0; size_t N_reused_images = 0; const bool calculate_posture = FAST_SETTINGS(calculate_posture); - std::map<long_t, std::vector<std::tuple<long_t, Image::Ptr>>> individual_training_images; + std::map<Idx_t, std::vector<std::tuple<long_t, Image::Ptr>>> individual_training_images; size_t failed_blobs = 0, found_blobs = 0; for(auto frame : frames) { @@ -1043,11 +1041,11 @@ bool TrainingData::generate(const std::string& step_description, pv::File & vide } // check so that we do not generate images again, that we have generated before - std::set<long_t> filtered_ids; + std::set<Idx_t> filtered_ids; for(auto id : FAST_SETTINGS(manual_identities)) { - if(individuals_per_frame.at(frame).find(id) != individuals_per_frame.at(frame).end()) - filtered_ids.insert(id); + if(individuals_per_frame.at(frame).find(Idx_t(id)) != individuals_per_frame.at(frame).end()) + filtered_ids.insert(Idx_t(id)); } if(frame < inserted_start) @@ -1252,9 +1250,9 @@ bool TrainingData::generate(const std::string& step_description, pv::File & vide return N_training_images + N_validation_images > 0; } -std::tuple<std::vector<Image::Ptr>, std::vector<long_t>, std::vector<long_t>, std::map<long_t, Range<size_t>>> TrainingData::join_arrays_ordered() const +std::tuple<std::vector<Image::Ptr>, std::vector<Idx_t>, std::vector<long_t>, std::map<Frame_t, Range<size_t>>> TrainingData::join_arrays_ordered() const { - using fdx_t = long_t; + using fdx_t = Idx_t; using frame_t = long_t; std::vector<Image::Ptr> images; @@ -1282,11 +1280,11 @@ std::tuple<std::vector<Image::Ptr>, std::vector<long_t>, std::vector<long_t>, st } } - std::map<frame_t, Range<size_t>> start_indexes; + std::map<Frame_t, Range<size_t>> start_indexes; for(auto && [frame, data] : collector) { auto & [_ids, _images] = data; - start_indexes[frame] = Range<size_t>(ids.size(), ids.size() + _ids.size()); + start_indexes[Frame_t(frame)] = Range<size_t>(ids.size(), ids.size() + _ids.size()); images.insert(images.end(), _images.begin(), _images.end()); ids.insert(ids.end(), _ids.begin(), _ids.end()); diff --git a/Application/src/tracker/tracking/TrainingData.h b/Application/src/tracker/tracking/TrainingData.h index 3f56163..1fe72ed 100644 --- a/Application/src/tracker/tracking/TrainingData.h +++ b/Application/src/tracker/tracking/TrainingData.h @@ -5,6 +5,7 @@ #include <misc/Image.h> #include <pv.h> #include <tracker/misc/default_config.h> +#include <tracker/misc/idx_t.h> namespace track { @@ -39,10 +40,10 @@ public: std::set<FrameRange> ranges; }; - std::map<long_t, PerIndividual> mappings; - std::map<long_t, long_t> applied_mapping; - std::set<long_t> classes; - std::vector<long_t> ids; + std::map<Idx_t, PerIndividual> mappings; + std::map<Idx_t, Idx_t> applied_mapping; + std::set<Idx_t> classes; + std::vector<Idx_t> ids; std::vector<Image::Ptr> images; Rangel frames; @@ -54,8 +55,8 @@ public: DataRange(bool salt = false) : frames(-1, -1), salty(salt) {} - long_t map(long_t) const; - long_t unmap(long_t) const; + Idx_t map(Idx_t) const; + Idx_t unmap(Idx_t) const; void reverse_mapping(); operator MetaObject() const; @@ -65,13 +66,13 @@ public: }; struct MidlineFilters { - std::map<long_t, std::map<FrameRange, TrainingFilterConstraints>> filters; + std::map<Idx_t, std::map<FrameRange, TrainingFilterConstraints>> filters; MidlineFilters(const decltype(filters)& filters = {}) : filters(filters) {} - bool has(long_t ID, const FrameRange& range = FrameRange()) const { + bool has(Idx_t ID, const FrameRange& range = FrameRange()) const { if(range.empty()) return filters.count(ID) != 0; else { @@ -89,7 +90,7 @@ public: } } - bool has(long_t ID, long_t frame) const { + bool has(Idx_t ID, long_t frame) const { auto it = filters.find(ID); if(it == filters.end()) return false; @@ -112,7 +113,7 @@ public: return false; } - void set(long_t ID, const TrainingFilterConstraints& filter) { + void set(Idx_t ID, const TrainingFilterConstraints& filter) { if(has(ID)) Warning("[TrainingFilter] %d is already present. Replacing.", ID); @@ -121,7 +122,7 @@ public: filters[ID][FrameRange()] = filter; } - void set(long_t ID, const FrameRange& range, const TrainingFilterConstraints& filter) { + void set(Idx_t ID, const FrameRange& range, const TrainingFilterConstraints& filter) { if(has(ID, range)) Warning("[TrainingFilter] %d in range %d-%d is already present. Replacing.", ID, range.start(), range.end()); if(filters[ID].find(FrameRange()) != filters[ID].end()) @@ -130,7 +131,7 @@ public: filters[ID][range] = filter; } - const TrainingFilterConstraints& get(long_t ID, long_t frame) const { + const TrainingFilterConstraints& get(Idx_t ID, long_t frame) const { auto fit = filters.find(ID); if(fit == filters.end()) U_EXCEPTION("Cannot find ID %d in TrainingFilterConstraints.", ID); @@ -163,10 +164,10 @@ private: using d_type = std::set<std::shared_ptr<DataRange>>; GETTER(d_type, data) - GETTER(std::set<uint32_t>, all_classes) + GETTER(std::set<Idx_t>, all_classes) GETTER_NCONST(MidlineFilters, filters) - using s_type = std::map<uint32_t, std::set<FrameRange>>; + using s_type = std::map<Idx_t, std::set<FrameRange>>; GETTER(s_type, included_segments) //FrameRanges frames; @@ -190,9 +191,9 @@ public: class TrainingImageData : public Image::CustomData { public: ImageClass type; - const long_t original_id; + const int64_t original_id; const std::string source; - TrainingImageData(std::string source, long_t oid) : type(ImageClass::NONE), original_id(oid), source(source) {} + TrainingImageData(std::string source, int64_t oid) : type(ImageClass::NONE), original_id(oid), source(source) {} ~TrainingImageData() {} }; @@ -224,26 +225,26 @@ public: } TrainingAndValidation join_split_data() const; - std::tuple<std::vector<Image::Ptr>, std::vector<long_t>> join_arrays() const; - std::tuple<std::vector<Image::Ptr>, std::vector<long_t>, std::vector<long_t>, std::map<long_t, Range<size_t>>> join_arrays_ordered() const; + std::tuple<std::vector<Image::Ptr>, std::vector<Idx_t>> join_arrays() const; + std::tuple<std::vector<Image::Ptr>, std::vector<Idx_t>, std::vector<long_t>, std::map<Frame_t, Range<size_t>>> join_arrays_ordered() const; - bool generate(const std::string& step_description, pv::File& video_file, std::map<long_t, std::set<long_t> > individuals_per_frame, const std::function<void(float)>& callback, const TrainingData* source); + bool generate(const std::string& step_description, pv::File& video_file, std::map<Frame_t, std::set<Idx_t> > individuals_per_frame, const std::function<void(float)>& callback, const TrainingData* source); //bool generate(pv::File& video_file, const std::map<long_t, std::set<FrameRange>>&, const std::function<void(float)>& callback); std::shared_ptr<DataRange> add_salt(const std::shared_ptr<TrainingData>& source, const std::string& purpose); - void add_frame(std::shared_ptr<DataRange> ptr, long_t frame_index, long_t id, long_t original_id, Image::Ptr image, const Vec2& pos, size_t px, const FrameRange& from_range); - void apply_mapping(const std::map<long_t, long_t>&); + void add_frame(std::shared_ptr<DataRange> ptr, long_t frame_index, Idx_t id, int64_t original_id, Image::Ptr image, const Vec2& pos, size_t px, const FrameRange& from_range); + void apply_mapping(const std::map<Idx_t, Idx_t>&); operator MetaObject() const; static std::string class_name() { return "TrainingData"; } //! used as an override for when data is just used to initialize the network and nothing more. - void set_classes(const std::set<uint32_t>& classes); + void set_classes(const std::set<Idx_t>& classes); - std::unique_ptr<Image> draw_coverage(const std::map<uint32_t, float>& uniquenesses = {}, const std::vector<Rangel>& = {}, const std::vector<Rangel>& added_ranges = {}, const std::map<uint32_t, float>& uniquenesses_temp = {}, std::shared_ptr<DataRange> current_salt = nullptr, const std::map<Rangel, std::tuple<double, FrameRange>>& assigned_unique_averages = {}) const; + std::unique_ptr<Image> draw_coverage(const std::map<Frame_t, float>& uniquenesses = {}, const std::vector<Rangel>& = {}, const std::vector<Rangel>& added_ranges = {}, const std::map<Frame_t, float>& uniquenesses_temp = {}, std::shared_ptr<DataRange> current_salt = nullptr, const std::map<Rangel, std::tuple<double, FrameRange>>& assigned_unique_averages = {}) const; }; } diff --git a/Application/src/tracker/tracking/VisualField.cpp b/Application/src/tracker/tracking/VisualField.cpp index 0da695d..15acdc5 100644 --- a/Application/src/tracker/tracking/VisualField.cpp +++ b/Application/src/tracker/tracking/VisualField.cpp @@ -8,7 +8,7 @@ namespace track { static constexpr double right_angle = RADIANS(90); - VisualField::VisualField(uint32_t fish_id, long_t frame, const std::shared_ptr<Individual::BasicStuff>& basic, const std::shared_ptr<Individual::PostureStuff>& posture, bool blocking) + VisualField::VisualField(Idx_t fish_id, long_t frame, const std::shared_ptr<Individual::BasicStuff>& basic, const std::shared_ptr<Individual::PostureStuff>& posture, bool blocking) : max_d(SQR(Tracker::average().cols) + SQR(Tracker::average().rows)), _fish_id(fish_id), _frame(frame) { calculate(basic, posture, blocking); @@ -16,8 +16,8 @@ namespace track { template<typename T> inline void correct_angle(T& angle) { - while (angle > M_PI) angle -= M_PI*2; - while (angle <= -M_PI) angle += M_PI*2; + while (angle > T(M_PI)) angle -= T(M_PI)*2; + while (angle <= -T(M_PI)) angle += T(M_PI)*2; } template<typename K, typename T = K, typename V = K> @@ -48,7 +48,7 @@ namespace track { std::get<1>(t) = -1; }; - void VisualField::plot_projected_line(eye& e, std::tuple<float, float>& tuple, double d, const Vec2& point, idx_t id, float hd) + void VisualField::plot_projected_line(eye& e, std::tuple<float, float>& tuple, double d, const Vec2& point, Idx_t id, float hd) { auto x0 = std::get<0>(tuple), x1 = std::get<1>(tuple); if(x0 == x1 && x0 == -1) @@ -494,15 +494,15 @@ namespace track { auto cd = distances[j]->get().row(int(i+range-frameNr)); for(int i=0; i<(int)ids[j]->cols; i++) { - auto id = e._visible_ids[i]; + auto id = e._visible_ids[i] != -1 ? Idx_t(e._visible_ids[i]) : Idx_t(); auto d = 255 - min(255, e._visible_head_distance[i]); Color clr(Black); - if(id != -1) { + if(id.valid()) { if(id == selected->identity().ID()) clr = White; else { - auto it = Tracker::individuals().find((idx_t)id); + auto it = Tracker::individuals().find(id); if(it != Tracker::individuals().end()) { clr = it->second->identity().color().alpha(e._fov.data()[i]); } diff --git a/Application/src/tracker/tracking/VisualField.h b/Application/src/tracker/tracking/VisualField.h index e46aae3..1f0e7e5 100644 --- a/Application/src/tracker/tracking/VisualField.h +++ b/Application/src/tracker/tracking/VisualField.h @@ -43,17 +43,17 @@ namespace track { GETTER(Vec2, fish_pos) GETTER(double, fish_angle) - GETTER(uint32_t, fish_id) + GETTER(Idx_t, fish_id) GETTER(long_t, frame) public: - VisualField(uint32_t fish_id, long_t frame,const std::shared_ptr<Individual::BasicStuff>& basic, const std::shared_ptr<Individual::PostureStuff>& posture, bool blocking); + VisualField(Idx_t fish_id, long_t frame,const std::shared_ptr<Individual::BasicStuff>& basic, const std::shared_ptr<Individual::PostureStuff>& posture, bool blocking); const decltype(_eyes)& eyes() const { return _eyes; } void calculate(const std::shared_ptr<Individual::BasicStuff>& basic, const std::shared_ptr<Individual::PostureStuff>& posture, bool blocking = true); void show(gui::DrawStructure &graph); static void show_ts(gui::DrawStructure &graph, long_t frameNr, Individual* selected); - void plot_projected_line(eye& e, std::tuple<float, float>& tuple, double d, const Vec2& point, idx_t id, float hd); + void plot_projected_line(eye& e, std::tuple<float, float>& tuple, double d, const Vec2& point, Idx_t id, float hd); }; } diff --git a/docs/parameters_trex.rst b/docs/parameters_trex.rst index 0509ccc..88d8477 100644 --- a/docs/parameters_trex.rst +++ b/docs/parameters_trex.rst @@ -565,7 +565,7 @@ TRex parameters -.. function:: gui_focus_group(array<uint>) +.. function:: gui_focus_group(array<Idx_t>) **default value:** [] @@ -1112,7 +1112,7 @@ TRex parameters -.. function:: manual_identities(set<uint>) +.. function:: manual_identities(set<Idx_t>) **default value:** [] @@ -1121,7 +1121,7 @@ TRex parameters -.. function:: manual_matches(map<int,map<int,int64>>) +.. function:: manual_matches(map<int,map<Idx_t,int64>>) **default value:** {} @@ -1900,7 +1900,7 @@ TRex parameters .. function:: version(string) - **default value:** "1.0.4" + **default value:** "1.0.5" Current application version. -- GitLab