tools: Add metadata class to correspond to multiple output layers 54/268454/9
authorHyunsoo Park <hance.park@samsung.com>
Fri, 17 Dec 2021 07:49:05 +0000 (16:49 +0900)
committerHyunsoo Park <hance.park@samsung.com>
Mon, 3 Jan 2022 02:06:42 +0000 (11:06 +0900)
[Version] 0.2.2-0
[Issue Type] Update feature

Change-Id: I91cd820a301e142c5878706593ff12bf2608c939
Signed-off-by: Hyunsoo Park <hance.park@samsung.com>
packaging/inference-engine-interface.spec
tools/include/OutputMetadata.h
tools/src/InputMetadata.cpp
tools/src/OutputMetadata.cpp
tools/src/inference_engine_cltuner.cpp

index 6b32047b2725783688fc219223b606e2213e0391..faced4f9669c2e794dc4683f6151d7b4ce264391 100644 (file)
@@ -1,6 +1,6 @@
 Name:        inference-engine-interface
 Summary:     Interface of inference engines
-Version:     0.3.0
+Version:     0.3.1
 Release:     0
 Group:       Multimedia/Framework
 License:     Apache-2.0
index 5d242aa44e4848fcedf1ab840457c6c5d05fb7fc..92f4b85b0eb4f81f9425546525666af085467b0d 100644 (file)
 #ifndef __INFERENCE_ENGINE_OUTPUTMETADATA_H__
 #define __INFERENCE_ENGINE_OUTPUTMETADATA_H__
 
-#include <string>
-#include <vector>
 #include <map>
 #include <memory>
+#include <string>
+#include <vector>
 
-#include <dlog.h>
+#include "inference_engine_error.h"
 #include "inference_engine_private_type.h"
 #include "inference_engine_type.h"
-#include "inference_engine_error.h"
+#include <dlog.h>
 
-#include <json-glib/json-glib.h>
 #include "OutputMetadataTypes.h"
