16#include "../../AutonomyConstants.h"
17#include "../../interfaces/TensorflowTPU.hpp"
20#include <nlohmann/json.hpp>
21#include <opencv2/opencv.hpp>
22#include <torch/script.h>
23#include <torch/torch.h>
52 std::string szClassName;
72 std::vector<int>& vClassIDs,
73 std::vector<float>& vClassConfidences,
74 std::vector<cv::Rect>& vBoundingBoxes,
75 float fMinObjectConfidence,
79 std::vector<int> vNMSValidIndices;
82 cv::dnn::NMSBoxes(vBoundingBoxes, vClassConfidences, fMinObjectConfidence, fNMSThreshold, vNMSValidIndices);
85 for (
int nValidIndex : vNMSValidIndices)
90 stNewDetection.nClassID = vClassIDs[nValidIndex];
91 stNewDetection.fConfidence = vClassConfidences[nValidIndex];
92 stNewDetection.cvBoundingBox = vBoundingBoxes[nValidIndex];
95 vObjects.emplace_back(stNewDetection);
115 int nHue =
static_cast<int>(stObject.nClassID % 256);
117 int nSaturation = 255;
125 cv::Scalar cvBoxColor(cvConvertedValues[2], cvConvertedValues[1], cvConvertedValues[0]);
128 cv::rectangle(cvInputFrame, stObject.cvBoundingBox, cvBoxColor, 2);
131 cv::Point(stObject.cvBoundingBox.x, stObject.cvBoundingBox.y - 20),
132 cv::Point(stObject.cvBoundingBox.x + stObject.cvBoundingBox.width, stObject.cvBoundingBox.y),
137 std::to_string(stObject.nClassID) +
" " + std::to_string(stObject.fConfidence),
138 cv::Point(stObject.cvBoundingBox.x, stObject.cvBoundingBox.y - 5),
196 int nObjectnessLocationClasses;
241 PerformanceModes ePowerMode = PerformanceModes::eHigh,
242 unsigned int unMaxBulkInQueueLength = 32,
243 bool bUSBAlwaysDFU =
false) :
278 const float fMinObjectConfidence = 0.85,
279 const float fNMSThreshold = 0.6)
override
282 std::vector<std::vector<Detection>> vTensorObjectOutputs;
288 m_cvFrame = cvInputFrame;
291 if (m_bDeviceOpened && m_pEdgeTPUContext->IsReady())
301 if (m_cvFrame.
rows != stInputDimensions.nHeight || m_cvFrame.
cols != stInputDimensions.nWidth)
306 cv::Size(stInputDimensions.nWidth, stInputDimensions.nHeight),
307 constants::BASICCAM_RESIZE_INTERPOLATION_METHOD);
311 std::vector<int8_t> vInputData(m_cvFrame.
data,
312 m_cvFrame.
data + (
static_cast<unsigned long>(m_cvFrame.
cols) * m_cvFrame.
rows * m_cvFrame.
elemSize()));
321 TfLiteTensor* pInputTensor = m_pInterpreter->tensor(stInputDimensions.nTensorIndex);
322 std::memcpy(pInputTensor->data.raw, vInputData.data(), vInputData.size());
325 if (m_pInterpreter->Invoke() != kTfLiteOk)
328 LOG_WARNING(logging::g_qSharedLogger,
329 "Inferencing failed on an image for model {} with device {} ({})",
332 this->DeviceTypeToString(m_tpuDevice.type));
337 std::vector<int> vClassIDs;
338 std::vector<float> vClassConfidences;
339 std::vector<cv::Rect> vBoundingBoxes;
341 std::vector<Detection> vObjects;
344 for (
int nTensorIndex : m_pInterpreter->outputs())
348 vClassConfidences.clear();
349 vBoundingBoxes.clear();
359 int nImgSize = stInputDimensions.nHeight;
360 int nP3Stride = std::pow((nImgSize / 8), 2);
361 int nP4Stride = std::pow((nImgSize / 16), 2);
362 int nP5Stride = std::pow((nImgSize / 32), 2);
364 int nYOLOv5AnchorsPerGridPoint = 3;
365 int nYOLOv8AnchorsPerGridPoint = 1;
366 int nYOLOv5TotalPredictionLength =
367 (nP3Stride * nYOLOv5AnchorsPerGridPoint) + (nP4Stride * nYOLOv5AnchorsPerGridPoint) + (nP5Stride * nYOLOv5AnchorsPerGridPoint);
368 int nYOLOv8TotalPredictionLength =
369 (nP3Stride * nYOLOv8AnchorsPerGridPoint) + (nP4Stride * nYOLOv8AnchorsPerGridPoint) + (nP5Stride * nYOLOv8AnchorsPerGridPoint);
372 if (stOutputDimensions.nAnchors == nYOLOv5TotalPredictionLength)
379 fMinObjectConfidence,
384 else if (stOutputDimensions.nAnchors == nYOLOv8TotalPredictionLength)
391 fMinObjectConfidence,
397 NonMaxSuppression(vObjects, vClassIDs, vClassConfidences, vBoundingBoxes, fMinObjectConfidence, fNMSThreshold);
400 vTensorObjectOutputs.emplace_back(vObjects);
407 LOG_WARNING(logging::g_qSharedLogger,
408 "Inferencing failed on an image for model {} with device {} ({})",
411 this->DeviceTypeToString(m_tpuDevice.type));
414 return vTensorObjectOutputs;
449 std::vector<int>& vClassIDs,
450 std::vector<float>& vClassConfidences,
451 std::vector<cv::Rect>& vBoundingBoxes,
452 float fMinObjectConfidence,
453 int nOriginalFrameWidth,
454 int nOriginalFrameHeight)
457 TfLiteTensor* tfOutputTensor = m_pInterpreter->tensor(nOutputIndex);
461 std::vector<float> vGridPrediction;
463 vGridPrediction.resize(stOutputDimensions.nObjectnessLocationClasses);
472 for (
int nIter = 0; nIter < stOutputDimensions.nAnchors; ++nIter)
475 float fObjectnessConfidence =
476 (tfOutputTensor->data.uint8[(nIter * stOutputDimensions.nObjectnessLocationClasses) + 4] - stOutputDimensions.nQuantZeroPoint) *
477 stOutputDimensions.fQuantScale;
480 if (fObjectnessConfidence >= fMinObjectConfidence)
484 for (
int nJter = 0; nJter < stOutputDimensions.nObjectnessLocationClasses; ++nJter)
487 vGridPrediction[nJter] =
488 (tfOutputTensor->data.uint8[(nIter * stOutputDimensions.nObjectnessLocationClasses) + nJter] - stOutputDimensions.nQuantZeroPoint) *
489 stOutputDimensions.fQuantScale;
493 std::vector<float>::iterator pStartIterator = vGridPrediction.begin() + 5;
494 std::vector<float>::iterator pMaxConfidence = std::max_element(pStartIterator, vGridPrediction.end());
495 int nClassID = std::distance(pStartIterator, pMaxConfidence);
497 float fClassConfidence = vGridPrediction[nClassID + 5];
500 int nCenterX = vGridPrediction[0] * nOriginalFrameWidth;
501 int nCenterY = vGridPrediction[1] * nOriginalFrameHeight;
502 int nWidth = vGridPrediction[2] * nOriginalFrameWidth;
503 int nHeight = vGridPrediction[3] * nOriginalFrameHeight;
505 if (nWidth > 0 && nHeight > 0)
508 cvBoundingBox.
x = int(nCenterX - (0.5 * nWidth));
509 cvBoundingBox.
y = int(nCenterY - (0.5 * nHeight));
510 cvBoundingBox.
width = nWidth;
511 cvBoundingBox.
height = nHeight;
513 vClassIDs.emplace_back(nClassID);
514 vClassConfidences.emplace_back(fClassConfidence);
515 vBoundingBoxes.emplace_back(cvBoundingBox);
545 std::vector<int>& vClassIDs,
546 std::vector<float>& vClassConfidences,
547 std::vector<cv::Rect>& vBoundingBoxes,
548 float fMinObjectConfidence,
549 int nOriginalFrameWidth,
550 int nOriginalFrameHeight)
553 TfLiteTensor* tfOutputTensor = m_pInterpreter->tensor(nOutputIndex);
557 std::vector<float> vGridPrediction;
559 vGridPrediction.resize(stOutputDimensions.nObjectnessLocationClasses);
569 for (
int nIter = 0; nIter < stOutputDimensions.nAnchors; ++nIter)
573 std::string szTest =
"";
574 for (
int nJter = 0; nJter < stOutputDimensions.nObjectnessLocationClasses; ++nJter)
577 vGridPrediction[nJter] = (tfOutputTensor->data.int8[nIter + (nJter * stOutputDimensions.nAnchors)] - stOutputDimensions.nQuantZeroPoint) *
578 stOutputDimensions.fQuantScale;
582 std::vector<float>::iterator pStartIterator = vGridPrediction.begin() + 4;
583 std::vector<float>::iterator pMaxConfidence = std::max_element(pStartIterator, vGridPrediction.end());
584 int nClassID = std::distance(pStartIterator, pMaxConfidence);
586 float fClassConfidence = vGridPrediction[nClassID + 4];
589 if (fClassConfidence >= fMinObjectConfidence)
593 int nCenterX = vGridPrediction[0] * nOriginalFrameWidth;
594 int nCenterY = vGridPrediction[1] * nOriginalFrameHeight;
595 int nWidth = vGridPrediction[2] * nOriginalFrameWidth;
596 int nHeight = vGridPrediction[3] * nOriginalFrameHeight;
598 cvBoundingBox.
x = int(nCenterX - (0.5 * nWidth));
599 cvBoundingBox.
y = int(nCenterY - (0.5 * nHeight));
600 cvBoundingBox.
width = nWidth;
601 cvBoundingBox.
height = nHeight;
603 vClassIDs.emplace_back(nClassID);
604 vClassConfidences.emplace_back(fClassConfidence);
605 vBoundingBoxes.emplace_back(cvBoundingBox);
631 TfLiteTensor* tfInputTensor = m_pInterpreter->tensor(nTensorIndex);
632 TfLiteIntArray* tfDimensions = tfInputTensor->dims;
635 stInputDimensions.nHeight = tfDimensions->data[1];
636 stInputDimensions.nWidth = tfDimensions->data[2];
637 stInputDimensions.nChannels = tfDimensions->data[3];
638 stInputDimensions.nTensorIndex = nTensorIndex;
640 stInputDimensions.nQuantZeroPoint = tfInputTensor->params.zero_point;
641 stInputDimensions.fQuantScale = tfInputTensor->params.scale;
644 return stInputDimensions;
668 TfLiteTensor* tfOutputTensor = m_pInterpreter->tensor(nTensorIndex);
669 TfLiteIntArray* tfDimensions = tfOutputTensor->dims;
672 stOutputDimensions.nAnchors = std::max(tfDimensions->data[1], tfDimensions->data[2]);
673 stOutputDimensions.nObjectnessLocationClasses = std::min(tfDimensions->data[1], tfDimensions->data[2]);
674 stOutputDimensions.nTensorIndex = nTensorIndex;
676 stOutputDimensions.nQuantZeroPoint = tfOutputTensor->params.zero_point;
677 stOutputDimensions.fQuantScale = tfOutputTensor->params.scale;
680 return stOutputDimensions;
715 enum class HardwareDevices
734 PyTorchInterpreter(std::string szModelPath, HardwareDevices eHardwareDevice = HardwareDevices::eCUDA)
737 m_szModelPath = szModelPath;
739 m_cvModelInputSize =
cv::Size(640, 640);
740 m_szModelTask =
"Unknown";
741 m_vClassLabels = std::vector<std::string>();
744 switch (eHardwareDevice)
746 case HardwareDevices::eCPU: m_trDevice = torch::kCPU;
break;
747 case HardwareDevices::eCUDA: m_trDevice = torch::kCUDA;
break;
748 default: m_trDevice = torch::kCPU;
break;
752 LOG_INFO(logging::g_qSharedLogger,
"Attempting to load model {} onto device {}", szModelPath, m_trDevice.str());
755 if (!std::filesystem::exists(szModelPath))
758 LOG_ERROR(logging::g_qSharedLogger,
"Model path {} does not exist!", szModelPath);
762 if (!torch::cuda::is_available() && m_trDevice == torch::kCUDA)
765 LOG_ERROR(logging::g_qSharedLogger,
"CUDA device is not available, falling back to CPU.");
766 m_trDevice = torch::kCPU;
772 LOG_INFO(logging::g_qSharedLogger,
"Using device: {}", m_trDevice.str());
779 torch::jit::ExtraFilesMap trExtraConfigFiles{{
"config.txt",
""}};
780 m_trModel = torch::jit::load(szModelPath, m_trDevice, trExtraConfigFiles);
784 nlohmann::json jConfig = nlohmann::json::parse(trExtraConfigFiles.at(
"config.txt"));
786 m_cvModelInputSize =
cv::Size(jConfig[
"imgsz"][0], jConfig[
"imgsz"][1]);
787 m_szModelTask = jConfig[
"task"];
788 for (
const auto& item : jConfig[
"names"].items())
790 m_vClassLabels.push_back(item.value());
793 LOG_DEBUG(logging::g_qSharedLogger,
"Model config: {}", jConfig.dump(4));
796 if (m_trModel.get_methods().empty())
798 LOG_ERROR(logging::g_qSharedLogger,
"Model is empty! Check if the correct model file was provided.");
802 if (m_trModel.buffers().size() > 0)
805 torch::Device model_device = m_trModel.buffers().begin().operator->().device();
806 if (model_device != m_trDevice)
808 LOG_ERROR(logging::g_qSharedLogger,
"Model did not move to the expected device! Model is on: {}", model_device.str());
814 LOG_WARNING(logging::g_qSharedLogger,
"Model has no buffers to check the device.");
818 LOG_INFO(logging::g_qSharedLogger,
819 "Model successfully loaded and set to eval mode. The model is a {} model, and has {} classes.",
821 m_vClassLabels.size());
826 catch (
const c10::Error& trError)
828 LOG_ERROR(logging::g_qSharedLogger,
"Error loading model: {}", trError.what());
859 std::vector<Detection>
Inference(
const cv::Mat& cvInputFrame,
const float fMinObjectConfidence = 0.85,
const float fNMSThreshold = 0.6)
862 torch::set_num_threads(1);
864 std::vector<Detection> vObjects;
867 torch::Tensor trTensorImage =
PreprocessImage(cvInputFrame, m_trDevice);
870 std::vector<torch::jit::IValue> vInputs;
871 vInputs.push_back(trTensorImage);
872 torch::Tensor trOutputTensor;
875 trOutputTensor = m_trModel.forward(vInputs).toTensor();
877 catch (
const c10::Error& trError)
879 LOG_ERROR(logging::g_qSharedLogger,
"Error running inference: {}", trError.what());
884 int nImgSize = m_cvModelInputSize.
height;
885 int nP3Stride = std::pow((nImgSize / 8), 2);
886 int nP4Stride = std::pow((nImgSize / 16), 2);
887 int nP5Stride = std::pow((nImgSize / 32), 2);
889 int nYOLOv5AnchorsPerGridPoint = 3;
890 int nYOLOv8AnchorsPerGridPoint = 1;
891 int nYOLOv5TotalPredictionLength =
892 (nP3Stride * nYOLOv5AnchorsPerGridPoint) + (nP4Stride * nYOLOv5AnchorsPerGridPoint) + (nP5Stride * nYOLOv5AnchorsPerGridPoint);
893 int nYOLOv8TotalPredictionLength =
894 (nP3Stride * nYOLOv8AnchorsPerGridPoint) + (nP4Stride * nYOLOv8AnchorsPerGridPoint) + (nP5Stride * nYOLOv8AnchorsPerGridPoint);
897 std::vector<int> vClassIDs;
898 std::vector<std::string> vClassLabels;
899 std::vector<float> vClassConfidences;
900 std::vector<cv::Rect> vBoundingBoxes;
903 int nLargestDimension = *std::max_element(trOutputTensor.sizes().begin(), trOutputTensor.sizes().end());
905 if (nLargestDimension == nYOLOv5TotalPredictionLength)
908 this->
ParseTensorOutputYOLOv5(trOutputTensor, vClassIDs, vClassConfidences, vBoundingBoxes, cvInputFrame.
size(), fMinObjectConfidence);
911 else if (nLargestDimension == nYOLOv8TotalPredictionLength)
914 this->
ParseTensorOutputYOLOv8(trOutputTensor, vClassIDs, vClassConfidences, vBoundingBoxes, cvInputFrame.
size(), fMinObjectConfidence);
918 NonMaxSuppression(vObjects, vClassIDs, vClassConfidences, vBoundingBoxes, fMinObjectConfidence, fNMSThreshold);
921 for (
size_t nIter = 0; nIter < vObjects.size(); ++nIter)
924 if (vClassIDs[nIter] >= 0 && vClassIDs[nIter] <
static_cast<int>(m_vClassLabels.size()))
926 vObjects[nIter].szClassName = m_vClassLabels[vClassIDs[nIter]];
930 vObjects[nIter].szClassName =
"UnknownClass";
972 torch::Tensor trTensorImage = torch::from_blob(cvResizedImage.
data, {1, cvResizedImage.rows, cvResizedImage.cols, 3}, torch::kFloat);
973 trTensorImage = trTensorImage.permute({0, 3, 1, 2});
974 trTensorImage = trTensorImage.to(trDevice);
976 return trTensorImage;
994 std::vector<int>& vClassIDs,
995 std::vector<float>& vClassConfidences,
996 std::vector<cv::Rect>& vBoundingBoxes,
998 const float fMinObjectConfidence)
1006 torch::Tensor trSqueezedOutput = trOutput.squeeze(0);
1009 if (trSqueezedOutput.device().is_cuda())
1011 trSqueezedOutput = trSqueezedOutput.to(torch::kCPU);
1014 if (trSqueezedOutput.scalar_type() != torch::kFloat32)
1016 trSqueezedOutput = trSqueezedOutput.to(torch::kFloat32);
1019 if (!trSqueezedOutput.is_contiguous())
1021 trSqueezedOutput = trSqueezedOutput.contiguous();
1025 at::TensorAccessor trAccessor = trSqueezedOutput.accessor<float, 2>();
1026 const int nNumDetections = trSqueezedOutput.size(0);
1027 const int nTotalValues = trSqueezedOutput.size(1);
1030 for (
int i = 0; i < nNumDetections; i++)
1033 float fObjectnessConfidence = trAccessor[i][4];
1036 if (fObjectnessConfidence < fMinObjectConfidence)
1042 float fCenterX = trAccessor[i][0];
1043 float fCenterY = trAccessor[i][1];
1044 float fWidth = trAccessor[i][2];
1045 float fHeight = trAccessor[i][3];
1048 int nLeft =
static_cast<int>((fCenterX - (0.5 * fWidth)) * cvInputFrameSize.
width);
1049 int nTop =
static_cast<int>((fCenterY - (0.5 * fHeight)) * cvInputFrameSize.
height);
1050 int nBoundingWidth =
static_cast<int>(fWidth * cvInputFrameSize.
width);
1051 int nBoundingHeight =
static_cast<int>(fHeight * cvInputFrameSize.
height);
1054 cv::Rect cvBoundingBox(nLeft, nTop, nBoundingWidth, nBoundingHeight);
1057 float fClassConfidence = -1.0f;
1059 for (
int j = 5; j < nTotalValues; j++)
1061 float fConfidence = trAccessor[i][j];
1062 if (fConfidence > fClassConfidence)
1064 fClassConfidence = fConfidence;
1070 if (fClassConfidence < fMinObjectConfidence)
1076 vClassIDs.emplace_back(nClassID);
1077 vClassConfidences.emplace_back(fClassConfidence);
1078 vBoundingBoxes.emplace_back(cvBoundingBox);
1102 std::vector<int>& vClassIDs,
1103 std::vector<float>& vClassConfidences,
1104 std::vector<cv::Rect>& vBoundingBoxes,
1106 const float fMinObjectConfidence)
1117 torch::Tensor trPermuteOutput = trOutput.permute({0, 2, 1}).squeeze(0);
1120 if (trPermuteOutput.device().is_cuda())
1122 trPermuteOutput = trPermuteOutput.to(torch::kCPU);
1125 if (trPermuteOutput.scalar_type() != torch::kFloat32)
1127 trPermuteOutput = trPermuteOutput.to(torch::kFloat32);
1130 if (!trPermuteOutput.is_contiguous())
1132 trPermuteOutput = trPermuteOutput.contiguous();
1136 at::TensorAccessor trAccessor = trPermuteOutput.accessor<float, 2>();
1137 const int nNumDetections = trPermuteOutput.size(0);
1138 const int nTotalValues = trPermuteOutput.size(1);
1141 for (
int i = 0; i < nNumDetections; i++)
1143 float fClassConfidence = -1.0f;
1147 for (
int j = 4; j < nTotalValues; j++)
1149 float fConfidence = trAccessor[i][j];
1150 if (fConfidence > fClassConfidence)
1152 fClassConfidence = fConfidence;
1158 if (fClassConfidence < fMinObjectConfidence)
1164 float fCenterX = trAccessor[i][0];
1165 float fCenterY = trAccessor[i][1];
1166 float fWidth = trAccessor[i][2];
1167 float fHeight = trAccessor[i][3];
1170 int nLeft =
static_cast<int>(fCenterX * cvInputFrameSize.
width / 640.0f - (0.5f * fWidth * cvInputFrameSize.
width / 640.0f));
1171 int nTop =
static_cast<int>(fCenterY * cvInputFrameSize.
height / 640.0f - (0.5f * fHeight * cvInputFrameSize.
height / 640.0f));
1172 int nBoxWidth =
static_cast<int>(fWidth * cvInputFrameSize.
width / 640.0f);
1173 int nBoxHeight =
static_cast<int>(fHeight * cvInputFrameSize.
height / 640.0f);
1174 cv::Rect cvBoundingBox(nLeft, nTop, nBoxWidth, nBoxHeight);
1177 vClassIDs.push_back(nClassID);
1178 vClassConfidences.push_back(fClassConfidence);
1179 vBoundingBoxes.push_back(cvBoundingBox);
1186 torch::jit::script::Module m_trModel;
1187 torch::Device m_trDevice = torch::kCPU;
1188 std::string m_szModelPath;
1190 std::string m_szModelTask;
1192 std::vector<std::string> m_vClassLabels;
This class is designed to enable quick, easy, and robust handling of .tflite models for deployment an...
Definition TensorflowTPU.hpp:39
void convertTo(OutputArray m, int rtype, double alpha=1, double beta=0) const
This class is designed to enable quick, easy, and robust inferencing of .pt yolo model.
Definition YOLOModel.hpp:710
void ParseTensorOutputYOLOv8(const torch::Tensor &trOutput, std::vector< int > &vClassIDs, std::vector< float > &vClassConfidences, std::vector< cv::Rect > &vBoundingBoxes, const cv::Size &cvInputFrameSize, const float fMinObjectConfidence)
Given a tensor output from a YOLOv5 model, parse it's output into something more usable.
Definition YOLOModel.hpp:1101
bool IsReadyForInference() const
Check if the model is ready for inference.
Definition YOLOModel.hpp:946
std::vector< Detection > Inference(const cv::Mat &cvInputFrame, const float fMinObjectConfidence=0.85, const float fNMSThreshold=0.6)
Given an input image forward the image through the YOLO model to run inference on the PyTorch model,...
Definition YOLOModel.hpp:859
void ParseTensorOutputYOLOv5(const torch::Tensor &trOutput, std::vector< int > &vClassIDs, std::vector< float > &vClassConfidences, std::vector< cv::Rect > &vBoundingBoxes, const cv::Size &cvInputFrameSize, const float fMinObjectConfidence)
Given a tensor output from a YOLOv5 model, parse it's output into something more usable.
Definition YOLOModel.hpp:993
PyTorchInterpreter(std::string szModelPath, HardwareDevices eHardwareDevice=HardwareDevices::eCUDA)
Construct a new PyTorchInterpreter object.
Definition YOLOModel.hpp:734
~PyTorchInterpreter()
Destroy the PyTorchInterpreter object.
Definition YOLOModel.hpp:839
torch::Tensor PreprocessImage(const cv::Mat &cvInputFrame, const torch::Device &trDevice)
Given an input image, preprocess the image to match the input tensor shape of the model,...
Definition YOLOModel.hpp:964
This class is designed to enable quick, easy, and robust inferencing of .tflite yolo model.
Definition YOLOModel.hpp:214
TPUInterpreter(std::string szModelPath, PerformanceModes ePowerMode=PerformanceModes::eHigh, unsigned int unMaxBulkInQueueLength=32, bool bUSBAlwaysDFU=false)
Construct a new TPUInterpreter object.
Definition YOLOModel.hpp:240
std::vector< std::vector< Detection > > Inference(const cv::Mat &cvInputFrame, const float fMinObjectConfidence=0.85, const float fNMSThreshold=0.6) override
Given an input image forward the image through the YOLO model to run inference on the EdgeTPU,...
Definition YOLOModel.hpp:277
~TPUInterpreter()
Destroy the TPUInterpreter object.
Definition YOLOModel.hpp:255
OutputTensorDimensions GetOutputShape(const int nTensorIndex=0)
Get the output shape of the tensor at the given index. Requires the device to have been successfully ...
Definition YOLOModel.hpp:659
InputTensorDimensions GetInputShape(const int nTensorIndex=0)
Get the input shape of the tensor at the given index. Requires the device to have been successfully o...
Definition YOLOModel.hpp:622
void ParseTensorOutputYOLOv5(int nOutputIndex, std::vector< int > &vClassIDs, std::vector< float > &vClassConfidences, std::vector< cv::Rect > &vBoundingBoxes, float fMinObjectConfidence, int nOriginalFrameWidth, int nOriginalFrameHeight)
Given a TFLite output tensor from a YOLOv5 model, parse it's output into something more usable....
Definition YOLOModel.hpp:448
void ParseTensorOutputYOLOv8(int nOutputIndex, std::vector< int > &vClassIDs, std::vector< float > &vClassConfidences, std::vector< cv::Rect > &vBoundingBoxes, float fMinObjectConfidence, int nOriginalFrameWidth, int nOriginalFrameHeight)
Given a TFLite output tensor from a YOLOv8 model, parse it's output into something more usable....
Definition YOLOModel.hpp:544
void NMSBoxes(const std::vector< Rect > &bboxes, const std::vector< float > &scores, const float score_threshold, const float nms_threshold, std::vector< int > &indices, const float eta=1.f, const int top_k=0)
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0)
void rectangle(InputOutputArray img, Point pt1, Point pt2, const Scalar &color, int thickness=1, int lineType=LINE_8, int shift=0)
void putText(InputOutputArray img, const String &text, Point org, int fontFace, double fontScale, Scalar color, int thickness=1, int lineType=LINE_8, bool bottomLeftOrigin=false)
Namespace containing functions or objects/struct used to aid in easy use of YOLO models....
Definition YOLOModel.hpp:36
void NonMaxSuppression(std::vector< Detection > &vObjects, std::vector< int > &vClassIDs, std::vector< float > &vClassConfidences, std::vector< cv::Rect > &vBoundingBoxes, float fMinObjectConfidence, float fNMSThreshold)
Perform non max suppression for the given predictions. This eliminates/combines predictions that over...
Definition YOLOModel.hpp:71
void DrawDetections(cv::Mat &cvInputFrame, std::vector< Detection > &vObjects)
Given an image and a vector of object structs, draw each object bounding box, class type,...
Definition YOLOModel.hpp:109
This struct is used to.
Definition YOLOModel.hpp:45
This struct is used to store the dimensions of an output tensor for a yolo model.
Definition YOLOModel.hpp:189