From 0148613a057ca1d010dab5d80ba903c86ca097b8 Mon Sep 17 00:00:00 2001 From: Moritz Maxeiner Date: Wed, 3 Mar 2021 14:47:34 +0100 Subject: [PATCH 1/4] [ci] snapshot 2021-03-03 --- ci/prepare.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/prepare.py b/ci/prepare.py index 0d97cd75..42a56eb7 100755 --- a/ci/prepare.py +++ b/ci/prepare.py @@ -58,5 +58,5 @@ def extract_cmake_package(artifacts, name): ("biotracker-utility", "bioroboticslab/biotracker/utility", job_stem), ("robofish-behavior_loader", "bioroboticslab/biotracker/behavior_loader", job_stem), ]: - with fetch_artifacts(project, "master", job) as artifacts: + with fetch_artifacts(project, "snapshot_20210303", job) as artifacts: extract_cmake_package(artifacts, name) From 2b7fe5e98eec1c772135539768d2d7e5db87ae4f Mon Sep 17 00:00:00 2001 From: Moritz Maxeiner Date: Thu, 15 Jul 2021 13:48:08 +0200 Subject: [PATCH 2/4] Fix pylon camera code to not crash due to exception --- Src/Model/ImageStream.cpp | 70 ++++++--------------------------------- 1 file changed, 11 insertions(+), 59 deletions(-) diff --git a/Src/Model/ImageStream.cpp b/Src/Model/ImageStream.cpp index f138c452..f54480ef 100644 --- a/Src/Model/ImageStream.cpp +++ b/Src/Model/ImageStream.cpp @@ -491,52 +491,10 @@ namespace BioTracker { /*********************************************************/ class ImageStream3PylonCamera : public ImageStream { private: - class ImageCache : public Pylon::CImageEventHandler - { - private: - boost::circular_buffer grabResults_m; - mutable std::mutex mutex_m; - - public: - ImageCache(std::size_t n) - : grabResults_m(n) - {} - - void push_back(Pylon::CGrabResultPtr const& grabResult) - { - std::scoped_lock lock(mutex_m); - grabResults_m.push_back(grabResult); - } - - Pylon::CGrabResultPtr const& front() const - { - std::scoped_lock lock(mutex_m); - return grabResults_m.front(); - } - - void pop_front() - { - std::scoped_lock lock(mutex_m); - grabResults_m.pop_front(); - } - - std::size_t size() const - { - std::scoped_lock lock(mutex_m); - return grabResults_m.size(); - } - - void OnImageGrabbed([[maybe_unused]] Pylon::CInstantCamera& camera, Pylon::CGrabResultPtr const& grabResult) override - { - push_back(grabResult); - } - }; - - ImageCache m_images; + Pylon::CGrabResultPtr m_grabbed; public: explicit ImageStream3PylonCamera(Config* cfg, CameraConfiguration conf) : ImageStream(0, cfg) - , m_images(m_frame_stride + static_cast(std::ceil(m_frame_stride / 2.))) , m_camera(getPylonDevice(conf._selector.index), Pylon::Cleanup_Delete) { m_fps = conf._fps == -1 ? _cfg->RecordFPS : conf._fps; @@ -576,17 +534,13 @@ namespace BioTracker { } qDebug() << "\nStarting to record on camera " << m_camera.GetDeviceInfo().GetFriendlyName(); - m_camera.RegisterImageEventHandler(&m_images, Pylon::ERegistrationMode::RegistrationMode_Append, Pylon::ECleanup::Cleanup_None); - m_camera.StartGrabbing(Pylon::GrabStrategy_OneByOne, Pylon::GrabLoop_ProvidedByInstantCamera); + m_camera.StartGrabbing(); nextFrame_impl(); m_recording = false; m_encoder = std::make_unique(m_fps, _cfg); } - ~ImageStream3PylonCamera() - { - m_camera.DeregisterImageEventHandler(&m_images); - } + GuiParam::MediaType type() const override { return GuiParam::MediaType::Camera; @@ -621,19 +575,17 @@ namespace BioTracker { bool nextFrame_impl() override { - while (m_images.size() < m_frame_stride) - std::this_thread::sleep_for(std::chrono::milliseconds(1000) / m_fps / 2); // Half of a frame intervals - for (auto i = std::size_t{1}; i < m_frame_stride; ++i) - m_images.pop_front(); - Pylon::CGrabResultPtr grabbed = m_images.front(); - m_images.pop_front(); - - if (!grabbed->GrabSucceeded()) { - qCritical() << "Unable to grab frame:" << grabbed->GetErrorDescription(); + for (std::size_t i = 1; i < m_frame_stride; ++i) { + if (!m_camera.RetrieveResult(2000, m_grabbed, Pylon::TimeoutHandling_Return)) { + return false; + } + } + + if (!m_camera.RetrieveResult(2000, m_grabbed, Pylon::TimeoutHandling_Return)) { return false; } - auto view = toOpenCV(grabbed); + auto view = toOpenCV(m_grabbed); auto scaled = std::make_shared(); cv::resize(view, *scaled, m_imageSize); set_current_frame(scaled); From a3ced114c829f8185cf4d1134304428e60766e8b Mon Sep 17 00:00:00 2001 From: Moritz Maxeiner Date: Tue, 21 Sep 2021 12:37:23 +0200 Subject: [PATCH 3/4] Fix incorrect opencv camera device selection on Linux See https://bugzilla.kernel.org/show_bug.cgi?id=199575 as to why just using indices doesn't work --- Src/Model/ImageStream.cpp | 2 +- Src/View/CameraDevice.cpp | 12 ++++++++---- Src/util/camera/base.h | 5 +++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Src/Model/ImageStream.cpp b/Src/Model/ImageStream.cpp index f54480ef..1f7512a9 100644 --- a/Src/Model/ImageStream.cpp +++ b/Src/Model/ImageStream.cpp @@ -395,7 +395,7 @@ namespace BioTracker { */ explicit ImageStream3OpenCVCamera(Config *cfg, CameraConfiguration conf) : ImageStream(0, cfg) - , m_capture(conf._selector.index) + , m_capture(conf._selector.name) , m_fps(m_capture.get(cv::CAP_PROP_FPS)) { // Give the camera some extra time to get ready: // Somehow opening it on first try sometimes does not succeed. diff --git a/Src/View/CameraDevice.cpp b/Src/View/CameraDevice.cpp index ec559916..63e3eefb 100644 --- a/Src/View/CameraDevice.cpp +++ b/Src/View/CameraDevice.cpp @@ -60,7 +60,11 @@ void CameraDevice::on_showPreviewButton_clicked() { case CameraType::OpenCV: { - m_capture.open(conf._selector.index); + if (conf._selector.index == cv::CAP_XIAPI) { + m_capture.open(cv::CAP_XIAPI); + } else { + m_capture.open(conf._selector.name); + } for (auto num_tries = 0; !m_capture.isOpened() && num_tries < 50; ++num_tries) std::this_thread::sleep_for(std::chrono::milliseconds(100)); @@ -145,7 +149,7 @@ void CameraDevice::listAllCameras() { ui->comboBox->addItem( cameras[index].description(), - QVariant::fromValue(CameraSelector{CameraType::OpenCV, index})); + QVariant::fromValue(CameraSelector{CameraType::OpenCV, index, cameras[index].deviceName().toStdString()})); } { @@ -154,7 +158,7 @@ void CameraDevice::listAllCameras() { ui->comboBox->addItem( "XIMEA default", - QVariant::fromValue(CameraSelector{CameraType::OpenCV, cv::CAP_XIAPI})); + QVariant::fromValue(CameraSelector{CameraType::OpenCV, cv::CAP_XIAPI, ""})); } } @@ -170,7 +174,7 @@ void CameraDevice::listAllCameras() { ui->comboBox->addItem( QString{devices[index].GetFriendlyName()}, - QVariant::fromValue(CameraSelector{CameraType::Pylon, index})); + QVariant::fromValue(CameraSelector{CameraType::Pylon, index, ""})); } } #endif diff --git a/Src/util/camera/base.h b/Src/util/camera/base.h index 7d28620f..0998ba98 100644 --- a/Src/util/camera/base.h +++ b/Src/util/camera/base.h @@ -14,8 +14,9 @@ enum class CameraType struct CameraSelector { - CameraType type; - int index; + CameraType type; + int index; + std::string name; }; Q_DECLARE_METATYPE(CameraSelector); From f7c47b45360169c051c52b79d8846792a4521a36 Mon Sep 17 00:00:00 2001 From: Moritz Maxeiner Date: Tue, 21 Sep 2021 12:44:11 +0200 Subject: [PATCH 4/4] Fix a crash when image to display is completely black --- Src/Model/TextureObject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/Model/TextureObject.cpp b/Src/Model/TextureObject.cpp index 781939be..673b3a96 100644 --- a/Src/Model/TextureObject.cpp +++ b/Src/Model/TextureObject.cpp @@ -24,7 +24,7 @@ void TextureObject::set(const cv::Mat &img) { // (usually 64F) so we need to map a [HUGE range] to -> [0 .. 255] double min, max; cv::minMaxLoc(img, &min, &max); - if (min >= 0 && min < 255 && max > 0 && max <= 255) { + if (min >= 0 && min < 255 && max >= 0 && max <= 255) { // do not refit if the range is actually inbetween [0 ... 255] img.convertTo(img8U, CV_8U); } else if (max > min) {