+#include <json-glib/json-glib.h>
 
 /**
  * @file OutputMetadata.h
@@ -88,13 +88,179 @@ namespace Cltuner
                int ParseScore(JsonObject *root);
        };
 
+       class BoxInfo
+       {
+       private:
+               std::string name;
+               DimInfo dimInfo;
+               inference_box_type_e type;
+               std::vector<int> order;
+               inference_box_coordinate_type_e coordinate;
+               inference_box_decoding_type_e decodingType;
+
+               std::map<std::string, inference_box_type_e> supportedBoxTypes;
+               std::map<std::string, inference_box_coordinate_type_e> supportedBoxCoordinateTypes;
+               std::map<std::string, inference_box_decoding_type_e> supportedBoxDecodingTypes;
+
+       public:
+               BoxInfo();
+               ~BoxInfo() = default;
+
+               std::string GetName() { return name; }
+               DimInfo GetDimInfo() { return dimInfo; }
+               inference_box_type_e GetType() { return type; }
+               inference_box_decoding_type_e GetDecodingType() { return decodingType; }
+               std::vector<int> GetOrder() { return order; }
+               int GetCoordinate() { return coordinate; }
+
+               int ParseBox(JsonObject *root);
+       };
+
+       class Label
+       {
+       private:
+               std::string name;
+               DimInfo dimInfo;
+               inference_box_decoding_type_e decodingType;
+
+       public:
+               Label() = default;
+               ~Label() = default;
+               std::string GetName() { return name; }
+               DimInfo GetDimInfo() { return dimInfo; }
+
+               int ParseLabel(JsonObject *root);
+       };
+
+       class Number
+       {
+       private:
+               std::string name;
+               DimInfo dimInfo;
+
+       public:
+               Number() = default;
+               ~Number() = default;
+               std::string GetName() { return name; }
+               DimInfo GetDimInfo() { return dimInfo; }
+
+               int ParseNumber(JsonObject *root);
+       };
+
+       class Landmark
+       {
+       public:
+               class DecodeInfo {
+               public:
+                       class HeatMapInfo {
+                       public:
+                               int wIdx;
+                               int hIdx;
+                               int cIdx;
+                               inference_tensor_shape_type_e shapeType;
+                               float nmsRadius;
+                               HeatMapInfo() = default;
+                               ~HeatMapInfo() = default;
+                       };
+                       HeatMapInfo heatMap;
+                       DecodeInfo() = default;
+                       ~DecodeInfo() = default;
+               };
+       private:
+               std::string name;
+               DimInfo dimInfo;
+               inference_landmark_type_e type;
+               int offset;
+               inference_landmark_coorindate_type_e coordinate;
+               inference_landmark_decoding_type_e decodingType;
+               DecodeInfo decodingInfo;
+
+               std::map<std::string, inference_landmark_type_e> supportedLandmarkTypes;
+               std::map<std::string, inference_landmark_coorindate_type_e> supportedLandmarkCoordinateTypes;
+               std::map<std::string, inference_landmark_decoding_type_e> supportedLandmarkDecodingTypes;
+
+       public:
+               Landmark();
+               ~Landmark() = default;
+               std::string GetName() { return name; }
+               DimInfo GetDimInfo() { return dimInfo; }
+               inference_landmark_type_e GetType();
+               int GetOffset();
+               inference_landmark_coorindate_type_e GetCoordinate();
+               inference_landmark_decoding_type_e GetDecodingType();
+               DecodeInfo& GetDecodingInfo();
+
+               int ParseLandmark(JsonObject *root);
+       };
+
+       class OffsetVec
+       {
+       private:
+               std::string name;
+               DimInfo dimInfo;
+               int shapeType;
+       public:
+               OffsetVec() = default;
+               ~OffsetVec() = default;
+               std::string GetName() { return name; }
+               DimInfo GetDimInfo() { return dimInfo; }
+               int GetShapeType() { return shapeType; }
+
+               int ParseOffset(JsonObject *root);
+       };
+
+       class DispVec
+       {
+       private:
+               std::string name;
+               DimInfo dimInfo;
+               inference_displacement_type_e type;
+               int shapeType;
+               std::map<std::string, inference_displacement_type_e> supportedDispTypes;
+       public:
+               DispVec();
+               ~DispVec() = default;
+               std::string GetName() { return name; }
+               DimInfo GetDimInfo() { return dimInfo; }
+               inference_displacement_type_e GetType() { return type; }
+               int GetShapeType() { return shapeType; }
+
+               int ParseDisplacement(JsonObject *root);
+       };
+
+       class Edge
+       {
+       private:
+               std::vector<std::pair<int, int>> edges;
+       public:
+               Edge() = default;
+               ~Edge() = default;
+               int ParseEdge(JsonObject *root);
+               std::vector<std::pair<int, int>>& GetEdgesAll();
+       };
+
        class OutputMetadata
        {
        private:
                bool parsed;
                ScoreInfo score;
+               BoxInfo box;
+               Label label;
+               Number number;
+               Landmark landmark;
+               OffsetVec offsetVec;
+               std::vector<DispVec> dispVecs;
+               Edge edgeMap;
 
                int ParseScore(JsonObject *root);
+               int ParseBox(JsonObject *root);
+               int ParseLabel(JsonObject *root);
+               int ParseNumber(JsonObject *root);
+               int ParseLandmark(JsonObject *root);
+               int ParseLandmarkDecodeInfo(JsonObject *root);
+               int ParseOffset(JsonObject *root);
+               int ParseDisplacement(JsonObject *root);
+               int ParseEdgeMap(JsonObject *root);
 
        public:
                static std::map<std::string, inference_tensor_shape_type_e> supportedTensorShapes;
@@ -121,6 +287,13 @@ namespace Cltuner
 
                bool IsParsed();
                ScoreInfo& GetScore();
+               BoxInfo& GetBox();
+               Label& GetLabel();
+               Number& GetNumber();
+               Landmark& GetLandmark();
+               OffsetVec& GetOffset();
+               std::vector<DispVec>& GetDispVecAll();
+
                template <typename T>
                static T GetSupportedType(JsonObject* root, std::string typeName,
                                                                std::map<std::string, T>& supportedTypes);
index d4c3c5d4a223ac31cdefc3422a957dbe80af7551..5a71e502115139fd0afad520d48d2de8d5336400 100644 (file)
@@ -89,7 +89,7 @@ namespace Cltuner
                        JsonObject *pObject = json_node_get_object(pNode);
 
                        info.name =
-                                       static_cast<const char*>(json_object_get_string_member(pObject,"name"));
+                                       static_cast<const char*>(json_object_get_string_member(pObject, "name"));
                        LOGI("layer: %s", info.name.c_str());
 
                        try {
index 5f0f0a2d10033fd7ef061f9e208c080fa11cd062..b11aea17361e1814609efc5f5f94e835b6279fe9 100755 (executable)
  * limitations under the License.
  */
 
-#include <unistd.h>
+#include "OutputMetadata.h"
+#include <algorithm>
 #include <fstream>
-#include <string>
 #include <queue>
