Merge pull request #10126 from alalek:dnn_issue_10125

pull/10076/merge
Alexander Alekhin 7 years ago
commit e7d62d6ef3
  1. 3
      modules/core/include/opencv2/core/mat.hpp
  2. 76
      modules/core/src/matrix.cpp
  3. 4
      modules/dnn/src/dnn.cpp
  4. 81
      modules/dnn/src/layers/detection_output_layer.cpp
  5. 9
      samples/dnn/ssd_mobilenet_object_detection.cpp

@ -357,6 +357,9 @@ public:
void assign(const UMat& u) const;
void assign(const Mat& m) const;
void assign(const std::vector<UMat>& v) const;
void assign(const std::vector<Mat>& v) const;
};

@ -3053,6 +3053,82 @@ void _OutputArray::assign(const Mat& m) const
}
void _OutputArray::assign(const std::vector<UMat>& v) const
{
int k = kind();
if (k == STD_VECTOR_UMAT)
{
std::vector<UMat>& this_v = *(std::vector<UMat>*)obj;
CV_Assert(this_v.size() == v.size());
for (size_t i = 0; i < v.size(); i++)
{
const UMat& m = v[i];
UMat& this_m = this_v[i];
if (this_m.u != NULL && this_m.u == m.u)
continue; // same object (see dnn::Layer::forward_fallback)
m.copyTo(this_m);
}
}
else if (k == STD_VECTOR_MAT)
{
std::vector<Mat>& this_v = *(std::vector<Mat>*)obj;
CV_Assert(this_v.size() == v.size());
for (size_t i = 0; i < v.size(); i++)
{
const UMat& m = v[i];
Mat& this_m = this_v[i];
if (this_m.u != NULL && this_m.u == m.u)
continue; // same object (see dnn::Layer::forward_fallback)
m.copyTo(this_m);
}
}
else
{
CV_Error(Error::StsNotImplemented, "");
}
}
void _OutputArray::assign(const std::vector<Mat>& v) const
{
int k = kind();
if (k == STD_VECTOR_UMAT)
{
std::vector<UMat>& this_v = *(std::vector<UMat>*)obj;
CV_Assert(this_v.size() == v.size());
for (size_t i = 0; i < v.size(); i++)
{
const Mat& m = v[i];
UMat& this_m = this_v[i];
if (this_m.u != NULL && this_m.u == m.u)
continue; // same object (see dnn::Layer::forward_fallback)
m.copyTo(this_m);
}
}
else if (k == STD_VECTOR_MAT)
{
std::vector<Mat>& this_v = *(std::vector<Mat>*)obj;
CV_Assert(this_v.size() == v.size());
for (size_t i = 0; i < v.size(); i++)
{
const Mat& m = v[i];
Mat& this_m = this_v[i];
if (this_m.u != NULL && this_m.u == m.u)
continue; // same object (see dnn::Layer::forward_fallback)
m.copyTo(this_m);
}
}
else
{
CV_Error(Error::StsNotImplemented, "");
}
}
static _InputOutputArray _none;
InputOutputArray noArray() { return _none; }

@ -2381,6 +2381,10 @@ void Layer::forward_fallback(InputArrayOfArrays inputs_arr, OutputArrayOfArrays
inputs[i] = &inpvec[i];
this->forward(inputs, outputs, internals);
// sync results back
outputs_arr.assign(outputs);
internals_arr.assign(internals);
}
void Layer::run(const std::vector<Mat> &inputs, std::vector<Mat> &outputs, std::vector<Mat> &internals)

@ -211,92 +211,11 @@ public:
return false;
}
#ifdef HAVE_OPENCL
bool forward_ocl(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr)
{
std::vector<Mat> inpvec;
std::vector<Mat> outputs;
inputs_arr.getMatVector(inpvec);
outputs_arr.getMatVector(outputs);
std::vector<Mat*> inputs(inpvec.size());
for (size_t i = 0; i < inpvec.size(); i++)
inputs[i] = &inpvec[i];
std::vector<LabelBBox> allDecodedBBoxes;
std::vector<std::vector<std::vector<float> > > allConfidenceScores;
int num = inputs[0]->size[0];
// extract predictions from input layers
{
int numPriors = inputs[2]->size[2] / 4;
const float* locationData = inputs[0]->ptr<float>();
const float* confidenceData = inputs[1]->ptr<float>();
const float* priorData = inputs[2]->ptr<float>();
// Retrieve all location predictions
std::vector<LabelBBox> allLocationPredictions;
GetLocPredictions(locationData, num, numPriors, _numLocClasses,
_shareLocation, _locPredTransposed, allLocationPredictions);
// Retrieve all confidences
GetConfidenceScores(confidenceData, num, numPriors, _numClasses, allConfidenceScores);
// Retrieve all prior bboxes
std::vector<util::NormalizedBBox> priorBBoxes;
std::vector<std::vector<float> > priorVariances;
GetPriorBBoxes(priorData, numPriors, priorBBoxes, priorVariances);
// Decode all loc predictions to bboxes
DecodeBBoxesAll(allLocationPredictions, priorBBoxes, priorVariances, num,
_shareLocation, _numLocClasses, _backgroundLabelId,
_codeType, _varianceEncodedInTarget, false, allDecodedBBoxes);
}
size_t numKept = 0;
std::vector<std::map<int, std::vector<int> > > allIndices;
for (int i = 0; i < num; ++i)
{
numKept += processDetections_(allDecodedBBoxes[i], allConfidenceScores[i], allIndices);
}
if (numKept == 0)
{
// Set confidences to zeros.
Range ranges[] = {Range::all(), Range::all(), Range::all(), Range(2, 3)};
outputs[0](ranges).setTo(0);
return true;
}
int outputShape[] = {1, 1, (int)numKept, 7};
Mat mat(4, outputShape, CV_32F);
float* outputsData = mat.ptr<float>();
size_t count = 0;
for (int i = 0; i < num; ++i)
{
count += outputDetections_(i, &outputsData[count * 7],
allDecodedBBoxes[i], allConfidenceScores[i],
allIndices[i]);
}
UMat& output = outputs_arr.getUMatRef(0);
output = mat.getUMat(ACCESS_READ);
CV_Assert(count == numKept);
return true;
}
#endif
void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr)
{
CV_TRACE_FUNCTION();
CV_TRACE_ARG_VALUE(name, "name", name.c_str());
CV_OCL_RUN((preferableTarget == DNN_TARGET_OPENCL) &&
OCL_PERFORMANCE_CHECK(ocl::Device::getDefault().isIntel()),
forward_ocl(inputs_arr, outputs_arr, internals_arr))
Layer::forward_fallback(inputs_arr, outputs_arr, internals_arr);
}

@ -37,7 +37,9 @@ const char* params
"{ camera_device | 0 | camera device number }"
"{ video | | video or image for detection}"
"{ out | | path to output video file}"
"{ min_confidence | 0.2 | min confidence }";
"{ min_confidence | 0.2 | min confidence }"
"{ opencl | false | enable OpenCL }"
;
int main(int argc, char** argv)
{
@ -57,6 +59,11 @@ int main(int argc, char** argv)
dnn::Net net = readNetFromCaffe(modelConfiguration, modelBinary);
//! [Initialize network]
if (parser.get<bool>("opencl"))
{
net.setPreferableTarget(DNN_TARGET_OPENCL);
}
if (net.empty())
{
cerr << "Can't load network by using the following files: " << endl;

Loading…
Cancel
Save