_threads.clear();
}
-BaseResultType &TaskManager::output()
+vector<shared_ptr<BaseResultType> > &TaskManager::output()
{
auto lastNode = _nodes[_nodes.size() - 1];
+ _results.clear();
+
// TODO. consider for callback node support as last node.
- if (lastNode->getType() != NodeType::INFERENCE) {
- SINGLEO_LOGE("Last node is not an inference node.");
- throw InvalidOperation("Last node is not an inference node.");
- }
+ if (lastNode->getType() == NodeType::INFERENCE) {
+ auto inferenceNode = dynamic_pointer_cast<InferenceNode>(lastNode);
+ auto &result = inferenceNode->getInferenceService()->result();
+ if (result._type == ResultType::FACE_DETECTION) {
+ auto fd_result = dynamic_cast<FdResultType &>(result);
+ _results.push_back(make_shared<FdResultType>(fd_result));
+ } else if (result._type == ResultType::FACE_LANDMARK) {
+ auto fld_result = dynamic_cast<FldResultType &>(result);
+ _results.push_back(make_shared<FldResultType>(fld_result));
+ } else if (result._type == ResultType::OBJECT_DETECTION) {
+ auto od_result = dynamic_cast<OdResultType &>(result);
+ _results.push_back(make_shared<OdResultType>(od_result));
+ }
+ } else {
+ auto callbackNode = dynamic_pointer_cast<CallbackNode>(lastNode);
- auto infereneNode = dynamic_pointer_cast<InferenceNode>(lastNode);
+ _results = callbackNode->getResult();
+ }
- return infereneNode->getInferenceService()->result();
+ return _results;
}
void TaskManager::clear()
using namespace singleo::inference;
using namespace singleo::services;
-void ExampleNodeCallback(vector<BaseResultType *> &results, shared_ptr<BaseDataType> inputData, void *user_data)
+void BridgeNodeCallback(vector<BaseResultType *> &results, shared_ptr<BaseDataType> inputData, void *user_data)
{
shared_ptr<ImageDataType> imageData = dynamic_pointer_cast<ImageDataType>(inputData);
size_t buffer_size = imageData->width * imageData->height * imageData->byte_per_pixel;
}
node->setOutput(make_shared<ImageDataType>(newImage));
-};
+}
// GraphA : input ----> face_detection ----> callback ----> face_landmark_detection ----> output
TEST(SingloTaskManager, MultipleNodesBasedGraphAShouldWork)
auto callback_node = make_shared<CallbackNode>();
callback_node->setName("callback");
- callback_node->setCb(&ExampleNodeCallback, callback_node.get());
+ callback_node->setCb(BridgeNodeCallback, callback_node.get());
callback_node->addDependency(face_detection_node);
taskManager->addNode(callback_node);
taskManager->run();
cout << "Face landmark result" << endl;
- auto result = dynamic_cast<FldResultType &>(taskManager->output());
- for (auto &point : result._points)
- cout << point.x << " x " << point.y << endl;
+ auto results = taskManager->output();
+ for (auto &result : results) {
+ auto fld_result = dynamic_pointer_cast<FldResultType>(result);
+ for (auto &point : fld_result->_points)
+ cout << point.x << " x " << point.y << endl;
+ }
taskManager->clear();
}
auto callback_node = make_shared<CallbackNode>();
callback_node->setName("callback");
- callback_node->setCb(&ExampleNodeCallback, callback_node.get());
+ callback_node->setCb(BridgeNodeCallback, callback_node.get());
callback_node->addDependency(face_detection_node_a);
callback_node->addDependency(face_detection_node_b);
taskManager->addNode(callback_node);
taskManager->run();
cout << "Face landmark result" << endl;
- auto result = dynamic_cast<FldResultType &>(taskManager->output());
- for (auto &point : result._points)
- cout << point.x << " x " << point.y << endl;
+
+ auto results = taskManager->output();
+ for (auto &result : results) {
+ auto fld_result = dynamic_pointer_cast<FldResultType>(result);
+ for (auto &point : fld_result->_points)
+ cout << point.x << " x " << point.y << endl;
+ }
+
+ taskManager->clear();
+ }
+}
+
+void LastNodeCallback(vector<BaseResultType *> &results, shared_ptr<BaseDataType> inputData, void *user_data)
+{
+ CallbackNode *node = static_cast<CallbackNode *>(user_data);
+
+ for (auto &r : results) {
+ ASSERT_EQ((r->_type == ResultType::FACE_DETECTION || r->_type == ResultType::FACE_LANDMARK), true);
+
+ if (r->_type == ResultType::FACE_DETECTION) {
+ auto fdResult = dynamic_cast<FdResultType *>(r);
+ node->addResult(make_shared<FdResultType>(*fdResult));
+ } else {
+ auto fldResult = dynamic_cast<FldResultType *>(r);
+ node->addResult(make_shared<FldResultType>(*fldResult));
+ }
+ }
+}
+
+// GraphC:
+// -----> callback -----> face_landmark_detection ------
+// input -----> face_detection --| |----> callback ----> output
+// -----------------------------------------------------
+TEST(SingloTaskManager, MultipleNodesBasedGraphDShouldWork)
+{
+ cv::Mat cv_image = cv::imread(IMG_FACE, cv::IMREAD_COLOR);
+ cv::cvtColor(cv_image, cv_image, cv::COLOR_BGR2RGB);
+
+ if (cv_image.empty()) {
+ cout << "Fail to read a given image file." << endl;
+ return;
+ }
+
+ ImageDataType image_data;
+
+ image_data.width = cv_image.cols;
+ image_data.height = cv_image.rows;
+ image_data.byte_per_pixel = cv_image.channels();
+ image_data.ptr = cv_image.data;
+
+ auto factory = InferenceServiceFactory::instance().create("MvInferenceServiceFactory");
+
+ auto taskManager = make_unique<TaskManager>();
+ const unsigned int maxIteration = 10;
+
+ for (unsigned int cnt = 0; cnt < maxIteration; ++cnt) {
+ taskManager->addInput(image_data);
+
+ auto face_detection_node = make_shared<InferenceNode>();
+ face_detection_node->setName("face_detection");
+ face_detection_node->setInferenceService(factory->createFaceDetection());
+ taskManager->addNode(face_detection_node);
+
+ auto bridge_callback_node = make_shared<CallbackNode>();
+ bridge_callback_node->setName("bridge_callback");
+ bridge_callback_node->setCb(BridgeNodeCallback, bridge_callback_node.get());
+ bridge_callback_node->addDependency(face_detection_node);
+ taskManager->addNode(bridge_callback_node);
+
+ auto face_landmark_node = make_shared<InferenceNode>();
+ face_landmark_node->setName("face_landmark");
+ face_landmark_node->setInferenceService(factory->createFaceLandmarkDetection());
+ face_landmark_node->addDependency(bridge_callback_node);
+ taskManager->addNode(face_landmark_node);
+
+ auto lase_callback_node = make_shared<CallbackNode>();
+ lase_callback_node->setName("last_callback");
+ lase_callback_node->setCb(LastNodeCallback, lase_callback_node.get());
+ lase_callback_node->addDependency(face_detection_node);
+ lase_callback_node->addDependency(face_landmark_node);
+ taskManager->addNode(lase_callback_node);
+
+ taskManager->run();
+
+ auto results = taskManager->output();
+ for (auto &result : results) {
+ if (result->_type == ResultType::FACE_DETECTION) {
+ auto fd_result = dynamic_pointer_cast<FdResultType>(result);
+
+ cout << "Face detection result" << endl;
+
+ for (auto rect : fd_result->_rects)
+ cout << rect.left << " x " << rect.top << " ~ " << rect.right << " x " << rect.bottom << endl;
+ } else {
+ auto fld_result = dynamic_pointer_cast<FldResultType>(result);
+
+ cout << "Face landmark detection result" << endl;
+
+ for (auto &point : fld_result->_points)
+ cout << point.x << " x " << point.y << endl;
+ }
+ }
taskManager->clear();
}