|
|
|
@ -58,12 +58,32 @@ namespace cv |
|
|
|
|
namespace dnn |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
void sliceRangesFromShape(const MatShape& inpShape, int& axis, std::vector<std::vector<cv::Range> >& sliceRanges) |
|
|
|
|
Range normalizeRange(const Range& input_range, int n) |
|
|
|
|
{ |
|
|
|
|
Range range = input_range; |
|
|
|
|
|
|
|
|
|
range.start = std::min(std::max(range.start, -n), n - 1); |
|
|
|
|
if (range.start < 0) |
|
|
|
|
{ |
|
|
|
|
range.start += n; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
range.end = std::min(std::max(range.end, -n), n); |
|
|
|
|
if (range.end < 0) |
|
|
|
|
{ |
|
|
|
|
range.end += n; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return range; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
std::vector<std::vector<cv::Range> > finalizeSliceRange(const MatShape& inpShape, int& axis, |
|
|
|
|
const std::vector<std::vector<cv::Range> >& inputSliceRanges) |
|
|
|
|
{ |
|
|
|
|
std::vector<std::vector<cv::Range> > sliceRanges = inputSliceRanges; |
|
|
|
|
CV_Assert(inpShape.size() > 0); |
|
|
|
|
bool axisNeg = (axis < 0); |
|
|
|
|
axis = (axis + static_cast<int>(inpShape.size())) % inpShape.size(); |
|
|
|
|
int n = inpShape[axis]; |
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < sliceRanges.size(); ++i){ |
|
|
|
|
std::vector<Range>& ranges = sliceRanges[i]; |
|
|
|
@ -71,16 +91,20 @@ void sliceRangesFromShape(const MatShape& inpShape, int& axis, std::vector<std:: |
|
|
|
|
{ |
|
|
|
|
ranges.insert(ranges.begin(), axis, Range::all()); |
|
|
|
|
} |
|
|
|
|
Range& range = ranges.back(); |
|
|
|
|
|
|
|
|
|
if (range.start >= 0) |
|
|
|
|
for (size_t j = 0; j < ranges.size(); ++j) |
|
|
|
|
{ |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
int n = inpShape[j]; |
|
|
|
|
if (n <= 0) |
|
|
|
|
{ |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
CV_Assert(n != 0); |
|
|
|
|
range.start = (n + range.start) % n; |
|
|
|
|
ranges[j] = normalizeRange(ranges[j], n); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return sliceRanges; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
class SliceLayerImpl : public SliceLayer |
|
|
|
@ -130,7 +154,7 @@ public: |
|
|
|
|
{ |
|
|
|
|
int size = sizeOrEnd; |
|
|
|
|
CV_Assert(size == -1 || size > 0); // -1 value means range [start, axis_size).
|
|
|
|
|
sliceRanges[0][i].end = size > 0 ? (start + size) : -1; // We'll finalize a negative value later.
|
|
|
|
|
sliceRanges[0][i].end = size > 0 ? (start + size) : INT_MAX; // We'll finalize a negative value later.
|
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
@ -181,8 +205,7 @@ public: |
|
|
|
|
MatShape inpShape = inputs[0]; |
|
|
|
|
|
|
|
|
|
int axis_rw = axis; |
|
|
|
|
std::vector<std::vector<cv::Range> > sliceRanges_rw = sliceRanges; |
|
|
|
|
sliceRangesFromShape(inpShape, axis_rw, sliceRanges_rw); |
|
|
|
|
std::vector<std::vector<cv::Range> > sliceRanges_rw = finalizeSliceRange(inpShape, axis_rw, sliceRanges); |
|
|
|
|
|
|
|
|
|
if (!sliceRanges_rw.empty()) |
|
|
|
|
{ |
|
|
|
@ -193,7 +216,7 @@ public: |
|
|
|
|
for (int j = 0; j < sliceRanges_rw[i].size(); ++j) |
|
|
|
|
{ |
|
|
|
|
if (shapesInitialized || inpShape[j] > 0) |
|
|
|
|
outputs[i][j] = normalize_axis_range(sliceRanges_rw[i][j], inpShape[j]).size(); |
|
|
|
|
outputs[i][j] = normalizeRange(sliceRanges_rw[i][j], inpShape[j]).size(); |
|
|
|
|
|
|
|
|
|
if (!sliceSteps.empty() && (i < sliceSteps.size()) && (j < sliceSteps[i].size()) && (sliceSteps[i][j] > 1)) |
|
|
|
|
outputs[i][j] = (outputs[i][j] + sliceSteps[i][j] - 1) / sliceSteps[i][j]; |
|
|
|
@ -230,8 +253,7 @@ public: |
|
|
|
|
CV_Assert(inputs.size() == 1); |
|
|
|
|
const MatSize& inpShape = inputs[0].size; |
|
|
|
|
|
|
|
|
|
sliceRangesFromShape(shape(inputs[0]), axis, sliceRanges); |
|
|
|
|
finalSliceRanges = sliceRanges; |
|
|
|
|
finalSliceRanges = finalizeSliceRange(shape(inputs[0]), axis, sliceRanges); |
|
|
|
|
|
|
|
|
|
if (sliceRanges.empty()) |
|
|
|
|
{ |
|
|
|
@ -261,7 +283,7 @@ public: |
|
|
|
|
// Clamp.
|
|
|
|
|
for (int j = 0; j < finalSliceRanges[i].size(); ++j) |
|
|
|
|
{ |
|
|
|
|
finalSliceRanges[i][j] = normalize_axis_range(finalSliceRanges[i][j], inpShape[j]); |
|
|
|
|
finalSliceRanges[i][j] = normalizeRange(finalSliceRanges[i][j], inpShape[j]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|