上传yolo3和yolo8合并的代码
parent
a650161d80
commit
9f842cfef0
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"memory": "cpp"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
//// YOLOManager.cpp
|
||||||
|
//#include "YOLOManager.h"
|
||||||
|
//
|
||||||
|
//YOLOManager::~YOLOManager() {
|
||||||
|
// // 这里可以添加清理资源的代码
|
||||||
|
//}
|
||||||
|
#include "YOLOManager.h"
|
||||||
|
#include <alg_jd_yolo3.h>
|
||||||
|
#include <alg_jd_yolo8.h>
|
||||||
|
|
||||||
|
bool YOLOManager::InitializeDetector(SysConf& sys_conf, uint8_t Num) {
|
||||||
|
|
||||||
|
bool ret=true;
|
||||||
|
params[Num].rectConfidenceThreshold = sys_conf.ConfThreshold;
|
||||||
|
params[Num].modelPath = sys_conf.model_path.toStdString();
|
||||||
|
params[Num].imgSize = { IMAGE_WIDTH, IMAGE_HEIGHT };
|
||||||
|
#ifdef USE_CUDA
|
||||||
|
params[Num].cudaEnable = true;
|
||||||
|
#else
|
||||||
|
params[Num].cudaEnable = false;
|
||||||
|
#endif
|
||||||
|
//params[Num].modelType = YOLO_DETECT_V3;
|
||||||
|
params[Num].modelType = YOLO_DETECT_V8;
|
||||||
|
|
||||||
|
if (params[Num].modelType == YOLO_DETECT_V8)
|
||||||
|
detector[Num] = std::unique_ptr<YOLO>(new YOLO_V8());
|
||||||
|
else if (params[Num].modelType == YOLO_DETECT_V3)
|
||||||
|
detector[Num] = std::unique_ptr<YOLO>(new YOLO_V3());
|
||||||
|
|
||||||
|
if (detector[Num])
|
||||||
|
{
|
||||||
|
ret&=detector[Num]->InitParam(params[Num]);
|
||||||
|
ret&=detector[Num]->CreateSession(params[Num].modelPath);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "common.h"
|
||||||
|
#include <basecamera.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
|
||||||
|
enum MODEL_TYPE
|
||||||
|
{
|
||||||
|
YOLO_DETECT_V3 = 0,
|
||||||
|
//FLOAT32 MODEL
|
||||||
|
YOLO_DETECT_V8 = 1,
|
||||||
|
YOLO_POSE = 2,
|
||||||
|
YOLO_CLS = 3,
|
||||||
|
//FLOAT16 MODEL
|
||||||
|
YOLO_DETECT_V8_HALF = 4,
|
||||||
|
YOLO_POSE_V8_HALF = 5,
|
||||||
|
YOLO_CLS_HALF = 6
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _DL_INIT_PARAM
|
||||||
|
{
|
||||||
|
std::string modelPath;
|
||||||
|
MODEL_TYPE modelType = YOLO_DETECT_V8;
|
||||||
|
std::vector<int> imgSize = { IMAGE_WIDTH, IMAGE_HEIGHT };
|
||||||
|
float rectConfidenceThreshold = 0.6;
|
||||||
|
float iouThreshold = 0.5;
|
||||||
|
int keyPointsNum = 2;//Note:kpt number for pose
|
||||||
|
bool cudaEnable = false;
|
||||||
|
int logSeverityLevel = 3;
|
||||||
|
int intraOpNumThreads = 1;
|
||||||
|
} DL_INIT_PARAM;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _DL_RESULT
|
||||||
|
{
|
||||||
|
int classId;
|
||||||
|
float confidence;
|
||||||
|
cv::Rect box;
|
||||||
|
std::vector<cv::Point2f> keyPoints;
|
||||||
|
} DL_RESULT;
|
||||||
|
|
||||||
|
|
||||||
|
class YOLO
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool InitParam(DL_INIT_PARAM& iParams) = 0;
|
||||||
|
|
||||||
|
virtual bool CreateSession(std::string model_path, std::string model_name) = 0;
|
||||||
|
virtual bool CreateSession(std::string model_path) = 0;
|
||||||
|
|
||||||
|
virtual char* RunSession(cv::Mat& in, cv::Mat& out, std::vector<std::pair<int, cv::Rect> >& results) = 0;
|
||||||
|
virtual char* RunSession(std::vector<cv::Mat>& vec_in, std::vector<cv::Mat>& vec_out, std::vector<std::vector<std::pair<int, cv::Rect> > >& vec_results) = 0;
|
||||||
|
|
||||||
|
virtual char* WarmUpSession() = 0;
|
||||||
|
virtual char* WarmUpSession(int shoot) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class YOLOManager {
|
||||||
|
public:
|
||||||
|
// 获取单例实例的方法
|
||||||
|
static YOLOManager& GetInstance() {
|
||||||
|
static YOLOManager instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取 YOLO 检测器实例
|
||||||
|
YOLO* GetDetector(uint8_t Num) const {
|
||||||
|
return detector[Num].get();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InitializeDetector(SysConf& sys_conf, uint8_t Num);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 私有构造函数,防止外部实例化
|
||||||
|
YOLOManager() = default;
|
||||||
|
|
||||||
|
// 禁用拷贝构造函数和赋值操作符
|
||||||
|
YOLOManager(const YOLOManager&) = delete;
|
||||||
|
YOLOManager& operator=(const YOLOManager&) = delete;
|
||||||
|
|
||||||
|
~YOLOManager() = default;
|
||||||
|
|
||||||
|
// 初始化检测器
|
||||||
|
#ifdef __DEBUG
|
||||||
|
DL_INIT_PARAM params[NumberOfSupportedCameras+1];
|
||||||
|
std::unique_ptr<YOLO> detector[NumberOfSupportedCameras+1];
|
||||||
|
#else
|
||||||
|
DL_INIT_PARAM params[NumberOfSupportedCameras];
|
||||||
|
std::unique_ptr<YOLO> detector[NumberOfSupportedCameras];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,442 @@
|
|||||||
|
#define _CRT_SECURE_NO_WARNINGS 1
|
||||||
|
#include "alg_jd_yolo8.h"
|
||||||
|
#include <regex>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#define benchmark
|
||||||
|
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||||
|
|
||||||
|
YOLO_V8::YOLO_V8() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
YOLO_V8::~YOLO_V8() {
|
||||||
|
delete session;
|
||||||
|
for (char* name : inputNodeNames) {
|
||||||
|
delete[] name;
|
||||||
|
}
|
||||||
|
for (char* name : outputNodeNames) {
|
||||||
|
delete[] name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_CUDA
|
||||||
|
namespace Ort
|
||||||
|
{
|
||||||
|
template<>
|
||||||
|
struct TypeToTensorType<half> { static constexpr ONNXTensorElementDataType type = ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT16; };
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
char* BlobFromImage(cv::Mat& iImg, T* iBlob) {
|
||||||
|
int channels = iImg.channels();
|
||||||
|
int imgHeight = iImg.rows;
|
||||||
|
int imgWidth = iImg.cols;
|
||||||
|
|
||||||
|
for (int c = 0; c < channels; c++) {
|
||||||
|
for (int h = 0; h < imgHeight; h++) {
|
||||||
|
for (int w = 0; w < imgWidth; w++) {
|
||||||
|
iBlob[c * imgWidth * imgHeight + h * imgWidth + w] = T(
|
||||||
|
(iImg.at<cv::Vec3b>(h, w)[c]) / 255.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
char* YOLO_V8::PreProcess(cv::Mat& iImg, std::vector<int> iImgSize, cv::Mat& oImg)
|
||||||
|
{
|
||||||
|
if (iImg.channels() == 3)
|
||||||
|
{
|
||||||
|
oImg = iImg.clone();
|
||||||
|
cv::cvtColor(oImg, oImg, cv::COLOR_BGR2RGB);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cv::cvtColor(iImg, oImg, cv::COLOR_GRAY2RGB);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (modelType)
|
||||||
|
{
|
||||||
|
case YOLO_DETECT_V8:
|
||||||
|
case YOLO_POSE:
|
||||||
|
case YOLO_DETECT_V8_HALF:
|
||||||
|
case YOLO_POSE_V8_HALF://LetterBox
|
||||||
|
{
|
||||||
|
if (iImg.cols >= iImg.rows)
|
||||||
|
{
|
||||||
|
resizeScales = iImg.cols / (float)iImgSize.at(0);
|
||||||
|
cv::resize(oImg, oImg, cv::Size(iImgSize.at(0), int(iImg.rows / resizeScales)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resizeScales = iImg.rows / (float)iImgSize.at(0);
|
||||||
|
cv::resize(oImg, oImg, cv::Size(int(iImg.cols / resizeScales), iImgSize.at(1)));
|
||||||
|
}
|
||||||
|
cv::Mat tempImg = cv::Mat::zeros(iImgSize.at(0), iImgSize.at(1), CV_8UC3);
|
||||||
|
oImg.copyTo(tempImg(cv::Rect(0, 0, oImg.cols, oImg.rows)));
|
||||||
|
oImg = tempImg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case YOLO_CLS://CenterCrop
|
||||||
|
{
|
||||||
|
int h = iImg.rows;
|
||||||
|
int w = iImg.cols;
|
||||||
|
int m = min(h, w);
|
||||||
|
int top = (h - m) / 2;
|
||||||
|
int left = (w - m) / 2;
|
||||||
|
cv::resize(oImg(cv::Rect(left, top, m, m)), oImg, cv::Size(iImgSize.at(0), iImgSize.at(1)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool YOLO_V8::InitParam(DL_INIT_PARAM& iParams)
|
||||||
|
{
|
||||||
|
// Initialize the parameters
|
||||||
|
rectConfidenceThreshold = iParams.rectConfidenceThreshold;
|
||||||
|
iouThreshold = iParams.iouThreshold;
|
||||||
|
imgSize = {640,640};
|
||||||
|
modelType = iParams.modelType;
|
||||||
|
cudaEnable = iParams.cudaEnable;
|
||||||
|
intraOpNumThreads = iParams.intraOpNumThreads;
|
||||||
|
logSeverityLevel = iParams.logSeverityLevel;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool YOLO_V8::CreateSession(std::string model_path, std::string model_name) {
|
||||||
|
char* Ret = RET_OK;
|
||||||
|
// std::regex pattern("[\u4e00-\u9fa5]");
|
||||||
|
// bool result = std::regex_search(model_path, pattern);
|
||||||
|
// if (result) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
model_path += "/jd.onnx";
|
||||||
|
try {
|
||||||
|
env = Ort::Env(ORT_LOGGING_LEVEL_WARNING, "Yolo");
|
||||||
|
Ort::SessionOptions sessionOption;
|
||||||
|
|
||||||
|
if (cudaEnable) {
|
||||||
|
OrtCUDAProviderOptions cudaOption;
|
||||||
|
cudaOption.device_id = 0;
|
||||||
|
sessionOption.AppendExecutionProvider_CUDA(cudaOption);
|
||||||
|
}
|
||||||
|
|
||||||
|
sessionOption.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_ALL);
|
||||||
|
sessionOption.SetIntraOpNumThreads(intraOpNumThreads);
|
||||||
|
sessionOption.SetLogSeverityLevel(logSeverityLevel);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
int ModelPathSize = MultiByteToWideChar(CP_UTF8, 0, model_path.c_str(),
|
||||||
|
static_cast<int>(model_path.length()), nullptr, 0);
|
||||||
|
std::unique_ptr<wchar_t[]> wide_cstr(new wchar_t[ModelPathSize + 1]);
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, model_path.c_str(),
|
||||||
|
static_cast<int>(model_path.length()), wide_cstr.get(), ModelPathSize);
|
||||||
|
wide_cstr[ModelPathSize] = L'\0';
|
||||||
|
const wchar_t* modelPath = wide_cstr.get();
|
||||||
|
#else
|
||||||
|
const char* modelPath = model_path.c_str();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
session = new Ort::Session(env, modelPath, sessionOption);
|
||||||
|
Ort::AllocatorWithDefaultOptions allocator;
|
||||||
|
|
||||||
|
// 获取输入节点
|
||||||
|
size_t inputNodesNum = session->GetInputCount();
|
||||||
|
for (size_t i = 0; i < inputNodesNum; i++) {
|
||||||
|
Ort::AllocatedStringPtr input_node_name = session->GetInputNameAllocated(i, allocator);
|
||||||
|
// 动态分配足够大的空间
|
||||||
|
size_t name_len = strlen(input_node_name.get()) + 1;
|
||||||
|
char* temp_buf = new char[name_len];
|
||||||
|
strcpy(temp_buf, input_node_name.get());
|
||||||
|
inputNodeNames.push_back(temp_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取输出节点
|
||||||
|
size_t OutputNodesNum = session->GetOutputCount();
|
||||||
|
for (size_t i = 0; i < OutputNodesNum; i++) {
|
||||||
|
Ort::AllocatedStringPtr output_node_name = session->GetOutputNameAllocated(i, allocator);
|
||||||
|
// 动态分配足够大的空间
|
||||||
|
size_t name_len = strlen(output_node_name.get()) + 1;
|
||||||
|
char* temp_buf = new char[name_len];
|
||||||
|
strcpy(temp_buf, output_node_name.get());
|
||||||
|
outputNodeNames.push_back(temp_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
options = Ort::RunOptions{ nullptr };
|
||||||
|
WarmUpSession();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (const std::exception& e) {
|
||||||
|
std::string result = "[YOLO_V8]:" + std::string(e.what());
|
||||||
|
char* merged = new char[result.length() + 1];
|
||||||
|
std::strcpy(merged, result.c_str());
|
||||||
|
std::cout << merged << std::endl;
|
||||||
|
delete[] merged;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool YOLO_V8::CreateSession(std::string model_path)
|
||||||
|
{
|
||||||
|
return CreateSession(model_path, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
//char* YOLO_V8::RunSession(cv::Mat& iImg, std::vector<DL_RESULT>& oResult) {
|
||||||
|
char* YOLO_V8::RunSession(cv::Mat& in, cv::Mat& out, std::vector<std::pair<int, cv::Rect> >& results){
|
||||||
|
std::vector<DL_RESULT> oResult;
|
||||||
|
out = in.clone();
|
||||||
|
|
||||||
|
#ifdef benchmark
|
||||||
|
clock_t starttime_1 = clock();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char* Ret = RET_OK;
|
||||||
|
cv::Mat processedImg;
|
||||||
|
PreProcess(in, imgSize, processedImg);
|
||||||
|
|
||||||
|
if (modelType < 4) {
|
||||||
|
std::unique_ptr<float[]> blob(new float[processedImg.total() * 3]);
|
||||||
|
BlobFromImage(processedImg, blob.get()); // 使用 .get() 获取原始指针
|
||||||
|
std::vector<int64_t> inputNodeDims = { 1, 3, imgSize.at(0), imgSize.at(1) };
|
||||||
|
TensorProcess(starttime_1, in, blob.get(), inputNodeDims, oResult);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#ifdef USE_CUDA
|
||||||
|
std::unique_ptr<half[]> blob(new half[processedImg.total() * 3]);
|
||||||
|
BlobFromImage(processedImg, blob.get()); // 使用 .get() 获取原始指针
|
||||||
|
std::vector<int64_t> inputNodeDims = { 1, 3, imgSize.at(0), imgSize.at(1) };
|
||||||
|
TensorProcess(starttime_1, in, blob.get(), inputNodeDims, oResult);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绘制检测结果
|
||||||
|
for (auto& re : oResult) {
|
||||||
|
cv::RNG rng(cv::getTickCount());
|
||||||
|
//cv::Scalar color(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
|
||||||
|
cv::Scalar color(0, 255, 0);
|
||||||
|
cv::rectangle(out, re.box, color, 3);
|
||||||
|
|
||||||
|
float confidence = floor(100 * re.confidence) / 100;
|
||||||
|
std::cout << std::fixed << std::setprecision(2);
|
||||||
|
std::string label = std::string("jd") + std::string(" ") +
|
||||||
|
std::to_string(confidence).substr(0, std::to_string(confidence).size() - 4);
|
||||||
|
|
||||||
|
cv::rectangle(
|
||||||
|
out,
|
||||||
|
cv::Point(re.box.x, re.box.y - 25),
|
||||||
|
cv::Point(re.box.x + label.length() * 15, re.box.y),
|
||||||
|
color,
|
||||||
|
cv::FILLED
|
||||||
|
);
|
||||||
|
|
||||||
|
cv::putText(
|
||||||
|
out,
|
||||||
|
label,
|
||||||
|
cv::Point(re.box.x, re.box.y - 5),
|
||||||
|
cv::FONT_HERSHEY_SIMPLEX,
|
||||||
|
0.75,
|
||||||
|
cv::Scalar(0, 0, 0),
|
||||||
|
2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!oResult.empty())
|
||||||
|
{
|
||||||
|
for(uint16_t index=0;index<oResult.size();index++)
|
||||||
|
{
|
||||||
|
results.push_back(std::make_pair(oResult[index].classId, oResult[index].box));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* YOLO_V8::RunSession(std::vector<cv::Mat>& vec_in, std::vector<cv::Mat>& vec_out, std::vector<std::vector<std::pair<int, cv::Rect> > >& vec_results){
|
||||||
|
std::vector<DL_RESULT> oResult;
|
||||||
|
|
||||||
|
return (char*)"RunSession Undefined";
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
char* YOLO_V8::TensorProcess(clock_t& starttime_1, cv::Mat& iImg, T* blob,
|
||||||
|
std::vector<int64_t>& inputNodeDims,
|
||||||
|
std::vector<DL_RESULT>& oResult) {
|
||||||
|
// 创建输入张量
|
||||||
|
Ort::Value inputTensor = Ort::Value::CreateTensor<T>(
|
||||||
|
Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU),
|
||||||
|
blob,
|
||||||
|
3 * imgSize.at(0) * imgSize.at(1),
|
||||||
|
inputNodeDims.data(), inputNodeDims.size());
|
||||||
|
|
||||||
|
#ifdef benchmark
|
||||||
|
clock_t starttime_2 = clock();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 运行推理
|
||||||
|
auto outputTensor = session->Run(options, inputNodeNames.data(), &inputTensor, 1,
|
||||||
|
outputNodeNames.data(), outputNodeNames.size());
|
||||||
|
|
||||||
|
#ifdef benchmark
|
||||||
|
clock_t starttime_3 = clock();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 检查输出是否有效
|
||||||
|
if (outputTensor.empty()) {
|
||||||
|
return (char*)"[YOLO_V8]: No output from model";
|
||||||
|
}
|
||||||
|
|
||||||
|
Ort::TypeInfo typeInfo = outputTensor.front().GetTypeInfo();
|
||||||
|
auto tensor_info = typeInfo.GetTensorTypeAndShapeInfo();
|
||||||
|
std::vector<int64_t> outputNodeDims = tensor_info.GetShape();
|
||||||
|
|
||||||
|
// 根据模型类型处理输出
|
||||||
|
switch (modelType) {
|
||||||
|
case YOLO_DETECT_V8:
|
||||||
|
case YOLO_DETECT_V8_HALF: {
|
||||||
|
// 检测模型的输出处理代码
|
||||||
|
int signalResultNum = outputNodeDims[1];//84
|
||||||
|
int strideNum = outputNodeDims[2];//8400
|
||||||
|
std::vector<int> class_ids;
|
||||||
|
std::vector<float> confidences;
|
||||||
|
std::vector<cv::Rect> boxes;
|
||||||
|
cv::Mat rawData;
|
||||||
|
|
||||||
|
if (modelType == YOLO_DETECT_V8) {
|
||||||
|
// FP32
|
||||||
|
rawData = cv::Mat(signalResultNum, strideNum, CV_32F, outputTensor.front().GetTensorMutableData<T>());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// FP16
|
||||||
|
rawData = cv::Mat(signalResultNum, strideNum, CV_16F, outputTensor.front().GetTensorMutableData<T>());
|
||||||
|
rawData.convertTo(rawData, CV_32F);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理检测结果...
|
||||||
|
rawData = rawData.t();
|
||||||
|
float* data = (float*)rawData.data;
|
||||||
|
|
||||||
|
for (int i = 0; i < strideNum; ++i) {
|
||||||
|
float* classesScores = data + 4;
|
||||||
|
cv::Mat scores(1, this->classes.size(), CV_32FC1, classesScores);
|
||||||
|
cv::Point class_id;
|
||||||
|
double maxClassScore;
|
||||||
|
cv::minMaxLoc(scores, 0, &maxClassScore, 0, &class_id);
|
||||||
|
if (maxClassScore > rectConfidenceThreshold) {
|
||||||
|
confidences.push_back(maxClassScore);
|
||||||
|
class_ids.push_back(class_id.x);
|
||||||
|
float x = data[0];
|
||||||
|
float y = data[1];
|
||||||
|
float w = data[2];
|
||||||
|
float h = data[3];
|
||||||
|
|
||||||
|
int left = int((x - 0.5 * w) * resizeScales);
|
||||||
|
int top = int((y - 0.5 * h) * resizeScales);
|
||||||
|
|
||||||
|
int width = int(w * resizeScales);
|
||||||
|
int height = int(h * resizeScales);
|
||||||
|
|
||||||
|
boxes.push_back(cv::Rect(left, top, width, height));
|
||||||
|
}
|
||||||
|
data += signalResultNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> nmsResult;
|
||||||
|
cv::dnn::NMSBoxes(boxes, confidences, rectConfidenceThreshold, iouThreshold, nmsResult);
|
||||||
|
for (int i = 0; i < nmsResult.size(); ++i) {
|
||||||
|
int idx = nmsResult[i];
|
||||||
|
DL_RESULT result;
|
||||||
|
result.classId = class_ids[idx];
|
||||||
|
result.confidence = confidences[idx];
|
||||||
|
result.box = boxes[idx];
|
||||||
|
oResult.push_back(result);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case YOLO_CLS:
|
||||||
|
case YOLO_CLS_HALF: {
|
||||||
|
// 分类模型的输出处理代码
|
||||||
|
cv::Mat rawData;
|
||||||
|
if (modelType == YOLO_CLS) {
|
||||||
|
// FP32
|
||||||
|
rawData = cv::Mat(1, this->classes.size(), CV_32F, outputTensor.front().GetTensorMutableData<T>());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// FP16
|
||||||
|
rawData = cv::Mat(1, this->classes.size(), CV_16F, outputTensor.front().GetTensorMutableData<T>());
|
||||||
|
rawData.convertTo(rawData, CV_32F);
|
||||||
|
}
|
||||||
|
|
||||||
|
float* data = (float*)rawData.data;
|
||||||
|
DL_RESULT result;
|
||||||
|
for (int i = 0; i < this->classes.size(); i++) {
|
||||||
|
result.classId = i;
|
||||||
|
result.confidence = data[i];
|
||||||
|
oResult.push_back(result);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
std::cout << "[YOLO_V8]: " << "Not support model type." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef benchmark
|
||||||
|
clock_t starttime_4 = clock();
|
||||||
|
double pre_process_time = (double)(starttime_2 - starttime_1) / CLOCKS_PER_SEC * 1000;
|
||||||
|
double process_time = (double)(starttime_3 - starttime_2) / CLOCKS_PER_SEC * 1000;
|
||||||
|
double post_process_time = (double)(starttime_4 - starttime_3) / CLOCKS_PER_SEC * 1000;
|
||||||
|
// 输出性能信息...
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return RET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
template char* YOLO_V8::TensorProcess<float>(clock_t&, cv::Mat&, float*, std::vector<int64_t>&, std::vector<DL_RESULT>&);
|
||||||
|
#ifdef USE_CUDA
|
||||||
|
template char* YOLO_V8::TensorProcess<half>(clock_t&, cv::Mat&, half*, std::vector<int64_t>&, std::vector<DL_RESULT>&);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
char* YOLO_V8::WarmUpSession() {
|
||||||
|
clock_t starttime_1 = clock();
|
||||||
|
cv::Mat iImg = cv::Mat(cv::Size(imgSize.at(0), imgSize.at(1)), CV_8UC3);
|
||||||
|
cv::Mat processedImg;
|
||||||
|
PreProcess(iImg, imgSize, processedImg);
|
||||||
|
|
||||||
|
if (modelType < 4) {
|
||||||
|
std::unique_ptr<float[]> blob(new float[processedImg.total() * 3]);
|
||||||
|
BlobFromImage(processedImg, blob.get());
|
||||||
|
std::vector<int64_t> inputNodeDims = { 1, 3, imgSize.at(0), imgSize.at(1) };
|
||||||
|
Ort::Value input_tensor = Ort::Value::CreateTensor<float>(
|
||||||
|
Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU),
|
||||||
|
blob.get(), 3 * imgSize.at(0) * imgSize.at(1),
|
||||||
|
inputNodeDims.data(), inputNodeDims.size());
|
||||||
|
auto output_tensors = session->Run(options, inputNodeNames.data(), &input_tensor, 1,
|
||||||
|
outputNodeNames.data(), outputNodeNames.size());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#ifdef USE_CUDA
|
||||||
|
std::unique_ptr<half[]> blob(new half[processedImg.total() * 3]);
|
||||||
|
BlobFromImage(processedImg, blob.get());
|
||||||
|
std::vector<int64_t> inputNodeDims = { 1, 3, imgSize.at(0), imgSize.at(1) };
|
||||||
|
Ort::Value input_tensor = Ort::Value::CreateTensor<half>(
|
||||||
|
Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU),
|
||||||
|
blob.get(), 3 * imgSize.at(0) * imgSize.at(1),
|
||||||
|
inputNodeDims.data(), inputNodeDims.size());
|
||||||
|
auto output_tensors = session->Run(options, inputNodeNames.data(), &input_tensor, 1,
|
||||||
|
outputNodeNames.data(), outputNodeNames.size());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return RET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* YOLO_V8::WarmUpSession(int shoot)
|
||||||
|
{
|
||||||
|
return (char*)"WarmUpSession Undefined";
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define RET_OK nullptr
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <direct.h>
|
||||||
|
#include <io.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include <onnxruntime_cxx_api.h>
|
||||||
|
#include "YOLOManager.h"
|
||||||
|
|
||||||
|
#ifdef USE_CUDA
|
||||||
|
#include <cuda_fp16.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class YOLO_V8 :public YOLO
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
YOLO_V8();
|
||||||
|
|
||||||
|
~YOLO_V8();
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool InitParam(DL_INIT_PARAM& iParams)override;
|
||||||
|
|
||||||
|
bool CreateSession(std::string model_path, std::string model_name)override;
|
||||||
|
bool CreateSession(std::string model_path)override;
|
||||||
|
|
||||||
|
char* RunSession(cv::Mat& in, cv::Mat& out, std::vector<std::pair<int, cv::Rect> >& results)override;
|
||||||
|
char* RunSession(std::vector<cv::Mat>& vec_in, std::vector<cv::Mat>& vec_out, std::vector<std::vector<std::pair<int, cv::Rect> > >& vec_results)override;
|
||||||
|
|
||||||
|
char* WarmUpSession()override;
|
||||||
|
char* WarmUpSession(int shoot)override;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
char* TensorProcess(clock_t& starttime_1, cv::Mat& iImg, T* blob,
|
||||||
|
std::vector<int64_t>& inputNodeDims,
|
||||||
|
std::vector<DL_RESULT>& oResult);
|
||||||
|
|
||||||
|
char* PreProcess(cv::Mat& iImg, std::vector<int> iImgSize, cv::Mat& oImg);
|
||||||
|
|
||||||
|
std::vector<std::string> classes{};
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ort::Env env;
|
||||||
|
Ort::Session* session;
|
||||||
|
bool cudaEnable;
|
||||||
|
Ort::RunOptions options;
|
||||||
|
//std::vector<const char*> inputNodeNames;
|
||||||
|
//std::vector<const char*> outputNodeNames;
|
||||||
|
int logSeverityLevel;
|
||||||
|
int intraOpNumThreads;
|
||||||
|
MODEL_TYPE modelType;
|
||||||
|
std::vector<int> imgSize;
|
||||||
|
float rectConfidenceThreshold;
|
||||||
|
float iouThreshold;
|
||||||
|
float resizeScales;//letterbox scale
|
||||||
|
std::vector<char*> inputNodeNames;
|
||||||
|
std::vector<char*> outputNodeNames;
|
||||||
|
};
|
||||||
|
|
@ -1,42 +0,0 @@
|
|||||||
#ifndef _CIGARETTE_JD_ng
|
|
||||||
#define _CIGARETTE_JD_ng
|
|
||||||
|
|
||||||
#include <opencv2/opencv.hpp>
|
|
||||||
#include <opencv2/dnn.hpp>
|
|
||||||
#include <opencv2/dnn/shape_utils.hpp>
|
|
||||||
#include <opencv2/imgproc.hpp>
|
|
||||||
#include <opencv2/highgui.hpp>
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
#include "common.h"
|
|
||||||
class AlgJd_ng
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool init_ng(QString model_path, QString model_name);
|
|
||||||
bool test_detect_ng();
|
|
||||||
bool test_detect_batcht_ng(int shoot);
|
|
||||||
int detect_ng(cv::Mat& in, cv::Mat &draw_frame, cv::Mat &out, std::vector<std::pair<int, cv::Rect>> &results);
|
|
||||||
int detect_ng(cv::Mat& in, cv::Mat &out, std::vector<std::pair<int, cv::Rect> > &results);
|
|
||||||
// Remove the bounding boxes with low confidence using non-maxima suppression
|
|
||||||
void post_process_ng(cv::Mat& frame, std::vector<cv::Mat>& outs, std::vector<std::pair<int, cv::Rect>> &results);
|
|
||||||
void CircleImagePro_ng(cv::Mat src, cv::Mat dst, std::vector<float> radius);
|
|
||||||
void detect_batch_ng(std::vector<cv::Mat>& vec_in, std::vector<cv::Mat> &vec_out, std::vector<std::vector<std::pair<int, cv::Rect> > > &vec_results);
|
|
||||||
void detect_batch_ng(std::vector<cv::Mat>& vec_in, std::vector<cv::Mat> &transits, std::vector<cv::Mat> &vec_out, std::vector<std::vector<std::pair<int, cv::Rect>>> &vec_results);
|
|
||||||
// Remove the bounding boxes with low confidence using non-maxima suppression
|
|
||||||
void post_process_batch_ng(std::vector<cv::Mat>& vec_frame, std::vector<cv::Mat>& outs, std::vector<std::vector<std::pair<int, cv::Rect>>> &vec_results);
|
|
||||||
void analyse_ng(cv::Mat vec_in, std::vector<std::pair<int, cv::Rect> > & vec_results);
|
|
||||||
// Get the names of the output layers
|
|
||||||
std::vector<cv::String> getOutputsNames_ng(const cv::dnn::Net& net);
|
|
||||||
// Draw the predicted bounding box
|
|
||||||
void drawPred_ng(int classId, float conf, int left, int top, int right, int bottom, cv::Mat& frame);
|
|
||||||
private:
|
|
||||||
cv::dnn::Net net_ng;
|
|
||||||
std::vector<std::string> classes_ng;
|
|
||||||
};
|
|
||||||
//jinhuan+
|
|
||||||
bool sort_rect_by_x_center_ng(cv::Rect r1, cv::Rect r2);
|
|
||||||
bool sort_rect_by_y_center_ng(cv::Rect r1, cv::Rect r2);
|
|
||||||
bool sort_rect_by_height_ng(cv::Rect r1, cv::Rect r2);
|
|
||||||
bool sort_rect_by_width_ng(cv::Rect r1, cv::Rect r2);
|
|
||||||
//jinhuan-
|
|
||||||
#endif //end of _CIGARETTE_JD
|
|
Loading…
Reference in New Issue