Merge pull request '优化热成像' (#12) from wangjiaqi23 into master
@ -1,14 +0,0 @@
|
||||
{
|
||||
"params": {
|
||||
"confidence_threshold": 0.5
|
||||
},
|
||||
"metrics": {
|
||||
"f1": 0.13793103448275862,
|
||||
"precision": 0.09900990099009901,
|
||||
"recall": 0.22727272727272727,
|
||||
"tp": 10,
|
||||
"fp": 91,
|
||||
"fn": 34
|
||||
},
|
||||
"note": "由 auto_tune.py 自动优化生成,需手动更新到 cpp/include/thermal_types.h"
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
# generated from CMake
|
||||
@ -1,3 +1,4 @@
|
||||
D:/29578/Documents/Study/computer/S_E/软件体系结构与设计/软件开发/热成像识别/cpp/build/CMakeFiles/onnxruntime_imp_lib.dir
|
||||
D:/29578/Documents/Study/computer/S_E/软件体系结构与设计/软件开发/热成像识别/cpp/build/CMakeFiles/thermal_detector.dir
|
||||
D:/29578/Documents/Study/computer/S_E/软件体系结构与设计/软件开发/热成像识别/cpp/build/CMakeFiles/ALL_BUILD.dir
|
||||
D:/29578/Documents/Study/computer/S_E/软件体系结构与设计/软件开发/热成像识别/cpp/build/CMakeFiles/ZERO_CHECK.dir
|
||||
|
||||
@ -0,0 +1 @@
|
||||
# generated from CMake
|
||||
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="17.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="D:\29578\Documents\Study\computer\S_E\软件体系结构与设计\软件开发\热成像识别\cpp\build\CMakeFiles\e9bd87dd49c8a00a589935b380b13b97\onnxruntime.lib.rule">
|
||||
<Filter>CMake Rules</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="D:\29578\Documents\Study\computer\S_E\软件体系结构与设计\软件开发\热成像识别\cpp\build\CMakeFiles\56e5eca5e8f7b67eb6dc57ed2871d760\onnxruntime_imp_lib.rule">
|
||||
<Filter>CMake Rules</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="D:\29578\Documents\Study\computer\S_E\软件体系结构与设计\软件开发\热成像识别\cpp\CMakeLists.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="D:\29578\Documents\Study\computer\S_E\软件体系结构与设计\软件开发\热成像识别\cpp\build\CMakeFiles\onnxruntime_imp_lib" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="CMake Rules">
|
||||
<UniqueIdentifier>{531032C3-567B-392F-8E3A-E279D9FF267E}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -1,3 +1,4 @@
|
||||
D:\29578\Documents\Study\computer\S_E\软件体系结构与设计\软件开发\热成像识别\cpp\src\main.cpp;D:\29578\Documents\Study\computer\S_E\软件体系结构与设计\软件开发\热成像识别\cpp\build\thermal_detector.dir\Release\main.obj
|
||||
D:\29578\Documents\Study\computer\S_E\软件体系结构与设计\软件开发\热成像识别\cpp\src\thermal_preprocessor.cpp;D:\29578\Documents\Study\computer\S_E\软件体系结构与设计\软件开发\热成像识别\cpp\build\thermal_detector.dir\Release\thermal_preprocessor.obj
|
||||
D:\29578\Documents\Study\computer\S_E\软件体系结构与设计\软件开发\热成像识别\cpp\src\thermal_detector.cpp;D:\29578\Documents\Study\computer\S_E\软件体系结构与设计\软件开发\热成像识别\cpp\build\thermal_detector.dir\Release\thermal_detector.obj
|
||||
D:\29578\Documents\Study\computer\S_E\软件体系结构与设计\软件开发\热成像识别\cpp\src\yolo_detector.cpp;D:\29578\Documents\Study\computer\S_E\软件体系结构与设计\软件开发\热成像识别\cpp\build\thermal_detector.dir\Release\yolo_detector.obj
|
||||
|
||||
@ -1 +1 @@
|
||||
^D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\BUILD\THERMAL_DETECTOR.DIR\RELEASE\MAIN.OBJ|D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\BUILD\THERMAL_DETECTOR.DIR\RELEASE\THERMAL_DETECTOR.OBJ|D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\BUILD\THERMAL_DETECTOR.DIR\RELEASE\THERMAL_PREPROCESSOR.OBJ
|
||||
^D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\BUILD\THERMAL_DETECTOR.DIR\RELEASE\MAIN.OBJ|D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\BUILD\THERMAL_DETECTOR.DIR\RELEASE\THERMAL_DETECTOR.OBJ|D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\BUILD\THERMAL_DETECTOR.DIR\RELEASE\THERMAL_PREPROCESSOR.OBJ|D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\BUILD\THERMAL_DETECTOR.DIR\RELEASE\YOLO_DETECTOR.OBJ
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
^D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\BUILD\CMAKEFILES\E9BD87DD49C8A00A589935B380B13B97\ONNXRUNTIME.LIB.RULE
|
||||
setlocal
|
||||
lib.exe /def:D:/29578/Documents/Study/computer/S_E/软件体系结构与设计/软件开发/热成像识别/cpp/third_party/onnxruntime/lib/onnxruntime.def /out:D:/29578/Documents/Study/computer/S_E/软件体系结构与设计/软件开发/热成像识别/cpp/build/onnxruntime.lib /machine:x64
|
||||
if %errorlevel% neq 0 goto :cmEnd
|
||||
:cmEnd
|
||||
endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
|
||||
:cmErrorLevel
|
||||
exit /b %1
|
||||
:cmDone
|
||||
if %errorlevel% neq 0 goto :VCEnd
|
||||
^D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\BUILD\CMAKEFILES\56E5ECA5E8F7B67EB6DC57ED2871D760\ONNXRUNTIME_IMP_LIB.RULE
|
||||
setlocal
|
||||
:cmEnd
|
||||
endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
|
||||
:cmErrorLevel
|
||||
exit /b %1
|
||||
:cmDone
|
||||
if %errorlevel% neq 0 goto :VCEnd
|
||||
^D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\CMAKELISTS.TXT
|
||||
setlocal
|
||||
D:\cmake\bin\cmake.exe -SD:/29578/Documents/Study/computer/S_E/软件体系结构与设计/软件开发/热成像识别/cpp -BD:/29578/Documents/Study/computer/S_E/软件体系结构与设计/软件开发/热成像识别/cpp/build --check-stamp-file D:/29578/Documents/Study/computer/S_E/软件体系结构与设计/软件开发/热成像识别/cpp/build/CMakeFiles/generate.stamp
|
||||
if %errorlevel% neq 0 goto :cmEnd
|
||||
:cmEnd
|
||||
endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
|
||||
:cmErrorLevel
|
||||
exit /b %1
|
||||
:cmDone
|
||||
if %errorlevel% neq 0 goto :VCEnd
|
||||
@ -0,0 +1,37 @@
|
||||
^D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\BUILD\CMAKEFILES\E9BD87DD49C8A00A589935B380B13B97\ONNXRUNTIME.LIB.RULE
|
||||
D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\THIRD_PARTY\ONNXRUNTIME\LIB\ONNXRUNTIME.DEF
|
||||
^D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\BUILD\CMAKEFILES\56E5ECA5E8F7B67EB6DC57ED2871D760\ONNXRUNTIME_IMP_LIB.RULE
|
||||
D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\BUILD\ONNXRUNTIME.LIB
|
||||
^D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\CMAKELISTS.TXT
|
||||
C:\USERS\29578\.CONDA\ENVS\OPENCV-BUILD\LIBRARY\CMAKE\OPENCVCONFIG-VERSION.CMAKE
|
||||
C:\USERS\29578\.CONDA\ENVS\OPENCV-BUILD\LIBRARY\CMAKE\OPENCVCONFIG.CMAKE
|
||||
C:\USERS\29578\.CONDA\ENVS\OPENCV-BUILD\LIBRARY\CMAKE\X64\VC17\LIB\OPENCVCONFIG.CMAKE
|
||||
C:\USERS\29578\.CONDA\ENVS\OPENCV-BUILD\LIBRARY\CMAKE\X64\VC17\LIB\OPENCVMODULES-RELEASE.CMAKE
|
||||
C:\USERS\29578\.CONDA\ENVS\OPENCV-BUILD\LIBRARY\CMAKE\X64\VC17\LIB\OPENCVMODULES.CMAKE
|
||||
D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\BUILD\CMAKEFILES\4.3.2\CMAKECXXCOMPILER.CMAKE
|
||||
D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\BUILD\CMAKEFILES\4.3.2\CMAKERCCOMPILER.CMAKE
|
||||
D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\BUILD\CMAKEFILES\4.3.2\CMAKESYSTEM.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\CMAKECXXINFORMATION.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\CMAKECOMMONLANGUAGEINCLUDE.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\CMAKEGENERICSYSTEM.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\CMAKEINITIALIZECONFIGS.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\CMAKELANGUAGEINFORMATION.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\CMAKERCINFORMATION.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\CMAKESYSTEMSPECIFICINFORMATION.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\CMAKESYSTEMSPECIFICINITIALIZE.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\COMPILER\CMAKECOMMONCOMPILERMACROS.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\COMPILER\MSVC-CXX.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\COMPILER\MSVC.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\FINDPACKAGEHANDLESTANDARDARGS.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\FINDPACKAGEMESSAGE.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\INTERNAL\CMAKECXXLINKERINFORMATION.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\INTERNAL\CMAKECOMMONLINKERINFORMATION.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\LINKER\MSVC-CXX.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\LINKER\MSVC.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\PLATFORM\LINKER\WINDOWS-MSVC-CXX.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\PLATFORM\LINKER\WINDOWS-MSVC.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\PLATFORM\WINDOWS-INITIALIZE.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\PLATFORM\WINDOWS-MSVC-CXX.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\PLATFORM\WINDOWS-MSVC.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\PLATFORM\WINDOWS.CMAKE
|
||||
D:\CMAKE\SHARE\CMAKE-4.3\MODULES\PLATFORM\WINDOWSPATHS.CMAKE
|
||||
@ -0,0 +1,6 @@
|
||||
^D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\BUILD\CMAKEFILES\E9BD87DD49C8A00A589935B380B13B97\ONNXRUNTIME.LIB.RULE
|
||||
D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\BUILD\ONNXRUNTIME.LIB
|
||||
^D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\BUILD\CMAKEFILES\56E5ECA5E8F7B67EB6DC57ED2871D760\ONNXRUNTIME_IMP_LIB.RULE
|
||||
D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\BUILD\CMAKEFILES\ONNXRUNTIME_IMP_LIB
|
||||
^D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\CMAKELISTS.TXT
|
||||
D:\29578\DOCUMENTS\STUDY\COMPUTER\S_E\软件体系结构与设计\软件开发\热成像识别\CPP\BUILD\CMAKEFILES\GENERATE.STAMP
|
||||
@ -0,0 +1,2 @@
|
||||
PlatformToolSet=v143:VCToolArchitecture=Native64Bit:VCToolsVersion=14.43.34808:TargetPlatformVersion=10.0.22621.0:
|
||||
Release|x64|D:\29578\Documents\Study\computer\S_E\软件体系结构与设计\软件开发\热成像识别\cpp\build\|
|
||||
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project>
|
||||
<ProjectOutputs>
|
||||
<ProjectOutput>
|
||||
<FullPath>D:\29578\Documents\Study\computer\S_E\软件体系结构与设计\软件开发\热成像识别\cpp\build\x64\Release\ZERO_CHECK</FullPath>
|
||||
</ProjectOutput>
|
||||
<ProjectOutput>
|
||||
<FullPath>D:\29578\Documents\Study\computer\S_E\软件体系结构与设计\软件开发\热成像识别\cpp\build\x64\Release\onnxruntime_imp_lib</FullPath>
|
||||
</ProjectOutput>
|
||||
</ProjectOutputs>
|
||||
<ContentFiles />
|
||||
<SatelliteDlls />
|
||||
<NonRecipeFileRefs />
|
||||
</Project>
|
||||
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "thermal_types.h"
|
||||
#include <opencv2/core.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct YoloConfig {
|
||||
std::string model_path;
|
||||
int input_size = 640;
|
||||
float conf_threshold = 0.25f;
|
||||
float nms_threshold = 0.45f;
|
||||
int max_detections = 100;
|
||||
int intra_threads = 1;
|
||||
};
|
||||
|
||||
class YoloDetector {
|
||||
public:
|
||||
explicit YoloDetector(const YoloConfig& config);
|
||||
~YoloDetector();
|
||||
|
||||
YoloDetector(const YoloDetector&) = delete;
|
||||
YoloDetector& operator=(const YoloDetector&) = delete;
|
||||
YoloDetector(YoloDetector&&) noexcept;
|
||||
YoloDetector& operator=(YoloDetector&&) noexcept;
|
||||
|
||||
std::vector<DetectionResult> detect(const cv::Mat& image);
|
||||
bool is_loaded() const noexcept;
|
||||
|
||||
private:
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> impl_;
|
||||
};
|
||||
@ -0,0 +1,255 @@
|
||||
#include "yolo_detector.h"
|
||||
#include <onnxruntime_cxx_api.h>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <numeric>
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
struct YoloDetector::Impl {
|
||||
YoloConfig config;
|
||||
Ort::Env env;
|
||||
std::unique_ptr<Ort::Session> session;
|
||||
std::unique_ptr<Ort::SessionOptions> session_options;
|
||||
bool loaded = false;
|
||||
int num_classes = 0;
|
||||
int input_size = 640;
|
||||
|
||||
explicit Impl(const YoloConfig& cfg)
|
||||
: config(cfg), env(ORT_LOGGING_LEVEL_WARNING, "thermal-yolo"),
|
||||
input_size(cfg.input_size) {
|
||||
session_options = std::make_unique<Ort::SessionOptions>();
|
||||
session_options->SetIntraOpNumThreads(config.intra_threads);
|
||||
session_options->SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED);
|
||||
}
|
||||
|
||||
bool load_model(const std::string& path) {
|
||||
std::ifstream check(path, std::ios::binary);
|
||||
if (!check) {
|
||||
std::cerr << "[YOLO] Model file not found: " << path << std::endl;
|
||||
return false;
|
||||
}
|
||||
check.close();
|
||||
|
||||
try {
|
||||
#ifdef _WIN32
|
||||
int wlen = MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, nullptr, 0);
|
||||
std::wstring wpath;
|
||||
if (wlen > 0) {
|
||||
wpath.resize(static_cast<std::size_t>(wlen));
|
||||
MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, &wpath[0], wlen);
|
||||
}
|
||||
session = std::make_unique<Ort::Session>(env, wpath.c_str(), *session_options);
|
||||
#else
|
||||
session = std::make_unique<Ort::Session>(env, path.c_str(), *session_options);
|
||||
#endif
|
||||
} catch (const Ort::Exception& e) {
|
||||
std::cerr << "[YOLO] ONNX Runtime load failed: " << e.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 从输出形状推断类别数
|
||||
auto output_count = session->GetOutputCount();
|
||||
if (output_count > 0) {
|
||||
auto type_info = session->GetOutputTypeInfo(0);
|
||||
auto tensor_info = type_info.GetTensorTypeAndShapeInfo();
|
||||
auto shape = tensor_info.GetShape();
|
||||
// YOLOv8 输出: [1, 4+nc, 8400]
|
||||
if (shape.size() == 3 && shape[1] > 4) {
|
||||
num_classes = static_cast<int>(shape[1]) - 4;
|
||||
}
|
||||
}
|
||||
|
||||
loaded = session != nullptr;
|
||||
return loaded;
|
||||
}
|
||||
|
||||
std::vector<float> preprocess(const cv::Mat& image, int& orig_w, int& orig_h) {
|
||||
cv::Mat bgr;
|
||||
if (image.channels() == 1)
|
||||
cv::cvtColor(image, bgr, cv::COLOR_GRAY2BGR);
|
||||
else
|
||||
bgr = image;
|
||||
|
||||
orig_w = bgr.cols;
|
||||
orig_h = bgr.rows;
|
||||
|
||||
cv::Mat resized;
|
||||
cv::resize(bgr, resized, cv::Size(input_size, input_size));
|
||||
|
||||
cv::Mat rgb;
|
||||
cv::cvtColor(resized, rgb, cv::COLOR_BGR2RGB);
|
||||
|
||||
cv::Mat f32;
|
||||
rgb.convertTo(f32, CV_32F, 1.0 / 255.0);
|
||||
|
||||
std::vector<cv::Mat> channels(3);
|
||||
cv::split(f32, channels);
|
||||
|
||||
int channel_size = input_size * input_size;
|
||||
std::vector<float> input_data(3 * channel_size);
|
||||
for (int c = 0; c < 3; c++) {
|
||||
std::memcpy(input_data.data() + c * channel_size,
|
||||
channels[c].data, channel_size * sizeof(float));
|
||||
}
|
||||
return input_data;
|
||||
}
|
||||
|
||||
struct RawDet {
|
||||
float cx, cy, w, h;
|
||||
int class_id;
|
||||
float score;
|
||||
};
|
||||
|
||||
static double compute_iou(const cv::Rect& a, const cv::Rect& b) {
|
||||
int ix1 = std::max(a.x, b.x);
|
||||
int iy1 = std::max(a.y, b.y);
|
||||
int ix2 = std::min(a.x + a.width, b.x + b.width);
|
||||
int iy2 = std::min(a.y + a.height, b.y + b.height);
|
||||
int inter = std::max(0, ix2 - ix1) * std::max(0, iy2 - iy1);
|
||||
int area_a = a.width * a.height;
|
||||
int area_b = b.width * b.height;
|
||||
int union_area = area_a + area_b - inter;
|
||||
return static_cast<double>(inter) / std::max(union_area, 1);
|
||||
}
|
||||
|
||||
ThreatType map_class(int class_id) {
|
||||
if (num_classes == 80) {
|
||||
return (class_id == 0) ? ThreatType::PERSON : ThreatType::PERSON;
|
||||
}
|
||||
if (class_id == 0) return ThreatType::PERSON;
|
||||
if (class_id == 1) return ThreatType::ANOMALY_HOTSPOT;
|
||||
return ThreatType::PERSON;
|
||||
}
|
||||
|
||||
std::vector<DetectionResult> postprocess(
|
||||
std::vector<Ort::Value>& outputs,
|
||||
int orig_w, int orig_h)
|
||||
{
|
||||
if (outputs.empty()) return {};
|
||||
|
||||
float* data = outputs[0].GetTensorMutableData<float>();
|
||||
auto shape = outputs[0].GetTensorTypeAndShapeInfo().GetShape();
|
||||
int nc = static_cast<int>(shape[1]) - 4;
|
||||
int num_preds = static_cast<int>(shape[2]);
|
||||
|
||||
std::vector<RawDet> raw;
|
||||
for (int i = 0; i < num_preds; i++) {
|
||||
float best_score = 0;
|
||||
int best_class = 0;
|
||||
for (int c = 0; c < nc; c++) {
|
||||
float s = data[(4 + c) * num_preds + i];
|
||||
if (s > best_score) { best_score = s; best_class = c; }
|
||||
}
|
||||
if (best_score < config.conf_threshold) continue;
|
||||
|
||||
raw.push_back({
|
||||
data[0 * num_preds + i],
|
||||
data[1 * num_preds + i],
|
||||
data[2 * num_preds + i],
|
||||
data[3 * num_preds + i],
|
||||
best_class, best_score
|
||||
});
|
||||
}
|
||||
|
||||
// NMS
|
||||
std::sort(raw.begin(), raw.end(),
|
||||
[](const RawDet& a, const RawDet& b) { return a.score > b.score; });
|
||||
|
||||
float scale_x = static_cast<float>(orig_w) / input_size;
|
||||
float scale_y = static_cast<float>(orig_h) / input_size;
|
||||
|
||||
// 转换为 cv::Rect 并做 NMS
|
||||
std::vector<std::pair<RawDet, cv::Rect>> boxed;
|
||||
for (const auto& d : raw) {
|
||||
int x = static_cast<int>((d.cx - d.w / 2) * scale_x);
|
||||
int y = static_cast<int>((d.cy - d.h / 2) * scale_y);
|
||||
int w = static_cast<int>(d.w * scale_x);
|
||||
int h = static_cast<int>(d.h * scale_y);
|
||||
boxed.push_back({d, cv::Rect(x, y, w, h)});
|
||||
}
|
||||
|
||||
std::vector<int> keep;
|
||||
for (int i = 0; i < static_cast<int>(boxed.size()); i++) {
|
||||
bool suppressed = false;
|
||||
for (int j : keep) {
|
||||
if (compute_iou(boxed[i].second, boxed[j].second) > config.nms_threshold) {
|
||||
suppressed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!suppressed) keep.push_back(i);
|
||||
if (static_cast<int>(keep.size()) >= config.max_detections) break;
|
||||
}
|
||||
|
||||
std::vector<DetectionResult> results;
|
||||
for (int idx : keep) {
|
||||
const auto& det = boxed[idx].first;
|
||||
const auto& box = boxed[idx].second;
|
||||
results.push_back({
|
||||
map_class(det.class_id),
|
||||
static_cast<double>(det.score),
|
||||
box,
|
||||
cv::Point2d(box.x + box.width / 2.0, box.y + box.height / 2.0),
|
||||
0, 0,
|
||||
box.width * box.height,
|
||||
static_cast<double>(std::max(box.width, box.height)) /
|
||||
std::max(std::min(box.width, box.height), 1)
|
||||
});
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
std::vector<DetectionResult> detect(const cv::Mat& image) {
|
||||
if (!loaded) return {};
|
||||
|
||||
int orig_w, orig_h;
|
||||
auto input_data = preprocess(image, orig_w, orig_h);
|
||||
|
||||
auto memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
|
||||
std::vector<int64_t> input_shape = {1, 3, input_size, input_size};
|
||||
Ort::Value input_tensor = Ort::Value::CreateTensor<float>(
|
||||
memory_info, input_data.data(), input_data.size(),
|
||||
input_shape.data(), input_shape.size());
|
||||
|
||||
// 动态获取 I/O 名称
|
||||
auto allocator = Ort::AllocatorWithDefaultOptions();
|
||||
auto input_name = session->GetInputNameAllocated(0, allocator);
|
||||
auto output_name = session->GetOutputNameAllocated(0, allocator);
|
||||
const char* input_names[] = {input_name.get()};
|
||||
const char* output_names[] = {output_name.get()};
|
||||
|
||||
auto outputs = session->Run(
|
||||
Ort::RunOptions{nullptr},
|
||||
input_names, &input_tensor, 1,
|
||||
output_names, 1);
|
||||
|
||||
return postprocess(outputs, orig_w, orig_h);
|
||||
}
|
||||
};
|
||||
|
||||
YoloDetector::YoloDetector(const YoloConfig& config)
|
||||
: impl_(std::make_unique<Impl>(config)) {
|
||||
if (!config.model_path.empty()) {
|
||||
impl_->load_model(config.model_path);
|
||||
}
|
||||
}
|
||||
|
||||
YoloDetector::~YoloDetector() = default;
|
||||
YoloDetector::YoloDetector(YoloDetector&&) noexcept = default;
|
||||
YoloDetector& YoloDetector::operator=(YoloDetector&&) noexcept = default;
|
||||
|
||||
std::vector<DetectionResult> YoloDetector::detect(const cv::Mat& image) {
|
||||
return impl_->detect(image);
|
||||
}
|
||||
|
||||
bool YoloDetector::is_loaded() const noexcept {
|
||||
return impl_->loaded;
|
||||
}
|
||||
@ -0,0 +1,535 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
|
||||
namespace onnxruntime_float16 {
|
||||
|
||||
namespace detail {
|
||||
|
||||
enum class endian {
|
||||
#if defined(_WIN32)
|
||||
little = 0,
|
||||
big = 1,
|
||||
native = little,
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
little = __ORDER_LITTLE_ENDIAN__,
|
||||
big = __ORDER_BIG_ENDIAN__,
|
||||
native = __BYTE_ORDER__,
|
||||
#else
|
||||
#error onnxruntime_float16::detail::endian is not implemented in this environment.
|
||||
#endif
|
||||
};
|
||||
|
||||
static_assert(
|
||||
endian::native == endian::little || endian::native == endian::big,
|
||||
"Only little-endian or big-endian native byte orders are supported.");
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// <summary>
|
||||
/// Shared implementation between public and internal classes. CRTP pattern.
|
||||
/// </summary>
|
||||
template <class Derived>
|
||||
struct Float16Impl {
|
||||
protected:
|
||||
/// <summary>
|
||||
/// Converts from float to uint16_t float16 representation
|
||||
/// </summary>
|
||||
/// <param name="v"></param>
|
||||
/// <returns></returns>
|
||||
constexpr static uint16_t ToUint16Impl(float v) noexcept;
|
||||
|
||||
/// <summary>
|
||||
/// Converts float16 to float
|
||||
/// </summary>
|
||||
/// <returns>float representation of float16 value</returns>
|
||||
float ToFloatImpl() const noexcept;
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance that represents absolute value.
|
||||
/// </summary>
|
||||
/// <returns>Absolute value</returns>
|
||||
uint16_t AbsImpl() const noexcept {
|
||||
return static_cast<uint16_t>(val & ~kSignMask);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance with the sign flipped.
|
||||
/// </summary>
|
||||
/// <returns>Flipped sign instance</returns>
|
||||
uint16_t NegateImpl() const noexcept {
|
||||
return IsNaN() ? val : static_cast<uint16_t>(val ^ kSignMask);
|
||||
}
|
||||
|
||||
public:
|
||||
// uint16_t special values
|
||||
static constexpr uint16_t kSignMask = 0x8000U;
|
||||
static constexpr uint16_t kBiasedExponentMask = 0x7C00U;
|
||||
static constexpr uint16_t kPositiveInfinityBits = 0x7C00U;
|
||||
static constexpr uint16_t kNegativeInfinityBits = 0xFC00U;
|
||||
static constexpr uint16_t kPositiveQNaNBits = 0x7E00U;
|
||||
static constexpr uint16_t kNegativeQNaNBits = 0xFE00U;
|
||||
static constexpr uint16_t kMaxValueBits = 0x7BFFU; // Largest normal number
|
||||
static constexpr uint16_t kOneBits = 0x3C00U;
|
||||
static constexpr uint16_t kMinusOneBits = 0xBC00U;
|
||||
|
||||
uint16_t val{0};
|
||||
|
||||
Float16Impl() = default;
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the value is negative
|
||||
/// </summary>
|
||||
/// <returns>true if negative</returns>
|
||||
bool IsNegative() const noexcept {
|
||||
return static_cast<int16_t>(val) < 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if the value is NaN
|
||||
/// </summary>
|
||||
/// <returns>true if NaN</returns>
|
||||
bool IsNaN() const noexcept {
|
||||
return AbsImpl() > kPositiveInfinityBits;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if the value is finite
|
||||
/// </summary>
|
||||
/// <returns>true if finite</returns>
|
||||
bool IsFinite() const noexcept {
|
||||
return AbsImpl() < kPositiveInfinityBits;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if the value represents positive infinity.
|
||||
/// </summary>
|
||||
/// <returns>true if positive infinity</returns>
|
||||
bool IsPositiveInfinity() const noexcept {
|
||||
return val == kPositiveInfinityBits;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if the value represents negative infinity
|
||||
/// </summary>
|
||||
/// <returns>true if negative infinity</returns>
|
||||
bool IsNegativeInfinity() const noexcept {
|
||||
return val == kNegativeInfinityBits;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if the value is either positive or negative infinity.
|
||||
/// </summary>
|
||||
/// <returns>True if absolute value is infinity</returns>
|
||||
bool IsInfinity() const noexcept {
|
||||
return AbsImpl() == kPositiveInfinityBits;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if the value is NaN or zero. Useful for comparisons.
|
||||
/// </summary>
|
||||
/// <returns>True if NaN or zero.</returns>
|
||||
bool IsNaNOrZero() const noexcept {
|
||||
auto abs = AbsImpl();
|
||||
return (abs == 0 || abs > kPositiveInfinityBits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if the value is normal (not zero, subnormal, infinite, or NaN).
|
||||
/// </summary>
|
||||
/// <returns>True if so</returns>
|
||||
bool IsNormal() const noexcept {
|
||||
auto abs = AbsImpl();
|
||||
return (abs < kPositiveInfinityBits) // is finite
|
||||
&& (abs != 0) // is not zero
|
||||
&& ((abs & kBiasedExponentMask) != 0); // is not subnormal (has a non-zero exponent)
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if the value is subnormal (denormal).
|
||||
/// </summary>
|
||||
/// <returns>True if so</returns>
|
||||
bool IsSubnormal() const noexcept {
|
||||
auto abs = AbsImpl();
|
||||
return (abs < kPositiveInfinityBits) // is finite
|
||||
&& (abs != 0) // is not zero
|
||||
&& ((abs & kBiasedExponentMask) == 0); // is subnormal (has a zero exponent)
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance that represents absolute value.
|
||||
/// </summary>
|
||||
/// <returns>Absolute value</returns>
|
||||
Derived Abs() const noexcept { return Derived::FromBits(AbsImpl()); }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance with the sign flipped.
|
||||
/// </summary>
|
||||
/// <returns>Flipped sign instance</returns>
|
||||
Derived Negate() const noexcept { return Derived::FromBits(NegateImpl()); }
|
||||
|
||||
/// <summary>
|
||||
/// IEEE defines that positive and negative zero are equal, this gives us a quick equality check
|
||||
/// for two values by or'ing the private bits together and stripping the sign. They are both zero,
|
||||
/// and therefore equivalent, if the resulting value is still zero.
|
||||
/// </summary>
|
||||
/// <param name="lhs">first value</param>
|
||||
/// <param name="rhs">second value</param>
|
||||
/// <returns>True if both arguments represent zero</returns>
|
||||
static bool AreZero(const Float16Impl& lhs, const Float16Impl& rhs) noexcept {
|
||||
return static_cast<uint16_t>((lhs.val | rhs.val) & ~kSignMask) == 0;
|
||||
}
|
||||
|
||||
bool operator==(const Float16Impl& rhs) const noexcept {
|
||||
if (IsNaN() || rhs.IsNaN()) {
|
||||
// IEEE defines that NaN is not equal to anything, including itself.
|
||||
return false;
|
||||
}
|
||||
return val == rhs.val;
|
||||
}
|
||||
|
||||
bool operator!=(const Float16Impl& rhs) const noexcept { return !(*this == rhs); }
|
||||
|
||||
bool operator<(const Float16Impl& rhs) const noexcept {
|
||||
if (IsNaN() || rhs.IsNaN()) {
|
||||
// IEEE defines that NaN is unordered with respect to everything, including itself.
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool left_is_negative = IsNegative();
|
||||
if (left_is_negative != rhs.IsNegative()) {
|
||||
// When the signs of left and right differ, we know that left is less than right if it is
|
||||
// the negative value. The exception to this is if both values are zero, in which case IEEE
|
||||
// says they should be equal, even if the signs differ.
|
||||
return left_is_negative && !AreZero(*this, rhs);
|
||||
}
|
||||
return (val != rhs.val) && ((val < rhs.val) ^ left_is_negative);
|
||||
}
|
||||
};
|
||||
|
||||
// The following Float16_t conversions are based on the code from
|
||||
// Eigen library.
|
||||
|
||||
// The conversion routines are Copyright (c) Fabian Giesen, 2016.
|
||||
// The original license follows:
|
||||
//
|
||||
// Copyright (c) Fabian Giesen, 2016
|
||||
// All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted.
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
namespace detail {
|
||||
union float32_bits {
|
||||
unsigned int u;
|
||||
float f;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
template <class Derived>
|
||||
inline constexpr uint16_t Float16Impl<Derived>::ToUint16Impl(float v) noexcept {
|
||||
detail::float32_bits f{};
|
||||
f.f = v;
|
||||
|
||||
constexpr detail::float32_bits f32infty = {255 << 23};
|
||||
constexpr detail::float32_bits f16max = {(127 + 16) << 23};
|
||||
constexpr detail::float32_bits denorm_magic = {((127 - 15) + (23 - 10) + 1) << 23};
|
||||
constexpr unsigned int sign_mask = 0x80000000u;
|
||||
uint16_t val = static_cast<uint16_t>(0x0u);
|
||||
|
||||
unsigned int sign = f.u & sign_mask;
|
||||
f.u ^= sign;
|
||||
|
||||
// NOTE all the integer compares in this function can be safely
|
||||
// compiled into signed compares since all operands are below
|
||||
// 0x80000000. Important if you want fast straight SSE2 code
|
||||
// (since there's no unsigned PCMPGTD).
|
||||
|
||||
if (f.u >= f16max.u) { // result is Inf or NaN (all exponent bits set)
|
||||
val = (f.u > f32infty.u) ? 0x7e00 : 0x7c00; // NaN->qNaN and Inf->Inf
|
||||
} else { // (De)normalized number or zero
|
||||
if (f.u < (113 << 23)) { // resulting FP16 is subnormal or zero
|
||||
// use a magic value to align our 10 mantissa bits at the bottom of
|
||||
// the float. as long as FP addition is round-to-nearest-even this
|
||||
// just works.
|
||||
f.f += denorm_magic.f;
|
||||
|
||||
// and one integer subtract of the bias later, we have our final float!
|
||||
val = static_cast<uint16_t>(f.u - denorm_magic.u);
|
||||
} else {
|
||||
unsigned int mant_odd = (f.u >> 13) & 1; // resulting mantissa is odd
|
||||
|
||||
// update exponent, rounding bias part 1
|
||||
// Equivalent to `f.u += ((unsigned int)(15 - 127) << 23) + 0xfff`, but
|
||||
// without arithmetic overflow.
|
||||
f.u += 0xc8000fffU;
|
||||
// rounding bias part 2
|
||||
f.u += mant_odd;
|
||||
// take the bits!
|
||||
val = static_cast<uint16_t>(f.u >> 13);
|
||||
}
|
||||
}
|
||||
|
||||
val |= static_cast<uint16_t>(sign >> 16);
|
||||
return val;
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
inline float Float16Impl<Derived>::ToFloatImpl() const noexcept {
|
||||
constexpr detail::float32_bits magic = {113 << 23};
|
||||
constexpr unsigned int shifted_exp = 0x7c00 << 13; // exponent mask after shift
|
||||
detail::float32_bits o{};
|
||||
|
||||
o.u = (val & 0x7fff) << 13; // exponent/mantissa bits
|
||||
unsigned int exp = shifted_exp & o.u; // just the exponent
|
||||
o.u += (127 - 15) << 23; // exponent adjust
|
||||
|
||||
// handle exponent special cases
|
||||
if (exp == shifted_exp) { // Inf/NaN?
|
||||
o.u += (128 - 16) << 23; // extra exp adjust
|
||||
} else if (exp == 0) { // Zero/Denormal?
|
||||
o.u += 1 << 23; // extra exp adjust
|
||||
o.f -= magic.f; // re-normalize
|
||||
}
|
||||
|
||||
// Attempt to workaround the Internal Compiler Error on ARM64
|
||||
// for bitwise | operator, including std::bitset
|
||||
#if (defined _MSC_VER) && (defined _M_ARM || defined _M_ARM64 || defined _M_ARM64EC)
|
||||
if (IsNegative()) {
|
||||
return -o.f;
|
||||
}
|
||||
#else
|
||||
// original code:
|
||||
o.u |= (val & 0x8000U) << 16U; // sign bit
|
||||
#endif
|
||||
return o.f;
|
||||
}
|
||||
|
||||
/// Shared implementation between public and internal classes. CRTP pattern.
|
||||
template <class Derived>
|
||||
struct BFloat16Impl {
|
||||
protected:
|
||||
/// <summary>
|
||||
/// Converts from float to uint16_t float16 representation
|
||||
/// </summary>
|
||||
/// <param name="v"></param>
|
||||
/// <returns></returns>
|
||||
static uint16_t ToUint16Impl(float v) noexcept;
|
||||
|
||||
/// <summary>
|
||||
/// Converts bfloat16 to float
|
||||
/// </summary>
|
||||
/// <returns>float representation of bfloat16 value</returns>
|
||||
float ToFloatImpl() const noexcept;
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance that represents absolute value.
|
||||
/// </summary>
|
||||
/// <returns>Absolute value</returns>
|
||||
uint16_t AbsImpl() const noexcept {
|
||||
return static_cast<uint16_t>(val & ~kSignMask);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance with the sign flipped.
|
||||
/// </summary>
|
||||
/// <returns>Flipped sign instance</returns>
|
||||
uint16_t NegateImpl() const noexcept {
|
||||
return IsNaN() ? val : static_cast<uint16_t>(val ^ kSignMask);
|
||||
}
|
||||
|
||||
public:
|
||||
// uint16_t special values
|
||||
static constexpr uint16_t kSignMask = 0x8000U;
|
||||
static constexpr uint16_t kBiasedExponentMask = 0x7F80U;
|
||||
static constexpr uint16_t kPositiveInfinityBits = 0x7F80U;
|
||||
static constexpr uint16_t kNegativeInfinityBits = 0xFF80U;
|
||||
static constexpr uint16_t kPositiveQNaNBits = 0x7FC1U;
|
||||
static constexpr uint16_t kNegativeQNaNBits = 0xFFC1U;
|
||||
static constexpr uint16_t kMaxValueBits = 0x7F7FU;
|
||||
static constexpr uint16_t kRoundToNearest = 0x7FFFU;
|
||||
static constexpr uint16_t kOneBits = 0x3F80U;
|
||||
static constexpr uint16_t kMinusOneBits = 0xBF80U;
|
||||
|
||||
uint16_t val{0};
|
||||
|
||||
BFloat16Impl() = default;
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the value is negative
|
||||
/// </summary>
|
||||
/// <returns>true if negative</returns>
|
||||
bool IsNegative() const noexcept {
|
||||
return static_cast<int16_t>(val) < 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if the value is NaN
|
||||
/// </summary>
|
||||
/// <returns>true if NaN</returns>
|
||||
bool IsNaN() const noexcept {
|
||||
return AbsImpl() > kPositiveInfinityBits;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if the value is finite
|
||||
/// </summary>
|
||||
/// <returns>true if finite</returns>
|
||||
bool IsFinite() const noexcept {
|
||||
return AbsImpl() < kPositiveInfinityBits;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if the value represents positive infinity.
|
||||
/// </summary>
|
||||
/// <returns>true if positive infinity</returns>
|
||||
bool IsPositiveInfinity() const noexcept {
|
||||
return val == kPositiveInfinityBits;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if the value represents negative infinity
|
||||
/// </summary>
|
||||
/// <returns>true if negative infinity</returns>
|
||||
bool IsNegativeInfinity() const noexcept {
|
||||
return val == kNegativeInfinityBits;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if the value is either positive or negative infinity.
|
||||
/// </summary>
|
||||
/// <returns>True if absolute value is infinity</returns>
|
||||
bool IsInfinity() const noexcept {
|
||||
return AbsImpl() == kPositiveInfinityBits;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if the value is NaN or zero. Useful for comparisons.
|
||||
/// </summary>
|
||||
/// <returns>True if NaN or zero.</returns>
|
||||
bool IsNaNOrZero() const noexcept {
|
||||
auto abs = AbsImpl();
|
||||
return (abs == 0 || abs > kPositiveInfinityBits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if the value is normal (not zero, subnormal, infinite, or NaN).
|
||||
/// </summary>
|
||||
/// <returns>True if so</returns>
|
||||
bool IsNormal() const noexcept {
|
||||
auto abs = AbsImpl();
|
||||
return (abs < kPositiveInfinityBits) // is finite
|
||||
&& (abs != 0) // is not zero
|
||||
&& ((abs & kBiasedExponentMask) != 0); // is not subnormal (has a non-zero exponent)
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if the value is subnormal (denormal).
|
||||
/// </summary>
|
||||
/// <returns>True if so</returns>
|
||||
bool IsSubnormal() const noexcept {
|
||||
auto abs = AbsImpl();
|
||||
return (abs < kPositiveInfinityBits) // is finite
|
||||
&& (abs != 0) // is not zero
|
||||
&& ((abs & kBiasedExponentMask) == 0); // is subnormal (has a zero exponent)
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance that represents absolute value.
|
||||
/// </summary>
|
||||
/// <returns>Absolute value</returns>
|
||||
Derived Abs() const noexcept { return Derived::FromBits(AbsImpl()); }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance with the sign flipped.
|
||||
/// </summary>
|
||||
/// <returns>Flipped sign instance</returns>
|
||||
Derived Negate() const noexcept { return Derived::FromBits(NegateImpl()); }
|
||||
|
||||
/// <summary>
|
||||
/// IEEE defines that positive and negative zero are equal, this gives us a quick equality check
|
||||
/// for two values by or'ing the private bits together and stripping the sign. They are both zero,
|
||||
/// and therefore equivalent, if the resulting value is still zero.
|
||||
/// </summary>
|
||||
/// <param name="lhs">first value</param>
|
||||
/// <param name="rhs">second value</param>
|
||||
/// <returns>True if both arguments represent zero</returns>
|
||||
static bool AreZero(const BFloat16Impl& lhs, const BFloat16Impl& rhs) noexcept {
|
||||
// IEEE defines that positive and negative zero are equal, this gives us a quick equality check
|
||||
// for two values by or'ing the private bits together and stripping the sign. They are both zero,
|
||||
// and therefore equivalent, if the resulting value is still zero.
|
||||
return static_cast<uint16_t>((lhs.val | rhs.val) & ~kSignMask) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Derived>
|
||||
inline uint16_t BFloat16Impl<Derived>::ToUint16Impl(float v) noexcept {
|
||||
uint16_t result;
|
||||
if (std::isnan(v)) {
|
||||
result = kPositiveQNaNBits;
|
||||
} else {
|
||||
auto get_msb_half = [](float fl) {
|
||||
uint16_t result;
|
||||
#ifdef __cpp_if_constexpr
|
||||
if constexpr (detail::endian::native == detail::endian::little) {
|
||||
#else
|
||||
if (detail::endian::native == detail::endian::little) {
|
||||
#endif
|
||||
std::memcpy(&result, reinterpret_cast<char*>(&fl) + sizeof(uint16_t), sizeof(uint16_t));
|
||||
} else {
|
||||
std::memcpy(&result, &fl, sizeof(uint16_t));
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
uint16_t upper_bits = get_msb_half(v);
|
||||
union {
|
||||
uint32_t U32;
|
||||
float F32;
|
||||
};
|
||||
F32 = v;
|
||||
U32 += (upper_bits & 1) + kRoundToNearest;
|
||||
result = get_msb_half(F32);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
inline float BFloat16Impl<Derived>::ToFloatImpl() const noexcept {
|
||||
if (IsNaN()) {
|
||||
return std::numeric_limits<float>::quiet_NaN();
|
||||
}
|
||||
float result;
|
||||
char* const first = reinterpret_cast<char*>(&result);
|
||||
char* const second = first + sizeof(uint16_t);
|
||||
#ifdef __cpp_if_constexpr
|
||||
if constexpr (detail::endian::native == detail::endian::little) {
|
||||
#else
|
||||
if (detail::endian::native == detail::endian::little) {
|
||||
#endif
|
||||
std::memset(first, 0, sizeof(uint16_t));
|
||||
std::memcpy(second, &val, sizeof(uint16_t));
|
||||
} else {
|
||||
std::memcpy(first, &val, sizeof(uint16_t));
|
||||
std::memset(second, 0, sizeof(uint16_t));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace onnxruntime_float16
|
||||
@ -0,0 +1,10 @@
|
||||
;
|
||||
; Definition file of onnxruntime.dll
|
||||
; Automatic generated by gendef 1.1
|
||||
; written by Kai Tietz 2008
|
||||
; The def file has to be processed by --kill-at (-k) option of dlltool or ld
|
||||
;
|
||||
LIBRARY "onnxruntime.dll"
|
||||
EXPORTS
|
||||
OrtGetApiBase
|
||||
OrtSessionOptionsAppendExecutionProvider_CPU
|
||||
|
After Width: | Height: | Size: 445 KiB |
|
After Width: | Height: | Size: 513 KiB |
|
After Width: | Height: | Size: 513 KiB |
|
After Width: | Height: | Size: 527 KiB |
|
After Width: | Height: | Size: 347 KiB |
|
After Width: | Height: | Size: 340 KiB |
|
After Width: | Height: | Size: 425 KiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 2.3 MiB |
|
After Width: | Height: | Size: 2.1 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 2.2 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 446 KiB |
|
After Width: | Height: | Size: 487 KiB |
|
After Width: | Height: | Size: 2.9 MiB |
|
After Width: | Height: | Size: 3.0 MiB |
|
After Width: | Height: | Size: 2.5 MiB |
|
After Width: | Height: | Size: 2.6 MiB |
|
After Width: | Height: | Size: 2.8 MiB |
|
After Width: | Height: | Size: 3.0 MiB |
|
After Width: | Height: | Size: 2.5 MiB |
|
After Width: | Height: | Size: 2.6 MiB |
@ -0,0 +1,553 @@
|
||||
{
|
||||
"20260510170010_1.jpg": [
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
882,
|
||||
283,
|
||||
76,
|
||||
131
|
||||
],
|
||||
"confidence": 0.8
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
883,
|
||||
394,
|
||||
22,
|
||||
39
|
||||
],
|
||||
"confidence": 0.78
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
883,
|
||||
476,
|
||||
125,
|
||||
58
|
||||
],
|
||||
"confidence": 0.75
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
819,
|
||||
624,
|
||||
46,
|
||||
24
|
||||
],
|
||||
"confidence": 0.68
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
1472,
|
||||
303,
|
||||
42,
|
||||
90
|
||||
],
|
||||
"confidence": 0.65
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
182,
|
||||
391,
|
||||
63,
|
||||
24
|
||||
],
|
||||
"confidence": 0.65
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
603,
|
||||
450,
|
||||
97,
|
||||
49
|
||||
],
|
||||
"confidence": 0.65
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
1400,
|
||||
525,
|
||||
141,
|
||||
58
|
||||
],
|
||||
"confidence": 0.6
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
294,
|
||||
394,
|
||||
53,
|
||||
22
|
||||
],
|
||||
"confidence": 0.55
|
||||
}
|
||||
],
|
||||
"20260510170100_1.jpg": [
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
1452,
|
||||
376,
|
||||
169,
|
||||
119
|
||||
],
|
||||
"confidence": 0.8
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
907,
|
||||
416,
|
||||
51,
|
||||
22
|
||||
],
|
||||
"confidence": 0.68
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
699,
|
||||
362,
|
||||
27,
|
||||
45
|
||||
],
|
||||
"confidence": 0.63
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
834,
|
||||
445,
|
||||
42,
|
||||
44
|
||||
],
|
||||
"confidence": 0.63
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
732,
|
||||
435,
|
||||
63,
|
||||
28
|
||||
],
|
||||
"confidence": 0.6
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
949,
|
||||
338,
|
||||
43,
|
||||
25
|
||||
],
|
||||
"confidence": 0.58
|
||||
}
|
||||
],
|
||||
"20260510170106_1.jpg": [
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
1452,
|
||||
376,
|
||||
169,
|
||||
119
|
||||
],
|
||||
"confidence": 0.8
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
907,
|
||||
416,
|
||||
51,
|
||||
22
|
||||
],
|
||||
"confidence": 0.68
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
699,
|
||||
362,
|
||||
27,
|
||||
45
|
||||
],
|
||||
"confidence": 0.63
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
834,
|
||||
445,
|
||||
42,
|
||||
44
|
||||
],
|
||||
"confidence": 0.63
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
732,
|
||||
435,
|
||||
63,
|
||||
28
|
||||
],
|
||||
"confidence": 0.6
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
949,
|
||||
338,
|
||||
43,
|
||||
25
|
||||
],
|
||||
"confidence": 0.58
|
||||
}
|
||||
],
|
||||
"20260510170110_1.jpg": [
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
737,
|
||||
490,
|
||||
26,
|
||||
43
|
||||
],
|
||||
"confidence": 0.78
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
1610,
|
||||
68,
|
||||
28,
|
||||
30
|
||||
],
|
||||
"confidence": 0.68
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
941,
|
||||
549,
|
||||
51,
|
||||
21
|
||||
],
|
||||
"confidence": 0.68
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
765,
|
||||
564,
|
||||
56,
|
||||
25
|
||||
],
|
||||
"confidence": 0.68
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
867,
|
||||
576,
|
||||
43,
|
||||
51
|
||||
],
|
||||
"confidence": 0.55
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
188,
|
||||
59,
|
||||
41,
|
||||
40
|
||||
],
|
||||
"confidence": 0.53
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
31,
|
||||
143,
|
||||
36,
|
||||
36
|
||||
],
|
||||
"confidence": 0.53
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
982,
|
||||
473,
|
||||
44,
|
||||
23
|
||||
],
|
||||
"confidence": 0.53
|
||||
}
|
||||
],
|
||||
"20260510170127_1.jpg": [
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
1300,
|
||||
463,
|
||||
110,
|
||||
115
|
||||
],
|
||||
"confidence": 0.8
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
386,
|
||||
607,
|
||||
274,
|
||||
82
|
||||
],
|
||||
"confidence": 0.75
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
485,
|
||||
779,
|
||||
68,
|
||||
21
|
||||
],
|
||||
"confidence": 0.75
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
17,
|
||||
345,
|
||||
41,
|
||||
47
|
||||
],
|
||||
"confidence": 0.65
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
532,
|
||||
243,
|
||||
61,
|
||||
18
|
||||
],
|
||||
"confidence": 0.58
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
274,
|
||||
323,
|
||||
30,
|
||||
33
|
||||
],
|
||||
"confidence": 0.58
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
1376,
|
||||
333,
|
||||
31,
|
||||
40
|
||||
],
|
||||
"confidence": 0.58
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
979,
|
||||
522,
|
||||
44,
|
||||
62
|
||||
],
|
||||
"confidence": 0.5
|
||||
}
|
||||
],
|
||||
"20260510170152_1.jpg": [],
|
||||
"20260510170205_1.jpg": [
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
796,
|
||||
330,
|
||||
47,
|
||||
48
|
||||
],
|
||||
"confidence": 0.85
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
773,
|
||||
603,
|
||||
28,
|
||||
57
|
||||
],
|
||||
"confidence": 0.85
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
792,
|
||||
139,
|
||||
150,
|
||||
188
|
||||
],
|
||||
"confidence": 0.75
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
96,
|
||||
194,
|
||||
40,
|
||||
44
|
||||
],
|
||||
"confidence": 0.75
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
912,
|
||||
569,
|
||||
55,
|
||||
25
|
||||
],
|
||||
"confidence": 0.75
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
679,
|
||||
753,
|
||||
52,
|
||||
28
|
||||
],
|
||||
"confidence": 0.75
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
1432,
|
||||
340,
|
||||
83,
|
||||
52
|
||||
],
|
||||
"confidence": 0.6
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
629,
|
||||
312,
|
||||
67,
|
||||
22
|
||||
],
|
||||
"confidence": 0.53
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
267,
|
||||
537,
|
||||
42,
|
||||
29
|
||||
],
|
||||
"confidence": 0.53
|
||||
}
|
||||
],
|
||||
"Thermal_ColdGun_001_processed.png": [],
|
||||
"微信图片_20260503224413_383_75.png": [
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
1286,
|
||||
155,
|
||||
52,
|
||||
53
|
||||
],
|
||||
"confidence": 0.85
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
1183,
|
||||
151,
|
||||
57,
|
||||
64
|
||||
],
|
||||
"confidence": 0.75
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
903,
|
||||
99,
|
||||
55,
|
||||
59
|
||||
],
|
||||
"confidence": 0.65
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
1353,
|
||||
191,
|
||||
70,
|
||||
45
|
||||
],
|
||||
"confidence": 0.6
|
||||
}
|
||||
],
|
||||
"微信图片_20260503224418_384_75.png": [],
|
||||
"微信图片_20260503224424_385_75.png": [
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
817,
|
||||
127,
|
||||
44,
|
||||
47
|
||||
],
|
||||
"confidence": 0.85
|
||||
},
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
554,
|
||||
160,
|
||||
73,
|
||||
62
|
||||
],
|
||||
"confidence": 0.65
|
||||
}
|
||||
],
|
||||
"微信图片_20260503224430_386_75.png": [
|
||||
{
|
||||
"type": "Person",
|
||||
"bbox": [
|
||||
509,
|
||||
79,
|
||||
50,
|
||||
50
|
||||
],
|
||||
"confidence": 0.85
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
placeholder
|
||||