#ifndef ANSYOLO12OD_H #define ANSYOL12OOD_H #pragma once #include "ANSEngineCommon.h" #include #include #include #include #include #include #include #include #include #include #include #include namespace ANSCENTER { // Standard Yolo engine class: yolo12 class ANSENGINE_API YOLO12OD :public ANSODBase { public: virtual bool Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) override; virtual bool LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword)override; virtual bool LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap)override; virtual bool OptimizeModel(bool fp16, std::string& optimizedModelFolder); std::vector RunInference(const cv::Mat& input); std::vector RunInference(const cv::Mat& input, const std::string& camera_id); bool Destroy(); ~YOLO12OD(); private: Ort::Env env{ nullptr }; // ONNX Runtime environment Ort::SessionOptions sessionOptions{ nullptr }; // Session options for ONNX Runtime Ort::Session session{ nullptr }; // ONNX Runtime session for running inference bool isDynamicInputShape{}; // Flag indicating if input shape is dynamic cv::Size inputImageShape; // Expected input image shape for the model std::string _modelFilePath; // Vectors to hold allocated input and output node names std::vector inputNodeNameAllocatedStrings; std::vector inputNames; std::vector outputNodeNameAllocatedStrings; std::vector outputNames; size_t numInputNodes, numOutputNodes; // Number of input and output nodes in the model std::vector classNames; // Vector of class names loaded from file std::vector classColors; // Vector of colors for each class float m_imgWidth = 0; float m_imgHeight = 0; protected: bool loadModel(const std::string& modelPath, bool useGPU = true); std::vector detect(const cv::Mat& image, float confThreshold = 0.4f, float iouThreshold = 0.45f); //cv::Mat preprocess(const cv::Mat& image, float*& blob, std::vector& inputTensorShape); cv::Mat preprocess(const cv::Mat& image, std::vector& blob, std::vector& inputTensorShape); std::vector postprocess(const cv::Size& originalImageSize, const cv::Size& resizedImageShape, const std::vector& outputTensors, float confThreshold, float iouThreshold); private: template typename std::enable_if::value, T>::type inline clamp(const T& value, const T& low, const T& high) { // Ensure the range [low, high] is valid; swap if necessary T validLow = low < high ? low : high; T validHigh = low < high ? high : low; // Clamp the value to the range [validLow, validHigh] if (value < validLow) return validLow; if (value > validHigh) return validHigh; return value; } size_t vectorProduct(const std::vector& vector); void letterBox(const cv::Mat& image, cv::Mat& outImage, const cv::Size& newShape, const cv::Scalar& color = cv::Scalar(114, 114, 114), bool auto_ = true, bool scaleFill = false, bool scaleUp = true, int stride = 32); BoundingBox scaleCoords(const cv::Size& imageShape, BoundingBox coords, const cv::Size& imageOriginalShape, bool p_Clip); void NMSBoxes(const std::vector& boundingBoxes, const std::vector& scores, float scoreThreshold, float nmsThreshold, std::vector& indices); }; } #endif