mirror of
https://github.com/opencv/opencv.git
synced 2024-11-25 19:50:38 +08:00
Make DNN Crop layer match Caffe default offset behavior
and add parametric unit test for crop layer.
This commit is contained in:
parent
a55aed5f42
commit
d1a3b530be
@ -110,27 +110,13 @@ public:
|
||||
}
|
||||
|
||||
crop_ranges.resize(dims, Range::all());
|
||||
for (int i = 0; i < dims; i++)
|
||||
{
|
||||
if( i < start_axis )
|
||||
continue;
|
||||
|
||||
if (!offset.empty()) //normal case
|
||||
for (int i = start_axis; i < dims; i++)
|
||||
{
|
||||
if (offset_final[i] < 0 || offset_final[i] + inpSzBlob.size[i] > inpBlob.size[i])
|
||||
CV_Error(Error::StsBadArg, "invalid crop parameters");
|
||||
CV_Error(Error::StsBadArg, "invalid crop parameters or blob sizes");
|
||||
|
||||
crop_ranges[i] = Range(offset_final[i], offset_final[i] + inpSzBlob.size[i]);
|
||||
}
|
||||
else //detect offset automatically so that cropped image is center of original one
|
||||
{
|
||||
if (inpSzBlob.size[i] > inpBlob.size[i])
|
||||
CV_Error(Error::StsBadArg, "invalid output blob size");
|
||||
|
||||
int cur_crop = (inpBlob.size[i] - inpSzBlob.size[i]) / 2;
|
||||
crop_ranges[i] = Range(cur_crop, cur_crop + inpSzBlob.size[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr)
|
||||
|
@ -715,4 +715,87 @@ INSTANTIATE_TEST_CASE_P(Layer_Test, Scale_untrainable, Combine(
|
||||
/*conv fusion*/ testing::Bool()
|
||||
));
|
||||
|
||||
typedef testing::TestWithParam<tuple<Vec4i, Vec4i, int, int, int> > Crop;
|
||||
TEST_P(Crop, Accuracy)
|
||||
{
|
||||
Vec4i inpShapeVec = get<0>(GetParam());
|
||||
Vec4i sizShapeVec = get<1>(GetParam());
|
||||
int axis = get<2>(GetParam());
|
||||
int numOffsets = get<3>(GetParam());
|
||||
int offsetVal = get<4>(GetParam());
|
||||
const int inpShape[] = {inpShapeVec[0], inpShapeVec[1], inpShapeVec[2], inpShapeVec[3]};
|
||||
const int sizShape[] = {sizShapeVec[0], sizShapeVec[1], sizShapeVec[2], sizShapeVec[3]};
|
||||
|
||||
// Create a network with two inputs. Crop layer crops a first input to
|
||||
// the size of a second one.
|
||||
// See http://caffe.berkeleyvision.org/tutorial/layers/crop.html
|
||||
Net net;
|
||||
|
||||
LayerParams lp;
|
||||
lp.name = "testCrop";
|
||||
lp.type = "Crop";
|
||||
lp.set("axis", axis);
|
||||
if (numOffsets > 0)
|
||||
{
|
||||
std::vector<int> offsets(numOffsets, offsetVal);
|
||||
lp.set("offset", DictValue::arrayInt<int*>(&offsets[0], offsets.size()));
|
||||
}
|
||||
else
|
||||
offsetVal = 0;
|
||||
int id = net.addLayerToPrev(lp.name, lp.type, lp);
|
||||
net.connect(0, 1, id, 1);
|
||||
|
||||
Mat inpImage(4, inpShape, CV_32F);
|
||||
Mat sizImage(4, sizShape, CV_32F);
|
||||
randu(inpImage, -1, 1);
|
||||
randu(sizImage, -1, 1);
|
||||
|
||||
std::vector<String> inpNames(2);
|
||||
inpNames[0] = "cropImage";
|
||||
inpNames[1] = "sizImage";
|
||||
net.setInputsNames(inpNames);
|
||||
net.setInput(inpImage, inpNames[0]);
|
||||
net.setInput(sizImage, inpNames[1]);
|
||||
|
||||
// There are a few conditions that represent invalid input to the crop
|
||||
// layer, so in those cases we want to verify an exception is thrown.
|
||||
|
||||
bool shouldThrowException = false;
|
||||
if (numOffsets > 1 && numOffsets != 4 - axis)
|
||||
shouldThrowException = true;
|
||||
else
|
||||
for (int i = axis; i < 4; i++)
|
||||
if (sizShape[i] + offsetVal > inpShape[i])
|
||||
shouldThrowException = true;
|
||||
|
||||
Mat out;
|
||||
if (shouldThrowException)
|
||||
{
|
||||
ASSERT_ANY_THROW(out = net.forward());
|
||||
return;
|
||||
}
|
||||
else
|
||||
out = net.forward();
|
||||
|
||||
// Finally, compare the cropped output blob from the DNN layer (out)
|
||||
// to a reference blob (ref) that we compute here.
|
||||
|
||||
std::vector<Range> crop_range;
|
||||
crop_range.resize(4, Range::all());
|
||||
for (int i = axis; i < 4; i++)
|
||||
crop_range[i] = Range(offsetVal, sizShape[i] + offsetVal);
|
||||
|
||||
Mat ref(sizImage.dims, sizImage.size, CV_32F);
|
||||
inpImage(&crop_range[0]).copyTo(ref);
|
||||
normAssert(out, ref);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Layer_Test, Crop, Combine(
|
||||
/*input blob shape*/ Values(Vec4i(1, 3, 20, 30)),
|
||||
/*cropsize blob shape*/ Values(Vec4i(1, 3, 10, 12)),
|
||||
/*start axis*/ Values(0, 1, 2),
|
||||
/*number of offsets*/ Values(0, 1, 2, 4),
|
||||
/*offset value*/ Values(3, 4)
|
||||
));
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user