diff --git a/modules/dnn/src/layers/slice_layer.cpp b/modules/dnn/src/layers/slice_layer.cpp index e69de29bb..b59d5e6e1 100644 --- a/modules/dnn/src/layers/slice_layer.cpp +++ b/modules/dnn/src/layers/slice_layer.cpp @@ -0,0 +1,99 @@ +#include "../precomp.hpp" +#include "layers_common.hpp" +#include + +namespace cv +{ +namespace dnn +{ + +class SliceLayer : public Layer +{ +public: + SliceLayer(LayerParams ¶ms); + + void allocate(const std::vector &inputs, std::vector &outputs); + + void forward(std::vector &inputs, std::vector &outputs); + +private: + int inAxis; + std::vector slicePoints; +}; + + +REGISTER_LAYER_CLASS(Slice, SliceLayer) + + +SliceLayer::SliceLayer(LayerParams ¶ms) +{ + inAxis = params.get("axis", 1); + + const DictValue &_slicePoints = params.get("slice_point"); + slicePoints.resize(_slicePoints.size()); + for (int i = 0; i < _slicePoints.size(); i++) + { + slicePoints[i] = _slicePoints.get(i); + CV_Assert(slicePoints[i] > 0 && (i == 0 || slicePoints[i-1] < slicePoints[i])); + } +} + +void SliceLayer::allocate(const std::vector &inputs, std::vector &outputs) +{ + CV_Assert(inputs.size() == 1); + + const Blob inpBlob = *inputs[0]; + int axis = inpBlob.canonicalAxis(inAxis); + int axisSize = inpBlob.size(axis); + BlobShape inpShape = inpBlob.shape(); + + if (slicePoints.size()) //divide blob with respect to passed parameters + { + std::vector outAxisSize; + int prevSlice = 0; + + for (size_t i = 0; i < slicePoints.size(); i++) + { + CV_Assert(prevSlice < slicePoints[i] && slicePoints[i] < axisSize); + outAxisSize.push_back(slicePoints[i] - prevSlice); + prevSlice = slicePoints[i]; + } + outAxisSize.push_back(axisSize - prevSlice); + + outputs.resize(outAxisSize.size()); + for (size_t i = 0; i < outAxisSize.size(); i++) + { + inpShape[axis] = outAxisSize[i]; + outputs[i].create(inpShape, inpBlob.type()); + } + } + else //divide blob with respect to count of output blobs + { + CV_Assert(outputs.size() > 0 && axisSize % outputs.size() == 0); + int outAxisSize = axisSize / (int)outputs.size(); + + for (size_t i = 0; i < outputs.size(); i++) + { + inpShape[axis] = outAxisSize; + outputs[i].create(inpShape, inpBlob.type()); + } + } +} + +void SliceLayer::forward(std::vector &inputs, std::vector &outputs) +{ + Blob &inpBlob = *inputs[0]; + const uchar *inpPtr = inpBlob.ptrRaw(); + const size_t elemSize = CV_ELEM_SIZE(inpBlob.type()); + + for (size_t i = 0; i < outputs.size(); i++) + { + uchar *outPtr = outputs[i].ptrRaw(); + size_t size = outputs[i].total() * elemSize; + memcpy(outPtr, inpPtr, size); + inpPtr += size; + } +} + +} +} \ No newline at end of file diff --git a/modules/dnn/src/layers/split_layer.cpp b/modules/dnn/src/layers/split_layer.cpp index e69de29bb..6bfc8a37b 100644 --- a/modules/dnn/src/layers/split_layer.cpp +++ b/modules/dnn/src/layers/split_layer.cpp @@ -0,0 +1,58 @@ +#include "../precomp.hpp" +#include "layers_common.hpp" + +namespace cv +{ +namespace dnn +{ + +//TODO: maybe "top_count" param is useless because it can be determined by output connections number? +class SplitLayer : public Layer +{ +public: + SplitLayer(LayerParams ¶ms); + + void allocate(const std::vector &inputs, std::vector &outputs); + + void forward(std::vector &inputs, std::vector &outputs); + +private: + int outputsNum; +}; + + +REGISTER_LAYER_CLASS(Split, SplitLayer) + + +SplitLayer::SplitLayer(LayerParams ¶ms) +{ + if (params.has("top_count")) + { + outputsNum = params.get("top_count"); + CV_Assert(outputsNum >= 0); + } + else + { + outputsNum = -1; + } +} + +void SplitLayer::allocate(const std::vector &inputs, std::vector &outputs) +{ + CV_Assert(inputs.size() == 1); + + if (outputsNum >= 0) + outputs.resize(outputsNum); + + for (size_t i = 0; i < outputs.size(); i++) + outputs[i].create(inputs[0]->shape(), inputs[0]->type()); +} + +void SplitLayer::forward(std::vector &inputs, std::vector &outputs) +{ + for (size_t i = 0; i < outputs.size(); i++) + inputs[0]->getMatRef().copyTo(outputs[i].getMatRef()); +} + +} +} \ No newline at end of file