-#include <algorithm>
-#include "OutputMetadata.h"
+#include <string>
+#include <unistd.h>
+
+extern "C"
+{
 
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define MAX_STR 256
+#define LOG_TAG "INFERENCE_ENGINE_CLTUNER"
+}
 namespace InferenceEngineInterface
 {
 namespace Cltuner
@@ -73,7 +82,7 @@ namespace Cltuner
                        JsonNode *pNode = json_array_get_element(rootArray, elem);
                        JsonObject *pObject = json_node_get_object(pNode);
 
-                       name = json_object_get_string_member(pObject,"name");
+                       name = json_object_get_string_member(pObject, "name");
                        LOGI("layer: %s", name.c_str());
 
                        JsonArray * array = json_object_get_array_member(pObject, "index");
@@ -122,48 +131,629 @@ namespace Cltuner
                return score.ParseScore(root);
        }
 
+       int OutputMetadata::Parse(JsonObject *root)
+       {
+               LOGI("ENTER");
+
+               int ret = ParseScore(root);
+               if (ret != INFERENCE_ENGINE_ERROR_NONE) {
+                       LOGE("Fail to ParseScore[%d]", ret);
+                       return ret;
+               }
+
+               ret = ParseBox(root);
+               if (ret != INFERENCE_ENGINE_ERROR_NONE) {
+                       LOGE("Fail to ParseBox[%d]", ret);
+                       return ret;
+               }
+
+               if (!box.GetName().empty()) {
+                       // addtional parsing is required according to decoding type
+
+                       switch (box.GetDecodingType()) {
+                               case INFERENCE_BOX_DECODING_TYPE_BYPASS:
+                                       ret = ParseLabel(root);
+                                       if (ret != INFERENCE_ENGINE_ERROR_NONE) {
+                                               LOGE("Fail to ParseLabel[%d]", ret);
+                                               return ret;
+                                       }
+
+                                       ret = ParseNumber(root);
+                                       if (ret != INFERENCE_ENGINE_ERROR_NONE) {
+                                               LOGE("Fail to ParseNumber[%d]", ret);
+                                               return ret;
+                                       }
+
+                                       break;
+                               case INFERENCE_BOX_DECODING_TYPE_SSD_ANCHOR:
+                                       LOGW("Not support because of OpenCV dependency. Ignore");
+                                       break;
+                               default:
+                                       LOGW("Unknown box decoding type. Ignore");
+                       }
+               }
+
+               ret = ParseLandmark(root);
+               if (ret != INFERENCE_ENGINE_ERROR_NONE) {
+                       LOGE("Fail to GetLandmark[%d]", ret);
+                       return ret;
+               }
+
+               if (!landmark.GetName().empty()) {
+                       switch (landmark.GetDecodingType()) {
+                               case INFERENCE_LANDMARK_DECODING_TYPE_BYPASS:
+                                       ret = ParseLandmarkDecodeInfo(root);
+                                       if (ret != INFERENCE_ENGINE_ERROR_NONE) {
+                                               LOGE("Fail to ParseLandmarkDecodeInfo[%d]", ret);
+                                               return ret;
+                                       }
+
+                                       break;
+                               case INFERENCE_LANDMARK_DECODING_TYPE_HEATMAP_REFINE:
+                                       ret = ParseOffset(root);
+                                       if (ret != INFERENCE_ENGINE_ERROR_NONE) {
+                                               LOGE("Fail to ParseOffset[%d]", ret);
+                                               return ret;
+                                       }
+
+                                       ret = ParseDisplacement(root);
+                                       if (ret != INFERENCE_ENGINE_ERROR_NONE) {
+                                               LOGE("Fail to ParseDisplacement[%d]", ret);
+                                               return ret;
+                                       }
+
+                                       ret = ParseEdgeMap(root);
+                                       if (ret != INFERENCE_ENGINE_ERROR_NONE) {
+                                               LOGE("Fail to ParseEdgeMap[%d]", ret);
+                                               return ret;
+                                       }
+
+                                       break;
+                               default:
+                                       LOGW("Unknown landmark decoding type. Ignore");
+                       }
+               }
+               parsed = true;
+
+               LOGI("LEAVE");
+
+               return INFERENCE_ENGINE_ERROR_NONE;
+       }
+
+       void DimInfo::SetValidIndex(int index)
+       {
+               LOGI("ENTER");
+
+               dims.push_back(index);
+
+               LOGI("LEAVE");
+       }
+
+       std::vector<int> DimInfo::GetValidIndexAll() const
+       {
+               LOGI("ENTER");
+
+               LOGI("LEAVE");
+               return dims;
+       }
+
+       BoxInfo::BoxInfo() :
+                       name(),
+                       dimInfo(),
+                       type(INFERENCE_BOX_TYPE_ORIGIN_LEFTTOP),
+                       order(),
+                       coordinate(INFERENCE_BOX_COORDINATE_TYPE_RATIO),
+                       decodingType(INFERENCE_BOX_DECODING_TYPE_BYPASS)
+       {
+               supportedBoxTypes.insert({"ORIGIN_LEFTTOP", INFERENCE_BOX_TYPE_ORIGIN_LEFTTOP});
+               supportedBoxTypes.insert({"ORIGIN_CENTER", INFERENCE_BOX_TYPE_ORIGIN_CENTER});
+
+               supportedBoxCoordinateTypes.insert({"RATIO", INFERENCE_BOX_COORDINATE_TYPE_RATIO});
+               supportedBoxCoordinateTypes.insert({"PIXEL", INFERENCE_BOX_COORDINATE_TYPE_PIXEL});
+
+               supportedBoxDecodingTypes.insert({"BYPASS", INFERENCE_BOX_DECODING_TYPE_BYPASS});
+               supportedBoxDecodingTypes.insert({"SSD_ANCHOR", INFERENCE_BOX_DECODING_TYPE_SSD_ANCHOR});
+       }
+
+       int BoxInfo::ParseBox(JsonObject *root)
+       {
+               LOGI("ENTER");
+
+               JsonArray * rootArray = json_object_get_array_member(root, "box");
+               unsigned int elements = json_array_get_length(rootArray);
+
+               for (unsigned int elem = 0; elem < elements; ++elem) {
+                       JsonNode *pNode = json_array_get_element(rootArray, elem);
+                       JsonObject *pObject = json_node_get_object(pNode);
+
+                       name = json_object_get_string_member(pObject, "name");
+                       LOGI("layer: %s", name.c_str());
+
+                       JsonArray * array = json_object_get_array_member(pObject, "index");
+                       unsigned int elements2 = json_array_get_length(array);
+                       LOGI("range dim: size[%u]", elements2);
+                       for (unsigned int elem2 = 0; elem2 < elements2; ++elem2) {
+                               if (static_cast<int>(json_array_get_int_element(array, elem2)) == 1)
+                                       dimInfo.SetValidIndex(elem2);
+                       }
+
+                       try {
+                               type = OutputMetadata::GetSupportedType(pObject, "box_type", supportedBoxTypes);
+                               coordinate = OutputMetadata::GetSupportedType(pObject, "box_coordinate", supportedBoxCoordinateTypes);
+                               decodingType = OutputMetadata::GetSupportedType(pObject, "decoding_type", supportedBoxDecodingTypes);
+                       } catch (const std::exception& e) {
+                               LOGE("Invalid %s", e.what());
+                               return INFERENCE_ENGINE_ERROR_INVALID_OPERATION;
+                       }
+
+                       array = json_object_get_array_member(pObject, "box_order");
+                       elements2 = json_array_get_length(array);
+                       LOGI("box order should have 4 elements and it has [%u]", elements2);
+                       for (unsigned int elem2 = 0; elem2 < elements2; ++elem2) {
+                               auto val = static_cast<int>(json_array_get_int_element(array, elem2));
+                               order.push_back(val);
+                               LOGI("%d", val);
+                       }
+               }
+
+               LOGI("LEAVE");
+               return INFERENCE_ENGINE_ERROR_NONE;
+       }
+
+       int OutputMetadata::ParseBox(JsonObject *root)
+       {
+               if (!json_object_has_member(root, "box")) {
+                       LOGE("No box outputmetadata");
+                       return INFERENCE_ENGINE_ERROR_NONE;
+               }
+
+               return box.ParseBox(root);
+       }
+
+       int Label::ParseLabel(JsonObject *root)
+       {
+               LOGI("ENTER");
+
+               JsonArray * rootArray = json_object_get_array_member(root, "label");
+               unsigned int elements = json_array_get_length(rootArray);
+
+               // TODO: handling error
+               for (unsigned int elem = 0; elem < elements; ++elem) {
+                       JsonNode *pNode = json_array_get_element(rootArray, elem);
+                       JsonObject *pObject = json_node_get_object(pNode);
+
+                       name = json_object_get_string_member(pObject, "name");
+                       LOGI("layer: %s", name.c_str());
+
+                       JsonArray * array = json_object_get_array_member(pObject, "index");
+                       unsigned int elements2 = json_array_get_length(array);
+                       LOGI("range dim: size[%u]", elements2);
+                       for (unsigned int elem2 = 0; elem2 < elements2; ++elem2) {
+                               if (static_cast<int>(json_array_get_int_element(array, elem2)) == 1)
+                                       dimInfo.SetValidIndex(elem2);
+                       }
+               }
+
+               LOGI("LEAVE");
+               return INFERENCE_ENGINE_ERROR_NONE;
+       }
+
+       int OutputMetadata::ParseLabel(JsonObject *root)
+       {
+               LOGI("ENTER");
+
+               if (!json_object_has_member(root, "label")) {
+                       LOGE("No box outputmetadata");
+                       LOGI("LEAVE");
+                       return INFERENCE_ENGINE_ERROR_INVALID_OPERATION;
+               }
+
+               label.ParseLabel(root);
+
+               LOGI("LEAVE");
+               return INFERENCE_ENGINE_ERROR_NONE;
+       }
+
+       int Number::ParseNumber(JsonObject *root)
+       {
+               // box
+               JsonArray * rootArray = json_object_get_array_member(root, "number");
+               unsigned int elements = json_array_get_length(rootArray);
+
+               // TODO: handling error
+               for (unsigned int elem = 0; elem < elements; ++elem) {
+                       JsonNode *pNode = json_array_get_element(rootArray, elem);
+                       JsonObject *pObject = json_node_get_object(pNode);
+
+                       name = json_object_get_string_member(pObject, "name");
+                       LOGI("layer: %s", name.c_str());
+
+                       JsonArray * array = json_object_get_array_member(pObject, "index");
+                       unsigned int elements2 = json_array_get_length(array);
+                       LOGI("range dim: size[%u]", elements2);
+                       for (unsigned int elem2 = 0; elem2 < elements2; ++elem2) {
+                               if (static_cast<int>(json_array_get_int_element(array, elem2)) == 1)
+                                       dimInfo.SetValidIndex(elem2);
+                       }
+               }
+
+               return INFERENCE_ENGINE_ERROR_NONE;
+       }
+
+       int OutputMetadata::ParseNumber(JsonObject *root)
+       {
+               LOGI("ENTER");
+
+               if (!json_object_has_member(root, "number")) {
+                       LOGE("No number outputmetadata");
+                       LOGI("LEAVE");
+                       return INFERENCE_ENGINE_ERROR_INVALID_OPERATION;
+               }
+               number.ParseNumber(root);
+
+               LOGI("LEAVE");
+               return INFERENCE_ENGINE_ERROR_NONE;
+       }
+
+       int Edge::ParseEdge(JsonObject *root)
+       {
+               LOGI("ENTER");
+               JsonArray * rootArray = json_object_get_array_member(root, "edgemap");
+               unsigned int elements = json_array_get_length(rootArray);
+
+               // TODO: handling error
+               int pEdgeNode, cEdgeNode;
+               for (unsigned int elem = 0; elem < elements; ++elem) {
+
+                       JsonNode *pNode = json_array_get_element(rootArray, elem);
+                       JsonObject *pObject = json_node_get_object(pNode);
+
+                       pEdgeNode = json_object_get_int_member(pObject, "parent");
+                       cEdgeNode = json_object_get_int_member(pObject, "child");
+
+                       edges.push_back(std::make_pair(pEdgeNode, cEdgeNode));
+                       LOGI("%ud: parent - child: %d - %d", elem, pEdgeNode, cEdgeNode);
+               }
+               LOGI("LEAVE");
+               return INFERENCE_ENGINE_ERROR_NONE;
+       }
+
+       int OutputMetadata::ParseEdgeMap(JsonObject * root)
+       {
+               LOGI("ENTER");
+
+               if (!json_object_has_member(root, "edgemap")) {
+                       LOGI("No edgemap outputmetadata");
+                       LOGI("LEAVE");
+                       return INFERENCE_ENGINE_ERROR_INVALID_OPERATION;
+               }
+
+               edgeMap.ParseEdge(root);
+
+               LOGI("LEAVE");
+               return INFERENCE_ENGINE_ERROR_NONE;
+       }
+
        ScoreInfo& OutputMetadata::GetScore()
        {
                return score;
        }
 
