From 85f9ec779eec3780f54032f1be4a95fc6936f8b7 Mon Sep 17 00:00:00 2001 From: Tristan Walter <twalter@orn.mpg.de> Date: Tue, 3 Nov 2020 17:13:06 +0100 Subject: [PATCH] * DEBUG_CV added to debug/catch individual opencv commands * fixing some warnings --- .../src/commons/common/gui/DrawCVBase.cpp | 8 ++--- .../src/commons/common/gui/IMGUIBase.cpp | 11 ++++--- .../src/commons/common/gui/IMGUIBase.h | 2 +- .../src/commons/common/misc/PixelTree.cpp | 3 +- Application/src/commons/common/misc/defines.h | 5 --- .../src/commons/common/misc/metastring.h | 13 +++----- Application/src/commons/common/types.h | 14 ++++++++- Application/src/tracker/gui/Timeline.cpp | 31 ++++++++++--------- Application/src/tracker/tracking/Tracker.cpp | 2 +- Application/src/tracker/tracking/Tracker.h | 2 +- .../src/tracker/tracking/TrainingData.cpp | 22 ++++++------- 11 files changed, 60 insertions(+), 53 deletions(-) diff --git a/Application/src/commons/common/gui/DrawCVBase.cpp b/Application/src/commons/common/gui/DrawCVBase.cpp index 72ab0cb..b6c567d 100644 --- a/Application/src/commons/common/gui/DrawCVBase.cpp +++ b/Application/src/commons/common/gui/DrawCVBase.cpp @@ -126,9 +126,9 @@ namespace gui { if(i) #if CV_MAJOR_VERSION >= 3 - cv::line(_window, prev, (cv::Point2f)p.position(), cv::Scalar(c.b, c.g, c.r, c.a), t, cv::LINE_AA); + DEBUG_CV(cv::line(_window, prev, (cv::Point2f)p.position(), cv::Scalar(c.b, c.g, c.r, c.a), t, cv::LINE_AA)); #else - cv::line(_window, prev, (cv::Point2f)p.position(), cv::Scalar(c.b, c.g, c.r, c.a), t); + DEBUG_CV(cv::line(_window, prev, (cv::Point2f)p.position(), cv::Scalar(c.b, c.g, c.r, c.a), t)); #endif prev = p.position(); } @@ -139,9 +139,9 @@ namespace gui { auto &c = p.color(); #if CV_MAJOR_VERSION >= 3 - cv::line(_window, (cv::Point2f)ptr->points().at(i < ptr->points().size()-1 ? i+1 : 0), (cv::Point2f)p.position(), cv::Scalar(c.b, c.g, c.r, c.a), t, cv::LINE_AA); + DEBUG_CV(cv::line(_window, (cv::Point2f)ptr->points().at(i < ptr->points().size()-1 ? i+1 : 0), (cv::Point2f)p.position(), cv::Scalar(c.b, c.g, c.r, c.a), t, cv::LINE_AA)); #else - cv::line(_window, (cv::Point2f)ptr->points().at(i < ptr->points().size()-1 ? i+1 : 0), (cv::Point2f)p.position(), cv::Scalar(c.b, c.g, c.r, c.a), t); + DEBUG_CV(cv::line(_window, (cv::Point2f)ptr->points().at(i < ptr->points().size()-1 ? i+1 : 0), (cv::Point2f)p.position(), cv::Scalar(c.b, c.g, c.r, c.a), t)); #endif } } diff --git a/Application/src/commons/common/gui/IMGUIBase.cpp b/Application/src/commons/common/gui/IMGUIBase.cpp index 951e9e5..3d9e8a2 100644 --- a/Application/src/commons/common/gui/IMGUIBase.cpp +++ b/Application/src/commons/common/gui/IMGUIBase.cpp @@ -715,7 +715,9 @@ void PolyFillScanFlood(ImDrawList *draw, std::vector<ImVec2> *poly, ImColor colo static ImVec2 min, max; // polygon min/max points auto &io = ImGui::GetIO(); bool isMinMaxDone = false; - unsigned int polysize = poly->size(); + const auto polysize = poly->size(); + if(polysize < 3) + return; // smaller shapes (lines and points) cannot be filled // find the orthagonal bounding box // probably can put this as a predefined @@ -887,9 +889,8 @@ void PolyFillScanFlood(ImDrawList *draw, std::vector<ImVec2> *poly, ImColor colo // generate the line segments. { - int i = 0; - int l = scanHits.size() - 1; // we need pairs of points, this prevents segfault. - for (i = 0; i < l; i += 2) { + auto l = scanHits.size(); // we need pairs of points, this prevents segfault. + for (size_t i = 0; i+1 < l; i += 2) { draw->AddLine(scanHits[i], scanHits[i + 1], color, strokeWidth); } } @@ -964,7 +965,7 @@ void IMGUIBase::draw_element(const DrawOrder& order) { //list->AddConvexPolyFilled(points.data(), points.size(), (ImColor)ptr->fill_clr()); if(ptr->border_clr() != Transparent) - list->AddPolyline(points.data(), points.size(), (ImColor)ptr->border_clr(), true, 1); + list->AddPolyline(points.data(), (int)points.size(), (ImColor)ptr->border_clr(), true, 1); } break; diff --git a/Application/src/commons/common/gui/IMGUIBase.h b/Application/src/commons/common/gui/IMGUIBase.h index c577051..715d5c6 100644 --- a/Application/src/commons/common/gui/IMGUIBase.h +++ b/Application/src/commons/common/gui/IMGUIBase.h @@ -124,7 +124,7 @@ namespace gui { template<typename F> void exec_main_queue(F&& fn) { std::lock_guard<std::mutex> guard(_mutex); - _exec_main_queue.push(std::move(std::unique_ptr<baseFunctor>(new functor<F>(std::move(fn))))); + _exec_main_queue.push(std::unique_ptr<baseFunctor>(new functor<F>(std::move(fn)))); //_exec_main_queue.push(std::bind([](F& fn){ fn(); }, std::move(fn))); } diff --git a/Application/src/commons/common/misc/PixelTree.cpp b/Application/src/commons/common/misc/PixelTree.cpp index e57e30b..d514ba3 100644 --- a/Application/src/commons/common/misc/PixelTree.cpp +++ b/Application/src/commons/common/misc/PixelTree.cpp @@ -1004,7 +1004,8 @@ Node::Node(float x, float y, const std::array<int, 9>& neighbors) : x(x), y(y), auto prev = line->back(); for(auto pt : *line) { - cv::line(output, OFFSET(prev), OFFSET(pt), DarkCyan, max(1, 0.025 * scale)); + auto t = max(1, min(0.025 * scale, CV_MAX_THICKNESS)); + cv::line(output, OFFSET(prev), OFFSET(pt), DarkCyan, t); prev = pt; } cv::circle(output, OFFSET(node->position), 0.1 * scale, DarkCyan, max(1, 0.025 * scale)); diff --git a/Application/src/commons/common/misc/defines.h b/Application/src/commons/common/misc/defines.h index 58f600b..5d08863 100644 --- a/Application/src/commons/common/misc/defines.h +++ b/Application/src/commons/common/misc/defines.h @@ -301,11 +301,6 @@ namespace cmn { template< class T1 , class T2 > struct is_pair< std::pair< T1 , T2 > > : public std::true_type {}; - template<class T, class U> - constexpr T narrow_cast(U&& u) noexcept { - return static_cast<T>(std::forward<U>(u)); - } - class IndexedDataTransport { protected: GETTER_SETTER(long_t, index) diff --git a/Application/src/commons/common/misc/metastring.h b/Application/src/commons/common/misc/metastring.h index 51d9052..5abcc36 100644 --- a/Application/src/commons/common/misc/metastring.h +++ b/Application/src/commons/common/misc/metastring.h @@ -27,15 +27,6 @@ namespace cmn { } } - template< class T > - struct remove_cvref { - typedef std::remove_cv_t<std::remove_reference_t<T>> type; - }; - - template< class T > - using remove_cvref_t = typename remove_cvref<T>::type; - - class illegal_syntax : public std::logic_error { public: illegal_syntax(const std::string& str) : std::logic_error(str) { } @@ -282,9 +273,13 @@ namespace cmn { */ //template<class Q> std::string name(const typename std::enable_if< std::is_integral<typename std::remove_cv<Q>::type>::value && !std::is_same<bool, typename std::remove_cv<Q>::type>::value, Q >::type* =nullptr) { return sizeof(Q) == sizeof(long) ? "long" : "int"; } template<class Q> std::string name(const typename std::enable_if< std::is_same<int, typename std::remove_cv<Q>::type>::value, Q >::type* =nullptr) { return "int"; } + template<class Q> std::string name(const typename std::enable_if< std::is_same<short, typename std::remove_cv<Q>::type>::value && !std::is_same<int16_t, short>::value, Q >::type* =nullptr) { return "short"; } template<class Q> std::string name(const typename std::enable_if< !std::is_same<int32_t, int>::value && std::is_same<int32_t, typename std::remove_cv<Q>::type>::value, Q >::type* =nullptr) { return "int32"; } template<class Q> std::string name(const typename std::enable_if< !std::is_same<uint32_t, unsigned int>::value && std::is_same<uint32_t, typename std::remove_cv<Q>::type>::value, Q >::type* =nullptr) { return "uint32"; } + template<class Q> std::string name(const typename std::enable_if< std::is_same<int16_t, typename std::remove_cv<Q>::type>::value, Q >::type* =nullptr) { return "int16"; } + template<class Q> std::string name(const typename std::enable_if< std::is_same<uint16_t, typename std::remove_cv<Q>::type>::value, Q >::type* =nullptr) { return "uint16"; } template<class Q> std::string name(const typename std::enable_if< std::is_same<unsigned int, typename std::remove_cv<Q>::type>::value, Q >::type* =nullptr) { return "uint"; } + template<class Q> std::string name(const typename std::enable_if< std::is_same<unsigned short, typename std::remove_cv<Q>::type>::value && !std::is_same<uint16_t, unsigned short>::value, Q >::type* =nullptr) { return "ushort"; } template<class Q> std::string name(const typename std::enable_if< !std::is_same<uint64_t, unsigned long>::value && std::is_same<uint64_t, typename std::remove_cv<Q>::type>::value, Q >::type* =nullptr) { return "uint64"; } template<class Q> std::string name(const typename std::enable_if< std::is_same<unsigned long, typename std::remove_cv<Q>::type>::value, Q >::type* =nullptr) { return "ulong"; } template<class Q> std::string name(const typename std::enable_if< !std::is_same<int64_t, long>::value && std::is_same<int64_t, typename std::remove_cv<Q>::type>::value, Q >::type* =nullptr) { return "int64"; } diff --git a/Application/src/commons/common/types.h b/Application/src/commons/common/types.h index 7bbf560..bdcefbb 100644 --- a/Application/src/commons/common/types.h +++ b/Application/src/commons/common/types.h @@ -16,9 +16,21 @@ */ namespace cmn { - typedef std::vector<std::tuple<std::shared_ptr<std::vector<HorizontalLine>>, std::shared_ptr<std::vector<uchar>>>> blobs_t; +typedef std::vector<std::tuple<std::shared_ptr<std::vector<HorizontalLine>>, std::shared_ptr<std::vector<uchar>>>> blobs_t; +constexpr int CV_MAX_THICKNESS = 32767; + +template< class T > +struct remove_cvref { + typedef std::remove_cv_t<std::remove_reference_t<T>> type; +}; + +template< class T > +using remove_cvref_t = typename remove_cvref<T>::type; } + +#define DEBUG_CV(COMMAND) try { COMMAND; } catch(const cv::Exception& e) { Except("OpenCV Exception ('%s':%d): %s\n%s", __FILE__, __LINE__, #COMMAND, e.what()); } + namespace tf { void imshow(const std::string& name, const cv::Mat& mat, std::string label = ""); void show(); diff --git a/Application/src/tracker/gui/Timeline.cpp b/Application/src/tracker/gui/Timeline.cpp index 857ae3c..39c3b2d 100644 --- a/Application/src/tracker/gui/Timeline.cpp +++ b/Application/src/tracker/gui/Timeline.cpp @@ -76,15 +76,14 @@ namespace gui { _recognition_image.set_source(Image()); }*/ -void Timeline::update_consecs(float max_w, const Range<long_t>& consec, const std::vector<Rangel>& other_consec, float scale) { +void Timeline::update_consecs(float max_w, const Range<long_t>& consec, const std::vector<Rangel>& other_consec, float _scale) { if(!_bar) return; static Range<long_t> previous_consec(-1, -1); static std::vector<Rangel> previous_other_consec = {}; static float previous_scale = 0; - if(scale < 1) - scale = 1; + const double scale = max(1, min(_scale, CV_MAX_THICKNESS)); float new_height = roundf(bar_height) + 5 * scale; if(consec == previous_consec @@ -128,8 +127,8 @@ void Timeline::update_consecs(float max_w, const Range<long_t>& consec, const st Gray }; - cv::rectangle(mat, position - Vec2(1), position - Vec2(1) + size + Size2(2), colors.front().alpha(50), cv::FILLED); - cv::rectangle(mat, position - Vec2(1), position - Vec2(1) + size + Size2(2), Color(alpha, alpha, alpha, 255)); + DEBUG_CV(cv::rectangle(mat, position - Vec2(1), position - Vec2(1) + size + Size2(2), colors.front().alpha(50))); + DEBUG_CV(cv::rectangle(mat, position - Vec2(1), position - Vec2(1) + size + Size2(2), Color(alpha, alpha, alpha, 255))); //base.rect(Bounds(position - Vec2(1), size + Size2(2)), colors.front().alpha(50), Color(alpha, alpha, alpha, 255)); colors.pop_front(); @@ -137,21 +136,25 @@ void Timeline::update_consecs(float max_w, const Range<long_t>& consec, const st position = offset + Vec2(max_w * consec.start / float(_frame_info.video_length), 0); size = Size2(max_w * (consec.end - consec.start) / float(_frame_info.video_length), bar_height); - cv::rectangle(mat, position - Vec2(1), position - Vec2(1) + size + Size2(2), colors.front().alpha(50), cv::FILLED); - cv::rectangle(mat, position - Vec2(1), position - Vec2(1) + size + Size2(2), Color(alpha, alpha, alpha, 255)); + DEBUG_CV(cv::rectangle(mat, position - Vec2(1), position - Vec2(1) + size + Size2(2), colors.front().alpha(50), cv::FILLED)); + DEBUG_CV(cv::rectangle(mat, position - Vec2(1), position - Vec2(1) + size + Size2(2), Color(alpha, alpha, alpha, 255))); colors.pop_front(); } } //base.line(pos - Vec2(0,1), pos + Vec2(max_w * tracker_endframe / float(_frame_info.video_length), 0) - Vec2(0,1), 1, Red.alpha(255)); + + auto thickness = narrow_cast<int>(scale); + assert(thickness > 0); + for(auto &consec : _frame_info.consecutive) { if( consec.length() > 2 && consec.length() >= consec.length() * 0.25) { auto position = offset + Vec2(max_w * consec.start / float(_frame_info.video_length), 0); auto size = Size2(max_w * consec.length() / float(_frame_info.video_length), bar_height); --position.y; - cv::line(mat, position, position + Vec2(size.width, 0), Green.alpha(alpha)); - cv::line(mat, position, position + Vec2(0, -5 * scale), Green.alpha(alpha), scale); + DEBUG_CV(cv::line(mat, position, position + Vec2(size.width, 0), Green.alpha(alpha))); + DEBUG_CV(cv::line(mat, position, position + Vec2(0, -5 * scale), Green.alpha(alpha), thickness)); } } @@ -160,8 +163,8 @@ void Timeline::update_consecs(float max_w, const Range<long_t>& consec, const st auto position = offset + Vec2(max_w * range.start / float(_frame_info.video_length), 0); auto size = Size2(max_w * range.length() / float(_frame_info.video_length), bar_height); - cv::rectangle(mat, position - Vec2(1), position - Vec2(1, 0) + size + Size2(2), Red.alpha(50), cv::FILLED); - cv::rectangle(mat, position - Vec2(1), position - Vec2(1, 0) + size + Size2(2), Color(alpha, alpha, alpha, 255)); + DEBUG_CV(cv::rectangle(mat, position - Vec2(1), position - Vec2(1, 0) + size + Size2(2), Red.alpha(50), cv::FILLED)); + DEBUG_CV(cv::rectangle(mat, position - Vec2(1), position - Vec2(1, 0) + size + Size2(2), Color(alpha, alpha, alpha, 255))); } } } @@ -544,8 +547,8 @@ void Timeline::update_consecs(float max_w, const Range<long_t>& consec, const st if(previous_point.x != -1 && previous_point.x != x) { Vec2 point(x, individual_coverage(tracker_endframe) * img.rows); - cv::line(img, previous_point, Vec2(x-1, previous_point.y), Red); - cv::line(img, Vec2(x-1, previous_point.y), point, Red); + DEBUG_CV(cv::line(img, previous_point, Vec2(x-1, previous_point.y), Red)); + DEBUG_CV(cv::line(img, Vec2(x-1, previous_point.y), point, Red)); } } @@ -685,7 +688,7 @@ void Timeline::update_consecs(float max_w, const Range<long_t>& consec, const st float x1 = Tracker::average().cols; Debug("Clearing from %f to %f", x0, x1 + pos.x); - cv::rectangle(img, Vec2(x0, 0), Vec2(pos + Vec2(x1, img.rows)), Transparent, -1); + DEBUG_CV(cv::rectangle(img, Vec2(x0, 0), Vec2(pos + Vec2(x1, img.rows)), Transparent, -1)); } } diff --git a/Application/src/tracker/tracking/Tracker.cpp b/Application/src/tracker/tracking/Tracker.cpp index 815cbdc..f269fed 100644 --- a/Application/src/tracker/tracking/Tracker.cpp +++ b/Application/src/tracker/tracking/Tracker.cpp @@ -4095,7 +4095,7 @@ void Tracker::update_iterator_maps(long_t frame, const Tracker::set_of_individua fclose(f); } -pv::BlobPtr Tracker::find_blob_noisy(std::map<uint32_t, pv::BlobPtr>& blob_to_id, uint32_t bid, int64_t pid, const Bounds& bounds, long_t frame) +pv::BlobPtr Tracker::find_blob_noisy(std::map<uint32_t, pv::BlobPtr>& blob_to_id, int64_t bid, int64_t pid, const Bounds& bounds, long_t frame) { if(blob_to_id.count(bid) == 0) { if(pid != -1) { diff --git a/Application/src/tracker/tracking/Tracker.h b/Application/src/tracker/tracking/Tracker.h index 0e160cb..40d0627 100644 --- a/Application/src/tracker/tracking/Tracker.h +++ b/Application/src/tracker/tracking/Tracker.h @@ -271,7 +271,7 @@ CREATE_STRUCT(Settings, void prepare_shutdown(); void wait(); - static pv::BlobPtr find_blob_noisy(std::map<uint32_t, pv::BlobPtr>& blob_to_id, uint32_t bid, int64_t pid, const Bounds& bounds, long_t frame); + static pv::BlobPtr find_blob_noisy(std::map<uint32_t, pv::BlobPtr>& blob_to_id, int64_t bid, int64_t pid, const Bounds& bounds, long_t frame); //static bool generate_training_images(pv::File&, std::map<long_t, std::set<long_t>> individuals_per_frame, TrainingData&, const std::function<void(float)>& = [](float){}, const TrainingData* source = nullptr); //static bool generate_training_images(pv::File&, const std::set<long_t>& frames, TrainingData&, const std::function<void(float)>& = [](float){}); diff --git a/Application/src/tracker/tracking/TrainingData.cpp b/Application/src/tracker/tracking/TrainingData.cpp index e8d8c9c..f25cfd3 100644 --- a/Application/src/tracker/tracking/TrainingData.cpp +++ b/Application/src/tracker/tracking/TrainingData.cpp @@ -339,8 +339,8 @@ std::unique_ptr<Image> TrainingData::draw_coverage(const std::map<long_t, float> smooth_points[i].y = smooth_points[i].y * 0.5 + unique_points[i].y / weight * 0.5; if(i > 0) - cv::line(mat, smooth_points[i], smooth_points[i-1], color.alpha(200), 2, cv::LINE_AA); - cv::circle(mat, unique_points[i], 2, color.alpha(200)); + DEBUG_CV(cv::line(mat, smooth_points[i], smooth_points[i-1], color.alpha(200), 2, cv::LINE_AA)); + DEBUG_CV(cv::circle(mat, unique_points[i], 2, color.alpha(200))); } unique_points = smooth_points; }; @@ -362,8 +362,8 @@ std::unique_ptr<Image> TrainingData::draw_coverage(const std::map<long_t, float> for(auto &range : added_ranges) { Vec2 topleft((range.start - analysis_range.start) * column_width, 0); Vec2 bottomright((range.end - analysis_range.start + 1) * column_width, 1); - cv::rectangle(mat, topleft, bottomright, gui::Green.alpha(100 + 100), cv::FILLED); - cv::putText(mat, Meta::toStr(range), (topleft + (bottomright - topleft) * 0.5) + Vec2(0,10), cv::FONT_HERSHEY_PLAIN, 0.5, gui::Green); + DEBUG_CV(cv::rectangle(mat, topleft, bottomright, gui::Green.alpha(100 + 100), cv::FILLED)); + DEBUG_CV(cv::putText(mat, Meta::toStr(range), (topleft + (bottomright - topleft) * 0.5) + Vec2(0,10), cv::FONT_HERSHEY_PLAIN, 0.5, gui::Green)); } } @@ -377,20 +377,20 @@ std::unique_ptr<Image> TrainingData::draw_coverage(const std::map<long_t, float> Vec2 topleft((next_range.start - analysis_range.start) * column_width, 0); Vec2 bottomright((next_range.end - analysis_range.start + 1) * column_width, 1); - cv::rectangle(mat, topleft, bottomright, color.alpha(100 + 100), cv::FILLED); + DEBUG_CV(cv::rectangle(mat, topleft, bottomright, color.alpha(100 + 100), cv::FILLED)); if(it == --next_ranges.rend()) - cv::putText(mat, "next: "+Meta::toStr(next_range), (topleft + (bottomright - topleft) * 0.5) + Vec2(10), cv::FONT_HERSHEY_PLAIN, 0.5, color); + DEBUG_CV(cv::putText(mat, "next: "+Meta::toStr(next_range), (topleft + (bottomright - topleft) * 0.5) + Vec2(10), cv::FONT_HERSHEY_PLAIN, 0.5, color)); if(assigned_unique_averages.count(next_range)) { auto && [distance, extended_range] = assigned_unique_averages.at(next_range); Vec2 rtl((extended_range.start() - analysis_range.start) * column_width, (1 - distance / 110.0) * mat.rows + 5); Vec2 rbr((extended_range.end() - analysis_range.start + 1) * column_width, (1 - distance / 110.0) * mat.rows + 2 + 5); - cv::rectangle(mat, rtl, rbr, color); + DEBUG_CV(cv::rectangle(mat, rtl, rbr, color)); - cv::line(mat, Vec2(rtl.x, rtl.y), Vec2(topleft.x, bottomright.y), gui::Cyan); - cv::line(mat, Vec2(rbr.x, rtl.y), Vec2(bottomright.x, bottomright.y), gui::Cyan.alpha(50)); + DEBUG_CV(cv::line(mat, Vec2(rtl.x, rtl.y), Vec2(topleft.x, bottomright.y), gui::Cyan)); + DEBUG_CV(cv::line(mat, Vec2(rbr.x, rtl.y), Vec2(bottomright.x, bottomright.y), gui::Cyan.alpha(50))); } } } @@ -400,13 +400,13 @@ std::unique_ptr<Image> TrainingData::draw_coverage(const std::map<long_t, float> for(size_t i=0; i<per.frame_indexes.size(); ++i) { Vec2 topleft((per.frame_indexes[i] - analysis_range.start) * column_width, row_height * (id + 0.2)); Vec2 bottomright((per.frame_indexes[i] - analysis_range.start + 1) * column_width, row_height * (id + 0.8)); - cv::rectangle(mat, topleft, bottomright, gui::White.alpha(100 + 100), cv::FILLED); + DEBUG_CV(cv::rectangle(mat, topleft, bottomright, gui::White.alpha(100 + 100), cv::FILLED)); } } } for(auto id : all_classes()) - cv::putText(mat, Meta::toStr(id), Vec2(10, row_height * (id + 0.25)), cv::FONT_HERSHEY_PLAIN, 0.75, gui::White); + DEBUG_CV(cv::putText(mat, Meta::toStr(id), Vec2(10, row_height * (id + 0.25)), cv::FONT_HERSHEY_PLAIN, 0.75, gui::White)); return image; } -- GitLab