blob: 42bf29d2440d6f9c22d9be5f981a2067e297bbf4 [file] [log] [blame]
/*
* dnn_object_detection.cpp - object detection
*
* Copyright (c) 2019 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Author: Zong Wei <[email protected]>
*/
#include <format_reader_ptr.h>
#include "dnn_object_detection.h"
using namespace std;
using namespace InferenceEngine;
namespace XCam {
DnnObjectDetection::DnnObjectDetection (DnnInferConfig& config)
: DnnInferenceEngine (config)
{
XCAM_LOG_DEBUG ("DnnObjectDetection::DnnObjectDetection");
create_model (config);
}
DnnObjectDetection::~DnnObjectDetection ()
{
}
XCamReturn
DnnObjectDetection::get_model_input_info (DnnInferInputOutputInfo& info)
{
if (!_model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return XCAM_RETURN_ERROR_ORDER;
}
int id = 0;
InputsDataMap inputs_info (_network.getInputsInfo ());
for (auto & item : inputs_info) {
auto& input = item.second;
const InferenceEngine::SizeVector input_dims = input->getDims ();
info.width[id] = input_dims[0];
info.height[id] = input_dims[1];
info.channels[id] = input_dims[2];
info.object_size[id] = input_dims[3];
info.precision[id] = convert_precision_type (input->getPrecision());
info.layout[id] = convert_layout_type (input->getLayout());
item.second->setPrecision(Precision::U8);
id++;
}
info.batch_size = get_batch_size ();
info.numbers = inputs_info.size ();
return XCAM_RETURN_NO_ERROR;
}
XCamReturn
DnnObjectDetection::set_model_input_info (DnnInferInputOutputInfo& info)
{
XCAM_LOG_DEBUG ("DnnObjectDetection::set_model_input_info");
if (!_model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return XCAM_RETURN_ERROR_ORDER;
}
InputsDataMap inputs_info (_network.getInputsInfo ());
if (info.numbers != inputs_info.size ()) {
XCAM_LOG_ERROR ("Input size is not matched with model info numbers %d !", info.numbers);
return XCAM_RETURN_ERROR_PARAM;
}
int id = 0;
for (auto & item : inputs_info) {
Precision precision = convert_precision_type (info.precision[id]);
item.second->setPrecision (precision);
Layout layout = convert_layout_type (info.layout[id]);
item.second->setLayout (layout);
id++;
}
return XCAM_RETURN_NO_ERROR;
}
XCamReturn
DnnObjectDetection::get_model_output_info (DnnInferInputOutputInfo& info)
{
if (!_model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return XCAM_RETURN_ERROR_ORDER;
}
int id = 0;
std::string output_name;
OutputsDataMap outputs_info (_network.getOutputsInfo ());
DataPtr output_info;
for (const auto& out : outputs_info) {
if (out.second->creatorLayer.lock()->type == "DetectionOutput") {
output_name = out.first;
output_info = out.second;
break;
}
}
if (output_info.get ()) {
const InferenceEngine::SizeVector output_dims = output_info->getTensorDesc().getDims();
info.width[id] = output_dims[0];
info.height[id] = output_dims[1];
info.channels[id] = output_dims[2];
info.object_size[id] = output_dims[3];
info.precision[id] = convert_precision_type (output_info->getPrecision());
info.layout[id] = convert_layout_type (output_info->getLayout());
info.batch_size = 1;
info.numbers = outputs_info.size ();
} else {
XCAM_LOG_ERROR ("Get output info error!");
return XCAM_RETURN_ERROR_UNKNOWN;
}
return XCAM_RETURN_NO_ERROR;
}
XCamReturn
DnnObjectDetection::set_model_output_info (DnnInferInputOutputInfo& info)
{
if (!_model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return XCAM_RETURN_ERROR_ORDER;
}
OutputsDataMap outputs_info (_network.getOutputsInfo ());
if (info.numbers != outputs_info.size ()) {
XCAM_LOG_ERROR ("Output size is not matched with model!");
return XCAM_RETURN_ERROR_PARAM;
}
int id = 0;
for (auto & item : outputs_info) {
Precision precision = convert_precision_type (info.precision[id]);
item.second->setPrecision (precision);
Layout layout = convert_layout_type (info.layout[id]);
item.second->setLayout (layout);
id++;
}
return XCAM_RETURN_NO_ERROR;
}
XCamReturn
DnnObjectDetection::set_inference_data (std::vector<std::string> images)
{
if (!_model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return XCAM_RETURN_ERROR_ORDER;
}
uint32_t idx = 0;
InputsDataMap inputs_info (_network.getInputsInfo ());
for (auto & i : images) {
FormatReader::ReaderPtr reader (i.c_str ());
if (reader.get () == NULL) {
XCAM_LOG_WARNING ("Image %d cannot be read!", i);
continue;
}
_input_image_width = reader->width ();
_input_image_height = reader->height ();
uint32_t image_width = 0;
uint32_t image_height = 0;
for (auto & item : inputs_info) {
image_width = inputs_info[item.first]->getDims ()[0];
image_height = inputs_info[item.first]->getDims ()[1];
}
std::shared_ptr<unsigned char> data (reader->getData (image_width, image_height));
if (data.get () != NULL) {
DnnInferData image;
image.width = image_width;
image.height = image_height;
image.width_stride = image_width;
image.height_stride = image_height;
image.buffer = data.get ();
image.channel_num = 3;
image.batch_idx = idx;
image.image_format = DnnInferImageFormatBGRPacked;
// set precision & data type
image.precision = get_input_presion (idx);
image.data_type = DnnInferDataTypeImage;
set_input_blob (idx, image);
idx ++;
} else {
XCAM_LOG_WARNING ("Valid input images were not found!");
continue;
}
}
return XCAM_RETURN_NO_ERROR;
}
void*
DnnObjectDetection::get_inference_results (uint32_t idx, uint32_t& size)
{
if (! _model_created || ! _model_loaded) {
XCAM_LOG_ERROR ("Please create and load the model firstly!");
return NULL;
}
uint32_t id = 0;
std::string item_name;
OutputsDataMap outputs_info (_network.getOutputsInfo ());
if (idx > outputs_info.size ()) {
XCAM_LOG_ERROR ("Output is out of range");
return NULL;
}
for (auto & item : outputs_info) {
if (item.second->creatorLayer.lock()->type == "DetectionOutput") {
item_name = item.first;
break;
}
id++;
}
if (item_name.empty ()) {
XCAM_LOG_ERROR ("item name is empty!");
return NULL;
}
const Blob::Ptr blob = _infer_request.GetBlob (item_name);
float* output_result = static_cast<PrecisionTrait<Precision::FP32>::value_type*>(blob->buffer ());
size = blob->byteSize ();
return (reinterpret_cast<void *>(output_result));
}
} // namespace XCam