OpenCV SSD MobileNet V2 模型:尽管有置信阈值,仍无法检测到目标

问题描述 投票:0回答:1

我使用带有 OpenCV 的 DNN 模块的 Basler 相机来运行 SSD 对象检测模型 (mobilenetv2_050_Opset18.onnx),并在 C++ 上启用 CUDA 支持。 Basler 相机正确捕获帧,OpenCV 正在处理图像,但 SSD 模型没有检测到任何物体,即使置信度阈值低至 0.0001 也没有检测到。

关键细节: 相机:Basler 相机配置为 640x480 分辨率和 BGR8 像素格式。

模型:SSD模型(mobilenetv2_050_Opset18.onnx)使用带有CUDA后端(DNN_BACKEND_CUDA)的OpenCV DNN模块加载。

CUDA 支持:使用 CUDA 编译的 OpenCV 和使用 cmake 的 cuDNN 支持。后端设置为使用 CUDA (net.setPreferableBackend(DNN_BACKEND_CUDA)),目标也设置为 CUDA (net.setPreferableTarget(DNN_TARGET_CUDA))。

问题:即使置信度阈值低至 0.0001,模型也未检测到任何物体。我已经验证相机和 CUDA 环境都按预期运行。

我的代码有什么问题?

#include <iostream>
#include <pylon/PylonIncludes.h>
#include <pylon/InstantCamera.h>
#include <pylon/BaslerUniversalInstantCamera.h>
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <opencv2/core/cuda.hpp>

using namespace Pylon;
using namespace GenApi;
using namespace std;
using namespace cv;
using namespace cv::dnn;

int main() {
    PylonInitialize();
    
    try {
        // Basler camera setup
        CInstantCamera camera(CTlFactory::GetInstance().CreateDevice(CDeviceInfo().SetSerialNumber("40432296")));
        camera.Open();

        // Configure the camera settings
        INodeMap& nodemap = camera.GetNodeMap();
        CIntegerParameter width(nodemap, "Width");
        CIntegerParameter height(nodemap, "Height");
        CEnumParameter pixelFormat(nodemap, "PixelFormat");
        CFloatParameter exposureTime(nodemap, "ExposureTime");
        CFloatParameter acquisitionFrameRate(nodemap, "AcquisitionFrameRate");
        CIntegerParameter xOffset(nodemap, "OffsetX");
        CIntegerParameter yOffset(nodemap, "OffsetY");

        width.SetValue(640, IntegerValueCorrection_Nearest);
        height.SetValue(480, IntegerValueCorrection_Nearest);
        pixelFormat.SetValue("BGR8");
        exposureTime.SetValue(15000.0);
        acquisitionFrameRate.SetValue(5000.0);
        xOffset.SetValue(0);
        yOffset.SetValue(0);

        CGrabResultPtr grabResult;

        // Load SSD model
        Net net = readNetFromONNX("mobilenetv2_050_Opset18.onnx");
        net.setPreferableBackend(DNN_BACKEND_CUDA);
        net.setPreferableTarget(DNN_TARGET_CUDA);

        camera.StartGrabbing();
        Mat frame;
        while (camera.IsGrabbing()) {
            camera.RetrieveResult(5000, grabResult, TimeoutHandling_ThrowException);
            if (grabResult->GrabSucceeded()) {
                uint8_t* buffer = (uint8_t*)grabResult->GetBuffer();
                frame = Mat(grabResult->GetHeight(), grabResult->GetWidth(), CV_8UC3, buffer);

                // Run SSD model
                Mat blob = blobFromImage(frame, 1.0, Size(640, 480), Scalar(), true, false);
                net.setInput(blob);

                Mat detections = net.forward();

                for (int i = 0; i < detections.size[2]; ++i) {
                    float confidence = detections.ptr<float>(0)[i * 7 + 2]; // Access confidence

                    if (confidence > 0.0001) {
                        int xLeftBottom = static_cast<int>(detections.ptr<float>(0)[i * 7 + 3] * frame.cols);
                        int yLeftBottom = static_cast<int>(detections.ptr<float>(0)[i * 7 + 4] * frame.rows);
                        int xRightTop = static_cast<int>(detections.ptr<float>(0)[i * 7 + 5] * frame.cols);
                        int yRightTop = static_cast<int>(detections.ptr<float>(0)[i * 7 + 6] * frame.rows);

                        rectangle(frame, Point(xLeftBottom, yLeftBottom), Point(xRightTop, yRightTop), Scalar(0, 255, 0), 2);
                    }
                }

                imshow("SSD Detection", frame);
                if (waitKey(1) == 27) break; // Press 'ESC' to exit
            }
        }

        camera.Close();
    }
    catch (const GenericException& e) {
        std::cerr << "Error: " << e.GetDescription() << std::endl;
    }

    PylonTerminate();
    return 0;
}

我是计算机视觉新手,我的目标是高性能(100+ fps)实时对象检测模型,以处理 640x480 等低分辨率素材。OpenCv 是一个好的起点,还是我应该跳过 C++ 并使用 Python更好的支持等。在对象检测模型性能方面,使用 C++ 是否比 Python 更有优势?

c++ opencv image-processing computer-vision
1个回答
0
投票

而不是

blobFromImage(frame, 1.0, Size(640, 480), Scalar(), true, false);

尝试

Mat blob = blobFromImage(frame, 1/127.5, Size(300, 300), Scalar(127.5, 127.5, 127.5), true, false);
net.setInput(blob);
Mat detections = net.forward();
© www.soinside.com 2019 - 2024. All rights reserved.