Given an input image forward the image through the YOLO model to run inference on the EdgeTPU, then parse and repackage the output tensor data into a vector of easy-to-use Detection structs.
273 {
274
275 std::vector<std::vector<Detection>> vTensorObjectOutputs;
276
277
278 InputTensorDimensions stInputDimensions = this->
GetInputShape(m_pInterpreter->inputs()[0]);
279
280
281 m_cvFrame = cvInputFrame;
282
283
284 if (m_bDeviceOpened && m_pEdgeTPUContext->IsReady())
285 {
286
287 if (m_cvFrame.
type() != CV_8UC3)
288 {
289
291 }
292
293
294 if (m_cvFrame.
rows != stInputDimensions.nHeight || m_cvFrame.
cols != stInputDimensions.nWidth)
295 {
296
298 m_cvFrame,
299 cv::Size(stInputDimensions.nWidth, stInputDimensions.nHeight),
300 constants::BASICCAM_RESIZE_INTERPOLATION_METHOD);
301 }
302
303
304 std::vector<int8_t> vInputData(m_cvFrame.
data,
305 m_cvFrame.
data + (
static_cast<unsigned long>(m_cvFrame.
cols) * m_cvFrame.
rows * m_cvFrame.
elemSize()));
306
307
308
309
310
311
312
313
314 TfLiteTensor* pInputTensor = m_pInterpreter->tensor(stInputDimensions.nTensorIndex);
315 std::memcpy(pInputTensor->data.raw, vInputData.data(), vInputData.size());
316
317
318 if (m_pInterpreter->Invoke() != kTfLiteOk)
319 {
320
321 LOG_WARNING(logging::g_qSharedLogger,
322 "Inferencing failed on an image for model {} with device {} ({})",
323 m_szModelPath,
324 m_tpuDevice.path,
325 this->DeviceTypeToString(m_tpuDevice.type));
326 }
327 else
328 {
329
330 std::vector<int> vClassIDs;
331 std::vector<float> vClassConfidences;
332 std::vector<cv::Rect> vBoundingBoxes;
333
334 std::vector<Detection> vObjects;
335
336
337 for (int nTensorIndex : m_pInterpreter->outputs())
338 {
339
340 vClassIDs.clear();
341 vClassConfidences.clear();
342 vBoundingBoxes.clear();
343
344 vObjects.clear();
345
346
347
348
349
350 OutputTensorDimensions stOutputDimensions = this->
GetOutputShape(nTensorIndex);
351
352 int nImgSize = stInputDimensions.nHeight;
353 int nP3Stride = std::pow((nImgSize / 8), 2);
354 int nP4Stride = std::pow((nImgSize / 16), 2);
355 int nP5Stride = std::pow((nImgSize / 32), 2);
356
357 int nYOLOv5AnchorsPerGridPoint = 3;
358 int nYOLOv8AnchorsPerGridPoint = 1;
359 int nYOLOv5TotalPredictionLength =
360 (nP3Stride * nYOLOv5AnchorsPerGridPoint) + (nP4Stride * nYOLOv5AnchorsPerGridPoint) + (nP5Stride * nYOLOv5AnchorsPerGridPoint);
361 int nYOLOv8TotalPredictionLength =
362 (nP3Stride * nYOLOv8AnchorsPerGridPoint) + (nP4Stride * nYOLOv8AnchorsPerGridPoint) + (nP5Stride * nYOLOv8AnchorsPerGridPoint);
363
364
365 if (stOutputDimensions.nAnchors == nYOLOv5TotalPredictionLength)
366 {
367
369 vClassIDs,
370 vClassConfidences,
371 vBoundingBoxes,
372 fMinObjectConfidence,
375 }
376
377 else if (stOutputDimensions.nAnchors == nYOLOv8TotalPredictionLength)
378 {
379
381 vClassIDs,
382 vClassConfidences,
383 vBoundingBoxes,
384 fMinObjectConfidence,
387 }
388
389
390 NonMaxSuppression(vObjects, vClassIDs, vClassConfidences, vBoundingBoxes, fMinObjectConfidence, fNMSThreshold);
391
392
393 vTensorObjectOutputs.emplace_back(vObjects);
394 }
395 }
396 }
397 else
398 {
399
400 LOG_WARNING(logging::g_qSharedLogger,
401 "Inferencing failed on an image for model {} with device {} ({})",
402 m_szModelPath,
403 m_tpuDevice.path,
404 this->DeviceTypeToString(m_tpuDevice.type));
405 }
406
407 return vTensorObjectOutputs;
408 }
void convertTo(OutputArray m, int rtype, double alpha=1, double beta=0) const
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:652
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:615
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:441
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:537
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:67