Added Split and Slice layer.

pull/265/head
Vitaliy Lyudvichenko 10 years ago
parent 172419ea1c
commit 71cfae419c
  1. 99
      modules/dnn/src/layers/slice_layer.cpp
  2. 58
      modules/dnn/src/layers/split_layer.cpp

@ -0,0 +1,99 @@
#include "../precomp.hpp"
#include "layers_common.hpp"
#include <stdlib.h>
namespace cv
{
namespace dnn
{
class SliceLayer : public Layer
{
public:
SliceLayer(LayerParams &params);
void allocate(const std::vector<Blob*> &inputs, std::vector<Blob> &outputs);
void forward(std::vector<Blob*> &inputs, std::vector<Blob> &outputs);
private:
int inAxis;
std::vector<int> slicePoints;
};
REGISTER_LAYER_CLASS(Slice, SliceLayer)
SliceLayer::SliceLayer(LayerParams &params)
{
inAxis = params.get<int>("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<int>(i);
CV_Assert(slicePoints[i] > 0 && (i == 0 || slicePoints[i-1] < slicePoints[i]));
}
}
void SliceLayer::allocate(const std::vector<Blob*> &inputs, std::vector<Blob> &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<int> 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<Blob*> &inputs, std::vector<Blob> &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;
}
}
}
}

@ -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 &params);
void allocate(const std::vector<Blob*> &inputs, std::vector<Blob> &outputs);
void forward(std::vector<Blob*> &inputs, std::vector<Blob> &outputs);
private:
int outputsNum;
};
REGISTER_LAYER_CLASS(Split, SplitLayer)
SplitLayer::SplitLayer(LayerParams &params)
{
if (params.has("top_count"))
{
outputsNum = params.get<int>("top_count");
CV_Assert(outputsNum >= 0);
}
else
{
outputsNum = -1;
}
}
void SplitLayer::allocate(const std::vector<Blob*> &inputs, std::vector<Blob> &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<Blob*> &inputs, std::vector<Blob> &outputs)
{
for (size_t i = 0; i < outputs.size(); i++)
inputs[0]->getMatRef().copyTo(outputs[i].getMatRef());
}
}
}
Loading…
Cancel
Save