Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add label_ids output in crop node #986

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/custom_nodes/model_zoo_intel_object_detection/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ make BASE_OS=redhat
| Output name | Description | Shape | Precision |
| ------------- |:-------------:| -----:| -----:|
| images | Returns images representing detected text boxes. Boxes are filtered based on confidence_threshold param. Resolution is defined by the node parameters. All images are in a single batch. Batch size depend on the number of detected objects. | `N,1,C,H,W` | FP32 |
| coordinates | For every detected box `N` the following info is added: x coordinate for the box center, y coordinate for the box center, box original width, box original height | `N,1,4` | I32 |
| coordinates | For every detected box `N` the following info is added: x coordinate for the box center, y coordinate for the box center, box original width, box original height | `N,1,4` | FP32 |
| confidences | For every detected box `N` information about confidence level (N - number of detected boxes; more about demultiplexing [here](./../../../docs/demultiplexing.md)) | `N,1,1` | FP32 |
| label_ids | For every detected box `N` information about label id (N - number of detected boxes; more about demultiplexing [here](./../../../docs/demultiplexing.md)) | `N,1,1` | I32 |

# Custom node parameters
Parameters can be defined in pipeline definition in OVMS configuration file. [Read more](./../../../docs/custom_node_development.md) about node parameters.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ static constexpr const char* INPUT_DETECTION_TENSOR_NAME = "detection";
static constexpr const char* OUTPUT_IMAGES_TENSOR_NAME = "images";
static constexpr const char* OUTPUT_COORDINATES_TENSOR_NAME = "coordinates";
static constexpr const char* OUTPUT_CONFIDENCES_TENSOR_NAME = "confidences";
static constexpr const char* OUTPUT_LABEL_IDS_TENSOR_NAME = "label_ids";

bool copy_images_into_output(struct CustomNodeTensor* output, const std::vector<cv::Rect>& boxes, const cv::Mat& originalImage, int targetImageHeight, int targetImageWidth, const std::string& targetImageLayout, bool convertToGrayScale) {
const uint64_t outputBatch = boxes.size();
Expand Down Expand Up @@ -127,6 +128,26 @@ bool copy_confidences_into_output(struct CustomNodeTensor* output, const std::ve
return true;
}

bool copy_label_ids_into_output(struct CustomNodeTensor* output, const std::vector<int>& labelIds) {
const uint64_t outputBatch = labelIds.size();
uint64_t byteSize = sizeof(float) * outputBatch;

float* buffer = (float*)malloc(byteSize);
NODE_ASSERT(buffer != nullptr, "malloc has failed");
std::memcpy(buffer, labelIds.data(), byteSize);

output->data = reinterpret_cast<uint8_t*>(buffer);
output->dataBytes = byteSize;
output->dimsCount = 3;
output->dims = (uint64_t*)malloc(output->dimsCount * sizeof(uint64_t));
NODE_ASSERT(output->dims != nullptr, "malloc has failed");
output->dims[0] = outputBatch;
output->dims[1] = 1;
output->dims[2] = 1;
output->precision = I32;
return true;
}

void cleanup(CustomNodeTensor& tensor) {
free(tensor.data);
free(tensor.dims);
Expand Down Expand Up @@ -213,6 +234,7 @@ int execute(const struct CustomNodeTensor* inputs, int inputsCount, struct Custo
std::vector<cv::Rect> boxes;
std::vector<cv::Vec4f> detections;
std::vector<float> confidences;
std::vector<int> labelIds;

for (uint64_t i = 0; i < detectionsCount; i++) {
float* detection = (float*)(detectionTensor->data + (i * featuresCount * sizeof(float)));
Expand All @@ -234,6 +256,7 @@ int execute(const struct CustomNodeTensor* inputs, int inputsCount, struct Custo
boxes.emplace_back(box);
detections.emplace_back(detection[3], detection[4], detection[5], detection[6]);
confidences.emplace_back(confidence);
labelIds.emplace_back(labelId);
if (debugMode) {
std::cout << "Detection:\nImageID: " << imageId << "; LabelID:" << labelId << "; Confidence:" << confidence << "; Box:" << box << std::endl;
}
Expand All @@ -246,7 +269,7 @@ int execute(const struct CustomNodeTensor* inputs, int inputsCount, struct Custo
confidences.resize(maxOutputBatch);
}

*outputsCount = 3;
*outputsCount = 4;
*outputs = (struct CustomNodeTensor*)malloc(*outputsCount * sizeof(CustomNodeTensor));
NODE_ASSERT((*outputs) != nullptr, "malloc has failed");

Expand Down Expand Up @@ -274,6 +297,16 @@ int execute(const struct CustomNodeTensor* inputs, int inputsCount, struct Custo
return 1;
}

CustomNodeTensor& labelIdsTensor = (*outputs)[3];
labelIdsTensor.name = OUTPUT_LABEL_IDS_TENSOR_NAME;
if (!copy_label_ids_into_output(&labelIdsTensor, labelIds)) {
cleanup(imagesTensor);
cleanup(coordinatesTensor);
cleanup(labelIdsTensor);
free(*outputs);
return 1;
}

return 0;
}

Expand Down Expand Up @@ -326,7 +359,7 @@ int getOutputsInfo(struct CustomNodeTensorInfo** info, int* infoCount, const str
NODE_ASSERT(targetImageLayout == "NCHW" || targetImageLayout == "NHWC", "target image layout must be NCHW or NHWC");
bool convertToGrayScale = get_string_parameter("convert_to_gray_scale", params, paramsCount) == "true";

*infoCount = 3;
*infoCount = 4;
*info = (struct CustomNodeTensorInfo*)malloc(*infoCount * sizeof(struct CustomNodeTensorInfo));
NODE_ASSERT((*info) != nullptr, "malloc has failed");

Expand Down Expand Up @@ -364,6 +397,15 @@ int getOutputsInfo(struct CustomNodeTensorInfo** info, int* infoCount, const str
(*info)[2].dims[1] = 1;
(*info)[2].dims[2] = 1;
(*info)[2].precision = FP32;

(*info)[3].name = OUTPUT_LABEL_IDS_TENSOR_NAME;
(*info)[3].dimsCount = 3;
(*info)[3].dims = (uint64_t*)malloc((*info)->dimsCount * sizeof(uint64_t));
NODE_ASSERT(((*info)[2].dims) != nullptr, "malloc has failed");
(*info)[3].dims[0] = 0;
(*info)[3].dims[1] = 1;
(*info)[3].dims[2] = 1;
(*info)[3].precision = I32;
return 0;
}

Expand Down