using namespace singleo::inference;
using namespace singleo::services;
-void BridgeNodeCallback(INode *node)
+void BridgeNodeCallbackFD(INode *node)
{
auto callbackNode = dynamic_cast<CallbackNode *>(node);
auto &inputBuffer = callbackNode->getInputBuffer();
taskManager->addNode(face_detection_node);
auto bridge_node = make_shared<BridgeNode>("bridge");
- bridge_node->setCb(BridgeNodeCallback);
+ bridge_node->setCb(BridgeNodeCallbackFD);
bridge_node->addDependency(face_detection_node);
taskManager->addNode(bridge_node);
taskManager->addNode(face_detection_node_b);
auto bridge_node = make_shared<BridgeNode>("bridge");
- bridge_node->setCb(BridgeNodeCallback);
+ bridge_node->setCb(BridgeNodeCallbackFD);
bridge_node->addDependency(face_detection_node_a);
bridge_node->addDependency(face_detection_node_b);
taskManager->addNode(bridge_node);
taskManager->addNode(face_detection_node);
auto bridge_node = make_shared<BridgeNode>("bridge");
- bridge_node->setCb(BridgeNodeCallback);
+ bridge_node->setCb(BridgeNodeCallbackFD);
bridge_node->addDependency(face_detection_node);
taskManager->addNode(bridge_node);
taskManager->addNode(face_detection_node_a);
auto bridge_node = make_shared<BridgeNode>("bridge");
- bridge_node->setCb(BridgeNodeCallback);
+ bridge_node->setCb(BridgeNodeCallbackFD);
bridge_node->addDependency(face_detection_node_a);
taskManager->addNode(bridge_node);
taskManager->clear();
}
}
+
+void BridgeNodeCallbackOD(INode *node)
+{
+ auto callbackNode = dynamic_cast<CallbackNode *>(node);
+ auto &inputBuffer = callbackNode->getInputBuffer();
+ auto inputBaseData = inputBuffer->getInputs()[0]->clone();
+ auto inputImage = dynamic_pointer_cast<ImageDataType>(inputBaseData);
+
+ cv::Mat cv_input_image(cv::Size(inputImage->width, inputImage->height), CV_MAKETYPE(CV_8U, 3), inputImage->ptr);
+
+ auto outputBuffer = make_shared<SharedBuffer>();
+
+ auto &results = callbackNode->results();
+ for (auto r : results) {
+ ASSERT_EQ(r->_type, ResultType::OBJECT_DETECTION);
+
+ auto obj_r = dynamic_pointer_cast<OdResultType>(r);
+
+ for (auto rect : obj_r->_rects) {
+ cv::Mat roi(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
+ cv::Mat cropped;
+ cv_input_image(roi).copyTo(cropped);
+
+ auto image_data = make_shared<ImageDataType>();
+
+ image_data->width = cropped.cols;
+ image_data->height = cropped.rows;
+ image_data->byte_per_pixel = cropped.channels();
+ image_data->ptr = cropped.data;
+
+ outputBuffer->addInput(static_pointer_cast<BaseDataType>(image_data));
+ }
+ }
+ // Object detection failed so do not go forward.
+ if (outputBuffer->getInputs().size() == 0)
+ return;
+ callbackNode->setOutputBuffer(outputBuffer);
+}
+
+void BridgeNodeCallbackIC(INode *node)
+{
+ auto callbackNode = dynamic_cast<CallbackNode *>(node);
+ auto &inputBuffer = callbackNode->getInputBuffer();
+ auto newBaseData = inputBuffer->getInputs()[0]->clone();
+
+ // For now, just copy the input to the output without any processing.
+ auto outputBuffer = make_shared<SharedBuffer>();
+ outputBuffer->addInput(newBaseData);
+ callbackNode->setOutputBuffer(outputBuffer);
+}
+
+// GraphE:
+// input -----> object_detection ----- bridge -----> IC -----bridge -----> IC -----> endpoint ----> output
+// | |
+// -----------------------------------------------------------------
+TEST(SingloTaskManager, MultipleNodesBasedGraphEShouldWork)
+{
+ cv::Mat cv_image(640, 480, CV_8UC3, cv::Scalar(0, 0, 0)); // Create a black image so that object detection fails
+ ASSERT_FALSE(cv_image.empty());
+
+ 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 = InferenceTaskFactory::instance().create("MvInferenceTaskFactory");
+
+ auto taskManager = make_unique<TaskManager>();
+ const unsigned int maxIteration = 10;
+
+ for (unsigned int cnt = 0; cnt < maxIteration; ++cnt) {
+ taskManager->addInput(image_data);
+
+ auto object_detection_node = make_shared<InferenceNode>("object_detection");
+ object_detection_node->setInferenceTask(factory->createObjectDetection());
+ taskManager->addNode(object_detection_node);
+
+ auto bridge_node_1 = make_shared<BridgeNode>("bridge_1");
+ bridge_node_1->setCb(BridgeNodeCallbackOD);
+ bridge_node_1->addDependency(object_detection_node);
+ taskManager->addNode(bridge_node_1);
+
+ auto image_classification_node_1 = make_shared<InferenceNode>("image_classification_1");
+ image_classification_node_1->setInferenceTask(factory->createImageClassification());
+ image_classification_node_1->addDependency(bridge_node_1);
+ taskManager->addNode(image_classification_node_1);
+
+ auto bridge_node_2 = make_shared<BridgeNode>("bridge_2");
+ bridge_node_2->setCb(BridgeNodeCallbackIC);
+ bridge_node_2->addDependency(image_classification_node_1);
+ taskManager->addNode(bridge_node_2);
+
+ auto image_classification_node_2 = make_shared<InferenceNode>("image_classification_2");
+ image_classification_node_2->setInferenceTask(factory->createImageClassification());
+ image_classification_node_2->addDependency(bridge_node_2);
+ taskManager->addNode(image_classification_node_2);
+
+ int endpoint_node_run = 0;
+ auto endpoint_node = make_shared<EndpointNode>("endpoint");
+ endpoint_node->addDependency(object_detection_node);
+ endpoint_node->addDependency(image_classification_node_2);
+ endpoint_node->setCb([&](INode *node) { endpoint_node_run += 1; });
+ taskManager->addNode(endpoint_node);
+
+ taskManager->run();
+
+ ASSERT_EQ(endpoint_node_run, 0); // Since OD node fails, endpoint node should not be run.
+
+ taskManager->clear();
+ }
+}
\ No newline at end of file