int begin[] = {0, split_size * group_id, 0, 0};
cv::dnn::DictValue paramBegin = cv::dnn::DictValue::arrayInt(begin, 4);
- int end[] = {-1, begin[1] + split_size, -1, -1};
+ int end[] = {INT_MAX, begin[1] + split_size, INT_MAX, INT_MAX};
cv::dnn::DictValue paramEnd = cv::dnn::DictValue::arrayInt(end, 4);
darknet::LayerParameter lp;
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];
{
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
{
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
{
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())
{
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];
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())
{
// 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]);
}
}
if (axis > 0) {
begin.resize(axis, 0);
- end.resize(axis, -1);
+ end.resize(axis, INT_MAX);
}
for (int i = 0; i < starts.size(); ++i)
{
begin.push_back(starts.get<int>(i));
- int finish = ends.get<int>(i);
- end.push_back((finish < 0) ? --finish : finish); // numpy doesn't include last dim
+ end.push_back(ends.get<int>(i));
}
} else { // inp_size > 1
CV_Assert(inp_size >= 3);
const int* ends = end_blob.ptr<int>();
if (axis > 0) {
begin.resize(axis, 0);
- end.resize(axis, -1);
+ end.resize(axis, INT_MAX);
}
std::copy(starts, starts + start_blob.total(), std::back_inserter(begin));
- for (int i = 0; i < end_blob.total(); ++i)
- {
- int finish = ends[i];
- end.push_back((finish < 0) ? --finish : finish); // numpy doesn't include last dim
- }
+ std::copy(ends, ends + end_blob.total(), std::back_inserter(end));
if (inp_size == 5) {
CV_Assert(constBlobs.find(node_proto.input(4)) != constBlobs.end());
if (!haveVariables)
{
- if (broadcast_axes.size() != 1)
+ if (broadcast_axes.size() > 1)
CV_Error(Error::StsNotImplemented, "Expand op doesn't support multiple axes for constant input");
+ if (broadcast_axes.empty())
+ {
+ addConstant(output_name, getBlob(node_proto, 0));
+ return;
+ }
+
Mat input = getBlob(node_proto, 0);
input = input.reshape(0, total(inpShape, 0, broadcast_axes[0]));
Mat output = cv::repeat(input, 1, targetShape[broadcast_axes[0]]);
sliceLp.type = "Slice";
sliceLp.name = inpShape.size() > 1 ? layerParams.name + "/slice" : layerParams.name;
std::vector<int> begin(inpShape.size(), 0);
- std::vector<int> end(inpShape.size(), -1);
+ std::vector<int> end(inpShape.size(), INT_MAX);
begin[axis] = index;
end[axis] = index + 1;
int end_mask = getLayerAttr(layer, "end_mask").i();
for (int i = 0; i < num; ++i)
{
- if (ends.at<int>(i) < 0)
- ends.at<int>(i) -= 1;
if (end_mask & (1 << i))
- ends.at<int>(i) = -1;
+ ends.at<int>(i) = INT_MAX;
if (strides.at<int>(i) != 1)
CV_Error(Error::StsNotImplemented,
format("StridedSlice with stride %d", strides.at<int>(i)));
int64_t pads[8];
bool explicit_pads = getExplicitPadding(layerParams, layer, pads);
int64_t begs[4] = {};
- int64_t ends[4] = {-1, -1, -1, -1};
+ int64_t ends[4] = {};
if (explicit_pads)
{
name += "/deconv";
layerParams.set("pad_mode", "VALID");
+ ends[0] = ends[1] = INT_MAX;
for (int i = 2; i < 4; ++i) // begins=[0, 0, a, b], ends=[-1, -1, c, d]
{
begs[i] = pads[2*i];
- ends[i] = -1 - pads[2*i + 1];
+ ends[i] = -pads[2*i + 1];
}
}
const int strideX = layerParams.get<int>("stride_w");
Mat outShape = getTensorContent(getConstBlob(layer, value_id, 0));
int shift = (getDataLayout(layer) == DATA_LAYOUT_NCHW);
- const int outH = outShape.at<int>(1 + shift) + begs[2] - 1 - ends[2];
- const int outW = outShape.at<int>(2 + shift) + begs[3] - 1 - ends[3];
+ const int outH = outShape.at<int>(1 + shift) + begs[2] - ends[2];
+ const int outW = outShape.at<int>(2 + shift) + begs[3] - ends[3];
if (layerParams.get<String>("pad_mode") == "SAME")
{
layerParams.set("adj_w", (outW - 1) % strideX);
int size = scalarParams.get<int>("size");
int begins[] = {0, 0, size, size};
- int ends[] = {-1, -1, -size - 1, -size - 1};
+ int ends[] = {INT_MAX, INT_MAX, -size, -size};
newModule->apiType = "Slice";
layerParams.set("begin", DictValue::arrayInt<int*>(&begins[0], 4));
int targetId = get<1>(GetParam());
int begin[] = {0, 0, 0, 0};
- int end[] = {-1, -1, -1, -1};
+ int end[] = {INT_MAX, INT_MAX, INT_MAX, INT_MAX};
Net net;
LayerParams lp;