MLECO-2492 Add CPP OD example with TFLITE-ArmnnDelegate
Signed-off-by: Dvir Markovich <dvir.markovich@arm.com>
Change-Id: If412c15ba49abe8370a570260b0a8ed8de305b7c
diff --git a/samples/ObjectDetection/test/delegate/ArmnnDelegateNetworkExecutorTest.cpp b/samples/ObjectDetection/test/delegate/ArmnnDelegateNetworkExecutorTest.cpp
new file mode 100644
index 0000000..4700660
--- /dev/null
+++ b/samples/ObjectDetection/test/delegate/ArmnnDelegateNetworkExecutorTest.cpp
@@ -0,0 +1,129 @@
+//
+// Copyright © 2022 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#include <catch.hpp>
+#include <opencv2/opencv.hpp>
+#include "ArmnnNetworkExecutor.hpp"
+#include "Types.hpp"
+#include "ImageUtils.hpp"
+#include "SSDResultDecoder.hpp"
+#include "YoloResultDecoder.hpp"
+
+using namespace std;
+
+static string GetResourceFilePath(const string& filename)
+{
+ string testResources = TEST_RESOURCE_DIR;
+
+ if(testResources.back() != '/')
+ {
+ return testResources + "/" + filename;
+ }
+ else
+ {
+ return testResources + filename;
+ }
+}
+
+TEST_CASE("Test Delegate Execution SSD_MOBILE")
+{
+ string testResources = TEST_RESOURCE_DIR;
+ REQUIRE(testResources != "");
+
+ vector<armnn::BackendId> m_backends = {"CpuRef"};
+ string file_path = GetResourceFilePath("ssd_mobilenet_v1.tflite");
+ common::InferenceResults<float> results;
+ cv::Mat processed;
+ cv::Mat cache;
+ float detectionThreshold = 0.6;
+ common::Profiling profiling(true);
+
+ profiling.ProfilingStart();
+ auto executor = make_unique<common::ArmnnNetworkExecutor<float>>(file_path, m_backends, true);
+ int width = executor->GetImageAspectRatio().m_Width;
+ int height = executor->GetImageAspectRatio().m_Height;
+ od::SSDResultDecoder ssdResult(detectionThreshold);
+
+ /* check GetInputDataType */
+ CHECK(executor->GetInputDataType() == armnn::DataType::QAsymmU8);
+ /* check GetImageAspectRatio */
+ CHECK(width == 300);
+ CHECK(height == 300);
+
+ cv::Mat inputFrame = cv::imread(GetResourceFilePath("basketball1.png"), cv::IMREAD_COLOR);
+ cv::cvtColor(inputFrame, inputFrame, cv::COLOR_BGR2RGB);
+ ResizeWithPad(inputFrame, processed, cache, common::Size(width,height));
+ CHECK(executor->Run(processed.data, processed.total() * processed.elemSize(), results) == true);
+ od::DetectedObjects detections = ssdResult.Decode(results,
+ common::Size(inputFrame.size().width, inputFrame.size().height),
+ common::Size(width, height), {});
+
+ /* Make sure we've found 2 persons in the image */
+ CHECK(detections.size() == 2 );
+ CHECK(detections[0].GetLabel() == "0");
+ CHECK(detections[1].GetLabel() == "0");
+ /* check GetQuantizationScale */
+ CHECK(to_string(executor->GetQuantizationScale()) == string("0.007812"));
+ /* check GetQuantizationOffset */
+ CHECK(executor->GetQuantizationOffset() == 128);
+ /* check GetQuantizationScale */
+ CHECK(executor->GetOutputQuantizationScale(0) == 0.0f);
+ /* check GetOutputQuantizationOffset */
+ CHECK(executor->GetOutputQuantizationOffset(0) == 0);
+ profiling.ProfilingStopAndPrintUs("Overall test");
+}
+
+TEST_CASE("Test Delegate Execution YOLO_V3")
+{
+ string testResources = TEST_RESOURCE_DIR;
+ REQUIRE(testResources != "");
+
+ vector<armnn::BackendId> m_backends = {"CpuRef"};
+ string file_path = GetResourceFilePath("yolo_v3_tiny_darknet_fp32.tflite");
+ common::InferenceResults<float> results;
+ cv::Mat processed;
+ cv::Mat cache;
+ float NMSThreshold = 0.3f;
+ float ClsThreshold = 0.3f;
+ float ObjectThreshold = 0.3f;
+
+
+ auto executor = make_unique<common::ArmnnNetworkExecutor<float>>(file_path, m_backends);
+ int width = executor->GetImageAspectRatio().m_Width;
+ int height = executor->GetImageAspectRatio().m_Height;
+ od::YoloResultDecoder yoloResult(NMSThreshold, ClsThreshold, ObjectThreshold);
+
+ /* check GetInputDataType */
+ CHECK(executor->GetInputDataType() == armnn::DataType::Float32);
+ /* check GetImageAspectRatio */
+ CHECK(width == 416);
+ CHECK(height == 416);
+
+ /* read the image */
+ cv::Mat inputFrame = cv::imread(GetResourceFilePath("basketball1.png"), cv::IMREAD_COLOR);
+ /* resize it according to the the input tensor requirments */
+ ResizeWithPad(inputFrame, processed, cache, common::Size(width,height));
+ /* converting to 3 channel matrix of 32 bits floats */
+ processed.convertTo(processed, CV_32FC3);
+ /* run the inference */
+ CHECK(executor->Run(processed.data, processed.total() * processed.elemSize(), results) == true);
+ /* decode the results */
+ od::DetectedObjects detections = yoloResult.Decode(results,
+ common::Size(inputFrame.size().width, inputFrame.size().height),
+ common::Size(width, height), {});
+
+ /* Make sure we've found 2 persons in the image */
+ CHECK(detections.size() == 2 );
+ CHECK(detections[0].GetLabel() == "0");
+ CHECK(detections[1].GetLabel() == "0");
+ /* check GetQuantizationScale */
+ CHECK(to_string(executor->GetQuantizationScale()) == string("0.000000"));
+ /* check GetQuantizationOffset */
+ CHECK(executor->GetQuantizationOffset() == 0);
+ /* check GetQuantizationScale */
+ CHECK(executor->GetOutputQuantizationScale(0) == 0.0f);
+ /* check GetOutputQuantizationOffset */
+ CHECK(executor->GetOutputQuantizationOffset(0) == 0);
+
+}