+       BoxInfo& OutputMetadata::GetBox()
+       {
+               return box;
+       }
+
+       Label& OutputMetadata::GetLabel()
+       {
+               return label;
+       }
+
+       Number& OutputMetadata::GetNumber()
+       {
+               return number;
+       }
+
+       Landmark& OutputMetadata::GetLandmark()
+       {
+               return landmark;
+       }
+
+       OffsetVec& OutputMetadata::GetOffset()
+       {
+               return offsetVec;
+       }
+
+       std::vector<DispVec>& OutputMetadata::GetDispVecAll()
+       {
+               return dispVecs;
+       }
+
        bool OutputMetadata::IsParsed()
        {
                return parsed;
        }
 
-       int OutputMetadata::Parse(JsonObject *root)
+       Landmark::Landmark() :
+                       name(),
+                       dimInfo(),
+                       type(INFERENCE_LANDMARK_TYPE_2D_SINGLE),
+                       offset(),
+                       coordinate(INFERENCE_LANDMARK_COORDINATE_TYPE_RATIO),
+                       decodingType(INFERENCE_LANDMARK_DECODING_TYPE_BYPASS),
+                       decodingInfo()
+
+       {
+               supportedLandmarkTypes.insert({"2D_SINGLE", INFERENCE_LANDMARK_TYPE_2D_SINGLE});
+               supportedLandmarkTypes.insert({"2D_MULTI",  INFERENCE_LANDMARK_TYPE_2D_MULTI});
+               supportedLandmarkTypes.insert({"3D_SINGLE", INFERENCE_LANDMARK_TYPE_3D_SINGLE});
+
+               supportedLandmarkCoordinateTypes.insert({"RATIO", INFERENCE_LANDMARK_COORDINATE_TYPE_RATIO});
+               supportedLandmarkCoordinateTypes.insert({"PIXEL", INFERENCE_LANDMARK_COORDINATE_TYPE_PIXEL});
+
+               supportedLandmarkDecodingTypes.insert({"BYPASS", INFERENCE_LANDMARK_DECODING_TYPE_BYPASS});
+               supportedLandmarkDecodingTypes.insert({"HEATMAP", INFERENCE_LANDMARK_DECODING_TYPE_HEATMAP});
+               supportedLandmarkDecodingTypes.insert({"HEATMAP_REFINE", INFERENCE_LANDMARK_DECODING_TYPE_HEATMAP_REFINE});
+       }
+
+       int Landmark::ParseLandmark(JsonObject *root)
+       {
+               // box
+               JsonArray * rootArray = json_object_get_array_member(root, "landmark");
+               unsigned int elements = json_array_get_length(rootArray);
+
+               // TODO: handling error
+               for (unsigned int elem = 0; elem < elements; ++elem) {
+
+                       JsonNode *pNode = json_array_get_element(rootArray, elem);
+                       JsonObject *pObject = json_node_get_object(pNode);
+
+                       name =
+                               static_cast<const char*>(json_object_get_string_member(pObject, "name"));
+                       LOGI("layer: %s", name.c_str());
+
+                       JsonArray * array = json_object_get_array_member(pObject, "index");
+                       unsigned int elements2 = json_array_get_length(array);
+                       LOGI("range dim: size[%u]", elements2);
+                       for (unsigned int elem2 = 0; elem2 < elements2; ++elem2) {
+                               if (static_cast<int>(json_array_get_int_element(array, elem2)) == 1)
+                                       dimInfo.SetValidIndex(elem2);
+                       }
+
+                       try {
+                               type = OutputMetadata::GetSupportedType(pObject, "landmark_type", supportedLandmarkTypes);
+                               coordinate = OutputMetadata::GetSupportedType(pObject, "landmark_coordinate", supportedLandmarkCoordinateTypes);
+                               decodingType = OutputMetadata::GetSupportedType(pObject, "decoding_type", supportedLandmarkDecodingTypes);
+                       } catch (const std::exception& e) {
+                               LOGE("Invalid %s", e.what());
+                               return INFERENCE_ENGINE_ERROR_INVALID_OPERATION;
+                       }
+
+                       offset = static_cast<int>(json_object_get_int_member(pObject, "landmark_offset"));
+                       LOGI("landmark offset: %d", offset);
+               }
+
+               LOGI("LEAVE");
+               return INFERENCE_ENGINE_ERROR_NONE;
+       }
+
+       inference_landmark_type_e Landmark::GetType()
+       {
+               return type;
+       }
+
+       int Landmark::GetOffset()
+       {
+               return offset;
+       }
+
+       inference_landmark_coorindate_type_e Landmark::GetCoordinate()
+       {
+               return coordinate;
+       }
+
+       inference_landmark_decoding_type_e Landmark::GetDecodingType()
+       {
+               return decodingType;
+       }
+
+       Landmark::DecodeInfo& Landmark::GetDecodingInfo()
+       {
+               return decodingInfo;
+       }
+
+       int OutputMetadata::ParseLandmark(JsonObject *root)
        {
                LOGI("ENTER");
 
-               int ret = ParseScore(root);
-               if (ret != INFERENCE_ENGINE_ERROR_NONE) {
-                       LOGE("Fail to GetScore[%d]", ret);
-                       return ret;
+               if (!json_object_has_member(root, "landmark")) {
+                       LOGI("No landmark outputmetadata");
+                       LOGI("LEAVE");
+                       return INFERENCE_ENGINE_ERROR_NONE;
                }
 
-               parsed = true;
+               landmark.ParseLandmark(root);
 
                LOGI("LEAVE");
+               return INFERENCE_ENGINE_ERROR_NONE;
+       }
+
+       int OutputMetadata::ParseLandmarkDecodeInfo(JsonObject *root)
+       {
+               LOGI("ENTER");
 
+               if (!json_object_has_member(root, "landmark")) {
+                       LOGI("No landmark outputmetadata");
+                       LOGI("LEAVE");
+                       return INFERENCE_ENGINE_ERROR_NONE;
+               }
+
+               // box
+               JsonArray * rootArray = json_object_get_array_member(root, "landmark");
+               unsigned int elements = json_array_get_length(rootArray);
+
+               // TODO: handling error
+               for (unsigned int elem = 0; elem < elements; ++elem) {
+
+                       JsonNode *pNode = json_array_get_element(rootArray, elem);
+                       JsonObject *pObject = json_node_get_object(pNode);
+
+                       if (!json_object_has_member(pObject, "decoding_info")) {
+                               LOGE("decoding_info is mandatory. Invalid metadata");
+                               LOGI("LEAVE");
+
+                               return INFERENCE_ENGINE_ERROR_INVALID_OPERATION;
+                       }
+
+                       JsonObject *cObject = json_object_get_object_member(pObject, "decoding_info");
+                       if (!json_object_has_member(cObject, "heatmap")) {
+                               LOGE("heatmap is mandatory. Invalid metadata");
+                               LOGI("LEAVE");
+
+                               return INFERENCE_ENGINE_ERROR_INVALID_OPERATION;
+                       }
+
+                       JsonObject *object = json_object_get_object_member(cObject, "heatmap") ;
+                       try {
+                               landmark.GetDecodingInfo().heatMap.shapeType = OutputMetadata::GetSupportedType(object, "shape_type", supportedTensorShapes);
+                       } catch (const std::exception& e) {
+                               LOGE("Invalid %s", e.what());
+                               return INFERENCE_ENGINE_ERROR_INVALID_OPERATION;
+                       }
+
+                       std::vector<int> heatMapIndexes = landmark.GetDimInfo().GetValidIndexAll();
+                       if (landmark.GetDecodingInfo().heatMap.shapeType == INFERENCE_TENSOR_SHAPE_NCHW) {
+                               landmark.GetDecodingInfo().heatMap.cIdx = heatMapIndexes[0];
+                               landmark.GetDecodingInfo().heatMap.hIdx = heatMapIndexes[1];
+                               landmark.GetDecodingInfo().heatMap.wIdx = heatMapIndexes[2];
+                       } else {
+                               landmark.GetDecodingInfo().heatMap.hIdx = heatMapIndexes[0];
+                               landmark.GetDecodingInfo().heatMap.wIdx = heatMapIndexes[1];
+                               landmark.GetDecodingInfo().heatMap.cIdx = heatMapIndexes[2];
+                       }
+
+                       if (json_object_has_member(object, "nms_radius")) {
+                               landmark.GetDecodingInfo().heatMap.nmsRadius = static_cast<float>(json_object_get_double_member(object, "nms_radius"));
+                               LOGI("nms is enabled with %3.f", landmark.GetDecodingInfo().heatMap.nmsRadius );
+                       }
+               }
+
+               LOGI("LEAVE");
                return INFERENCE_ENGINE_ERROR_NONE;
        }
 
-       void DimInfo::SetValidIndex(int index)
+       int OffsetVec::ParseOffset(JsonObject *root)
+       {
+               JsonArray * rootArray = json_object_get_array_member(root, "offset");
+               unsigned int elements = json_array_get_length(rootArray);
+
+               // TODO: handling error
+               for (unsigned int elem = 0; elem < elements; ++elem) {
+
+                       JsonNode *pNode = json_array_get_element(rootArray, elem);
+                       JsonObject *pObject = json_node_get_object(pNode);
+
+                       name =
+                               static_cast<const char*>(json_object_get_string_member(pObject, "name"));
+                       LOGI("layer: %s", name.c_str());
+
+                       JsonArray * array = json_object_get_array_member(pObject, "index");
+                       unsigned int elements2 = json_array_get_length(array);
+                       LOGI("range dim: size[%u]", elements2);
+                       for (unsigned int elem2 = 0; elem2 < elements2; ++elem2) {
+                               if (static_cast<int>(json_array_get_int_element(array, elem2)) == 1)
+                                       dimInfo.SetValidIndex(elem2);
+                       }
+
+                       try {
+                               shapeType = OutputMetadata::GetSupportedType(pObject, "shape_type", OutputMetadata::supportedTensorShapes);
+                       } catch (const std::exception& e) {
+                               LOGE("Invalid %s", e.what());
+                               return INFERENCE_ENGINE_ERROR_INVALID_OPERATION;
+                       }
+
+               }
+
+               LOGI("LEAVE");
+               return INFERENCE_ENGINE_ERROR_NONE;
+       }
+
+       int OutputMetadata::ParseOffset(JsonObject *root)
        {
                LOGI("ENTER");
 
-               dims.push_back(index);
+               if (!json_object_has_member(root, "offset")) {
+                       LOGI("No offset outputmetadata");
+                       LOGI("LEAVE");
+                       return INFERENCE_ENGINE_ERROR_INVALID_OPERATION;
+               }
+
+               offsetVec.ParseOffset(root);
 
                LOGI("LEAVE");
+               return INFERENCE_ENGINE_ERROR_NONE;
        }
 
-       std::vector<int> DimInfo::GetValidIndexAll() const
+       DispVec::DispVec() :
+                       name(),
+                       dimInfo(),
+                       type(INFERENCE_DISPLACEMENT_TYPE_FORWARD),
+                       shapeType(INFERENCE_TENSOR_SHAPE_NCHW)
+       {
+               supportedDispTypes.insert({"FORWARD", INFERENCE_DISPLACEMENT_TYPE_FORWARD});
+               supportedDispTypes.insert({"BACKWARD", INFERENCE_DISPLACEMENT_TYPE_BACKWARD});
+       }
+
+       int DispVec::ParseDisplacement(JsonObject *root)
        {
                LOGI("ENTER");
+               name =
+                       static_cast<const char*>(json_object_get_string_member(root, "name"));
+               LOGI("layer: %s", name.c_str());
+
+               JsonArray * array = json_object_get_array_member(root, "index");
+               unsigned int elements2 = json_array_get_length(array);
+               LOGI("range dim: size[%u]", elements2);
+               for (unsigned int elem2 = 0; elem2 < elements2; ++elem2) {
+                       if(static_cast<int>(json_array_get_int_element(array, elem2)) == 1)
+                               dimInfo.SetValidIndex(elem2);
+               }
+
+               try {
+                       shapeType = OutputMetadata::GetSupportedType(root, "shape_type", OutputMetadata::supportedTensorShapes);
+                       type = OutputMetadata::GetSupportedType(root, "type", supportedDispTypes);
+               } catch (const std::exception& e) {
+                       LOGE("Invalid %s", e.what());
+                       return INFERENCE_ENGINE_ERROR_INVALID_OPERATION;
+               }
 
                LOGI("LEAVE");
-               return dims;
+               return INFERENCE_ENGINE_ERROR_NONE;
+       }
+
+       int OutputMetadata::ParseDisplacement(JsonObject *root)
+       {
+               LOGI("ENTER");
+
+               if (!json_object_has_member(root, "displacement")) {
+                       LOGI("No displacement outputmetadata");
+                       LOGI("LEAVE");
+                       return INFERENCE_ENGINE_ERROR_INVALID_OPERATION;
+               }
+
+               JsonArray * rootArray = json_object_get_array_member(root, "displacement");
+               unsigned int elements = json_array_get_length(rootArray);
+
+               dispVecs.resize(elements);
+               unsigned int elem = 0;
+               for (auto& disp : dispVecs) {
+                       JsonNode *pNode = json_array_get_element(rootArray, elem++);
+                       JsonObject *pObject = json_node_get_object(pNode);
+                       disp.ParseDisplacement(pObject);
+               }
+
+               LOGI("LEAVE");
+               return INFERENCE_ENGINE_ERROR_NONE;
        }
 } /* Inference */
 } /* MediaVision */
