From aded92d8b3d4a4f37fcd59d51ebd1faa793a0a3a Mon Sep 17 00:00:00 2001 From: Timm Eversmeyer Date: Thu, 13 Nov 2025 20:47:46 +0100 Subject: [PATCH 1/2] Add support for 320x320 input size in YOLOv11SegDetectorNcnn constructor --- src/yolo11segncnn.cpp | 13 ++++++++++--- src/yolo11segncnn.h | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/yolo11segncnn.cpp b/src/yolo11segncnn.cpp index 111e4070..a1f8770b 100644 --- a/src/yolo11segncnn.cpp +++ b/src/yolo11segncnn.cpp @@ -9,7 +9,7 @@ YOLOv11SegDetectorNcnn::YOLOv11SegDetectorNcnn(const std::string &modelPath, const std::string &labelsPath, - bool useGPU) : Yolo11Segementation(labelsPath) + bool useGPU, bool use320x320input) : Yolo11Segementation(labelsPath) { QString ressourcePathGeneric = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "models", QStandardPaths::LocateDirectory); QString ressourcePathApp = QStandardPaths::locate(QStandardPaths::AppDataLocation, "models", QStandardPaths::LocateDirectory); @@ -48,7 +48,14 @@ YOLOv11SegDetectorNcnn::YOLOv11SegDetectorNcnn(const std::string &modelPath, numOutputNodes = net.output_names().size(); isDynamicInputShape = false; // Assume static input shape by default. NCNN models typically have fixed input shapes. - inputImageShape = cv::Size(640, 640); // Default shape. This is fixed for YOLOv11SegNCNN + + if(use320x320input) { + inputImageShape = cv::Size(320, 320); + } + else + { + inputImageShape = cv::Size(640, 640); // Default shape. This is fixed for YOLOv11SegNCNN + } // Input if (numInputNodes != 1) @@ -277,7 +284,7 @@ std::vector YOLOv11SegDetectorNcnn::segment(const cv::Mat &image, cv::Scalar(114, 114, 114), /*auto_=*/false, /*scaleFill=*/false, /*scaleUp=*/true, /*stride=*/32); - ncnn::Mat in = ncnn::Mat::from_pixels_resize(letterboxImage.data, ncnn::Mat::PIXEL_BGR2RGB, letterboxImage.cols, letterboxImage.rows, 640, 640); + ncnn::Mat in = ncnn::Mat::from_pixels_resize(letterboxImage.data, ncnn::Mat::PIXEL_BGR2RGB, letterboxImage.cols, letterboxImage.rows, inputImageShape.width, inputImageShape.height); const float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f}; in.substract_mean_normalize(0, norm_vals); diff --git a/src/yolo11segncnn.h b/src/yolo11segncnn.h index 02c24c62..7f19c006 100644 --- a/src/yolo11segncnn.h +++ b/src/yolo11segncnn.h @@ -30,7 +30,7 @@ class YOLOv11SegDetectorNcnn : public Yolo11Segementation { public: YOLOv11SegDetectorNcnn(const std::string &modelPath, const std::string &labelsPath, - bool useGPU = false); + bool useGPU = false, bool use320x320input = false); // Main API std::vector segment(const cv::Mat &image, From 71cd33b50d6e5d1c098ac2bdcce975b1319b09f4 Mon Sep 17 00:00:00 2001 From: Timm Eversmeyer Date: Thu, 13 Nov 2025 21:24:46 +0100 Subject: [PATCH 2/2] Add NCNN_LOW_RES option for faster preview in neural network runtime selection --- qml/SettingsMenuForm.ui.qml | 4 ++-- src/replacebackgroundvideofilter.cpp | 14 ++++++++++++++ src/replacebackgroundvideofilter.h | 3 ++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/qml/SettingsMenuForm.ui.qml b/qml/SettingsMenuForm.ui.qml index dc0239fe..b4aba3d8 100644 --- a/qml/SettingsMenuForm.ui.qml +++ b/qml/SettingsMenuForm.ui.qml @@ -242,8 +242,8 @@ Item { id: comboBoxNeuralNetworkRuntime textRole: "text" valueRole: "value" - model: [{text: "ONNX Runtime", value: "ONNX"}, {text: "NCNN Runtime", value: "NCNN"}] - Layout.preferredWidth: 200 + model: [{text: "ONNX Runtime", value: "ONNX"}, {text: "NCNN Runtime", value: "NCNN"}, {text: "NCNN Runtime (faster preview)", value: "NCNN_LOW_RES"} ] + Layout.preferredWidth: 250 } } } diff --git a/src/replacebackgroundvideofilter.cpp b/src/replacebackgroundvideofilter.cpp index 38ff129c..9692e770 100644 --- a/src/replacebackgroundvideofilter.cpp +++ b/src/replacebackgroundvideofilter.cpp @@ -57,6 +57,10 @@ void ReplaceBackgroundVideoFilter::setNeuralNetworkRuntime(QString runtime) { newRuntime = NeuralNetworkRuntime::ONNX; } + else if (runtime.contains("NCNN_LOW_RES")) + { + newRuntime = NeuralNetworkRuntime::NCNN_LOW_RES; + } else if (runtime.contains("NCNN")) { newRuntime = NeuralNetworkRuntime::NCNN; @@ -111,6 +115,10 @@ QString ReplaceBackgroundVideoFilter::getNeuralNetworkRuntime() const { return QString("NCNN"); } + else if (mNeuralNetworkRuntime == NeuralNetworkRuntime::NCNN_LOW_RES) + { + return QString("NCNN_LOW_RES"); + } else { return QString("Unknown"); @@ -317,6 +325,12 @@ void ReplaceBackgroundFilterRunable::changeNeuralNetworkRuntime(const NeuralNetw mYoloSegmentorPreview.reset(new YOLOv11SegDetectorNcnn("yolo11n-seg_ncnn_model", "coco.names", false)); mYoloSegmentorHighRes.reset(new YOLOv11SegDetectorNcnn("yolo11x-seg_ncnn_model", "coco.names", false)); } + else if (runtime == NeuralNetworkRuntime::NCNN_LOW_RES) + { + qDebug() << "[INFO] Change YOLOv11Segmentation runtime to NCNN_LOW_RES"; + mYoloSegmentorPreview.reset(new YOLOv11SegDetectorNcnn("yolo11n-seg_ncnn_model_320", "coco.names", false, true)); + mYoloSegmentorHighRes.reset(new YOLOv11SegDetectorNcnn("yolo11x-seg_ncnn_model", "coco.names", false)); + } } void ReplaceBackgroundFilterRunable::prepareBackground(cv::Mat &bg, cv::Size size) diff --git a/src/replacebackgroundvideofilter.h b/src/replacebackgroundvideofilter.h index 770df6cc..6ca2ec6a 100644 --- a/src/replacebackgroundvideofilter.h +++ b/src/replacebackgroundvideofilter.h @@ -17,7 +17,8 @@ class ReplaceBackgroundFilterRunable; enum class NeuralNetworkRuntime { ONNX, - NCNN + NCNN, + NCNN_LOW_RES }; class ReplaceBackgroundVideoFilter : public QVideoFrameInput