diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp index 9fdc5a9929..65408d5e7c 100644 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@ -357,6 +357,9 @@ public: void assign(const UMat& u) const; void assign(const Mat& m) const; + + void assign(const std::vector& v) const; + void assign(const std::vector& v) const; }; diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index 0208a71894..a85effc4c8 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -3053,6 +3053,82 @@ void _OutputArray::assign(const Mat& m) const } +void _OutputArray::assign(const std::vector& v) const +{ + int k = kind(); + if (k == STD_VECTOR_UMAT) + { + std::vector& this_v = *(std::vector*)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& this_v = *(std::vector*)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& v) const +{ + int k = kind(); + if (k == STD_VECTOR_UMAT) + { + std::vector& this_v = *(std::vector*)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& this_v = *(std::vector*)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; } diff --git a/modules/dnn/src/dnn.cpp b/modules/dnn/src/dnn.cpp index 40edf7aa1b..4faffe1439 100644 --- a/modules/dnn/src/dnn.cpp +++ b/modules/dnn/src/dnn.cpp @@ -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 &inputs, std::vector &outputs, std::vector &internals) diff --git a/modules/dnn/src/layers/detection_output_layer.cpp b/modules/dnn/src/layers/detection_output_layer.cpp index e5eb8be930..065c0c2566 100644 --- a/modules/dnn/src/layers/detection_output_layer.cpp +++ b/modules/dnn/src/layers/detection_output_layer.cpp @@ -211,92 +211,11 @@ public: return false; } -#ifdef HAVE_OPENCL - bool forward_ocl(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) - { - std::vector inpvec; - std::vector outputs; - - inputs_arr.getMatVector(inpvec); - outputs_arr.getMatVector(outputs); - - std::vector inputs(inpvec.size()); - for (size_t i = 0; i < inpvec.size(); i++) - inputs[i] = &inpvec[i]; - - std::vector allDecodedBBoxes; - std::vector > > 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(); - const float* confidenceData = inputs[1]->ptr(); - const float* priorData = inputs[2]->ptr(); - - // Retrieve all location predictions - std::vector allLocationPredictions; - GetLocPredictions(locationData, num, numPriors, _numLocClasses, - _shareLocation, _locPredTransposed, allLocationPredictions); - - // Retrieve all confidences - GetConfidenceScores(confidenceData, num, numPriors, _numClasses, allConfidenceScores); - - // Retrieve all prior bboxes - std::vector priorBBoxes; - std::vector > 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 > > 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(); - - 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); } diff --git a/samples/dnn/ssd_mobilenet_object_detection.cpp b/samples/dnn/ssd_mobilenet_object_detection.cpp index 895e548bf8..db7780d801 100644 --- a/samples/dnn/ssd_mobilenet_object_detection.cpp +++ b/samples/dnn/ssd_mobilenet_object_detection.cpp @@ -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("opencl")) + { + net.setPreferableTarget(DNN_TARGET_OPENCL); + } + if (net.empty()) { cerr << "Can't load network by using the following files: " << endl;