index 277dd770971659716f589ecf4f16b43a83e470e4..ee9b0ebf543f9d78e8fb025700a1b86125551717 100644 (file)
@@ -138,7 +138,30 @@ int ConfigureOutputInfo(InferenceEngineCommon* backend, Metadata& metadata,
        tensorConfig.mOutputLayerNames.clear();
        if (!outputMeta.GetScore().GetName().empty())
                tensorConfig.mOutputLayerNames.push_back(
-                   outputMeta.GetScore().GetName());
+                       outputMeta.GetScore().GetName());
+
+       if (!outputMeta.GetBox().GetName().empty())
+               tensorConfig.mOutputLayerNames.push_back(
+                       outputMeta.GetBox().GetName());
+
+       if (!outputMeta.GetLabel().GetName().empty())
+               tensorConfig.mOutputLayerNames.push_back(
+                       outputMeta.GetLabel().GetName());
+
+       if (!outputMeta.GetNumber().GetName().empty())
+               tensorConfig.mOutputLayerNames.push_back(
+                       outputMeta.GetNumber().GetName());
+
+       if (!outputMeta.GetLandmark().GetName().empty())
+               tensorConfig.mOutputLayerNames.push_back(
+                       outputMeta.GetLandmark().GetName());
+
+       if (!outputMeta.GetOffset().GetName().empty())
+               tensorConfig.mOutputLayerNames.push_back(
+                       outputMeta.GetOffset().GetName());
+
+       for (auto& dispVec : outputMeta.GetDispVecAll())
+               tensorConfig.mOutputLayerNames.push_back(dispVec.GetName());
 
        inference_engine_layer_property property;
        inference_engine_tensor_info tensor_info = {