1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 23:33:05 +04:00

Merge pull request #27757 from vpisarev:matshape_inside_mat

Use MatShape instead of MatSize inside cv::Mat/cv::UMat #27757

**Merge together with https://github.com/opencv/opencv_contrib/pull/3996**
---

This PR continues cv::Mat/cv::UMat refactoring. See #26056, where `MatShape` was introduced. Now it's put inside cv::Mat/cv::UMat instead of a weird `MatSize`. MatSize is now an alias for MatShape:

**before:**

```
struct MatShape { ... };
struct MatSize { ... };

struct Mat {
    ...
    int dims;
    int rows;
    int cols;

    ...

    MatShape shape() const { ... /* constructs MatShape out of MatSize and returns it;
                                    layout is always 'unknown', because we don't store it */ }

    MatSize size; // size is not valid without the parent cv::Mat,
                  // because size.p may point to Mat::rows or to Mat::cols,
                  // depending on the dimensionality, and dims() returns Mat::dims.
    MatStep step; // may allocate memory, depending on the dimensionality.
    ...
};
```

**after:**

```
struct MatShape { ... };
typedef MatShape MatSize; // they are now synonyms

struct Mat {
    ...
    int dims;
    int rows;
    int cols;

    ...

    MatShape shape() const { return size; } // just return the embedded shape (including the proper layout information)

    MatSize size; // size is self-contained data structure that can be used without the parent cv::Mat.
                  // size.dims is now a copy of dims; size.p[*] contains copies of Mat::rows and Mat::cols when dims <= 2.
    MatStep step; // does not allocate extra memory buffers.
    ...
};
```

There are several reasons to do that:

1. the main reason is to be able to store data layout (MatShape::layout) inside each cv::Mat/cv::UMat. This is necessary for the proper shape inference in DNN module. In particular, it's necessary for the next step of DNN inference optimization where we introduce block-layout-optimized convolution and other operations. Later on, we can use layout information to support non-interleaved images (e.g. RRR...GGG...BBB...) or even batches of such images in core/imgproc modules.
2. the other reason is to represent 3D/4D/5D etc. tensors as cv::Mat/cv::UMat instances more conveniently, without extra dynamic memory allocation. Before this patch we allocated some memory buffers dynamically to store shape & steps for more than 2D arrays. Now the whole cv::Mat/cv::UMat header can be stored completely on stack/in a container. Creating another copy of Mat/UMat header is now done more efficiently.
3. the third reason is to introduce the new coding pattern: `dst.create(src.size, <dst_type>);`. The pattern is suitable for most of element-wise (including cloning) and filtering operations. This pattern does not only look crisp and self-documenting, it will also automatically copy shape (including layout) from the source tensor into the destination matrix/tensor.
4. in the future we might add `colorspace` member to MatShape that will allow to distinguish RGB from BGR or NV12. `dst.create(src.size, <dst_type>);` will then copy the colorspace information as well.

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
Vadim Pisarevsky
2025-09-15 15:03:34 +03:00
committed by GitHub
parent abcfb3c1e7
commit bdab54f79e
52 changed files with 521 additions and 624 deletions
@@ -208,24 +208,6 @@ static inline MatShape concat(const MatShape& a, const MatShape& b)
return c;
}
static inline std::ostream& operator << (std::ostream& strm, const MatShape& shape)
{
strm << '[';
if (shape.empty()) {
strm << "<empty>";
} else {
size_t n = shape.size();
if (n == 0) {
strm << "<scalar>";
} else {
for(size_t i = 0; i < n; ++i)
strm << (i > 0 ? " x " : "") << shape[i];
}
}
strm << "]";
return strm;
}
static inline std::string toString(const MatShape& shape, const String& name = "")
{
std::ostringstream ss;
+3 -3
View File
@@ -26,18 +26,18 @@
"MatShape": {
"objc_type": "IntVector*",
"to_cpp": "cv::MatShape(%(n)s.nativeRef)",
"from_cpp": "[IntVector fromNative:(std::vector<int>)%(n)s]"
"from_cpp": "[IntVector fromNative:%(n)s.vec()]"
},
"vector_MatShape": {
"objc_type": "IntVector*",
"to_cpp": "cv::MatShape(%(n)s.nativeRef)",
"from_cpp": "[IntVector fromNative:(std::vector<int>)%(n)s]",
"from_cpp": "[IntVector fromNative:%(n)s.vec()]",
"v_type": "MatShape"
},
"vector_vector_MatShape": {
"objc_type": "IntVector*",
"to_cpp": "cv::MatShape(%(n)s.nativeRef)",
"from_cpp": "[IntVector fromNative:(std::vector<int>)%(n)s]",
"from_cpp": "[IntVector fromNative:%(n)s.vec()]",
"v_v_type": "MatShape"
},
"LayerId": {
+1 -1
View File
@@ -271,7 +271,7 @@ public:
CV_Assert(pbBlob.data_size() == (int)dstBlob.total());
CV_DbgAssert(pbBlob.GetDescriptor()->FindFieldByLowercaseName("data")->cpp_type() == FieldDescriptor::CPPTYPE_FLOAT);
Mat(dstBlob.dims, &dstBlob.size[0], CV_32F, (void*)pbBlob.data().data()).copyTo(dstBlob);
Mat(dstBlob.size, CV_32F, (void*)pbBlob.data().data()).copyTo(dstBlob);
}
else
{
+3 -1
View File
@@ -147,7 +147,9 @@ static inline std::string toString(const Mat& blob, const std::string& name = st
else if (blob.dims == 1)
{
Mat blob_ = blob;
blob_.dims = 2; // hack
blob_.size.dims = blob_.dims = 2; // hack
blob_.size[1] = blob_.size[0];
blob_.size[0] = 1;
ss << blob_.t();
}
else
@@ -86,7 +86,7 @@ public:
MatSize weightShape = blobs[0].size;
CV_Assert(inputs[0].dims == outputs[0].dims);
if (weightShape.dims() == 3)
if (weightShape.dims == 3)
{
kernel_size.resize(1, kernel_size[0]);
strides.resize(1, strides[0]);
@@ -94,7 +94,7 @@ public:
pads_begin.resize(1, pads_begin[0]);
pads_end.resize(1, pads_end[0]);
}
CV_Assert(weightShape.dims() == kernel_size.size() + 2);
CV_Assert(weightShape.dims == kernel_size.size() + 2);
for (int i = 0; i < kernel_size.size(); i++) {
CV_Assert(weightShape[i + 2] == kernel_size[i]);
}
+1 -1
View File
@@ -273,7 +273,7 @@ struct DataLayer : public Layer
std::vector<cv::Range> plane(4, Range::all());
plane[0] = Range(n, n + 1);
plane[1] = Range(c, c + 1);
UMat out = outputs[i](plane).reshape(1, inp.dims, inp.size);
UMat out = outputs[i](plane).reshape(1, inp.size);
if (isFP16)
{
+1 -1
View File
@@ -107,7 +107,7 @@ public:
const int out_h = outputs[0].size[2];
const int out_w = outputs[0].size[3];
float* out_data = outputs[0].ptr<float>();
std::vector<int> sizes(&outputs[0].size[0], &outputs[0].size[0] + outputs[0].size.dims());
std::vector<int> sizes(&outputs[0].size[0], &outputs[0].size[0] + outputs[0].size.dims);
for (int i = 0; i < inputs.size() - have_reference; i++)
{
sizes[1] = inputs[i].size[1];
+1 -1
View File
@@ -29,7 +29,7 @@ static inline T doShift(T inputVal, U shiftVal, int direction, int bitWidth)
template<typename T, int CvTypeConst, int BitWidth>
void runBitShift(const Mat& input, const Mat& shift, Mat& output, int direction)
{
output.create(input.dims, input.size.p, input.type());
output.create(input.size, input.type());
const size_t numElements = input.total();
const T* inputPtr = input.ptr<T>();
+1 -1
View File
@@ -617,7 +617,7 @@ public:
if (fusedWeights)
{
weightsMat.copyTo(weightVK); // to handle the case of isContinuous() == false
weightVK = weightVK.reshape(1, blobs[0].dims, blobs[0].size);
weightVK = weightVK.reshape(1, blobs[0].size);
}
else
weightVK = blobs[0];
@@ -252,7 +252,7 @@ public:
const cv::String& code_type, const bool variance_encoded_in_target,
const bool clip, std::vector<LabelBBox>& all_decode_bboxes)
{
UMat outmat = UMat(loc_mat.dims, loc_mat.size, CV_32F);
UMat outmat(loc_mat.size, CV_32F);
size_t nthreads = loc_mat.total();
String kernel_name;
@@ -382,7 +382,7 @@ public:
return true;
}
UMat umat = use_half ? UMat::zeros(4, outputs[0].size, CV_32F) : outputs[0];
UMat umat = use_half ? UMat::zeros(outputs[0].size, CV_32F) : outputs[0];
if (!use_half)
umat.setTo(0);
+2 -2
View File
@@ -532,7 +532,7 @@ public:
// create temporary variable
MatShape tmpResult;
for (int i = 0; i < result.size.dims(); i++)
for (int i = 0; i < result.size.dims; i++)
tmpResult.emplace_back(result.size[i]);
@@ -656,7 +656,7 @@ void LayerEinsumImpl::preProcessInputs(InputArrayOfArrays& inputs_arr)
}
if (IsTransposeRequired(
!preprocessed.empty() ? preprocessed.size.dims() : inputs[inputIter].size.dims(),
!preprocessed.empty() ? preprocessed.size.dims : inputs[inputIter].size.dims,
permutation))
{
// call transpose
@@ -671,7 +671,7 @@ public:
CV_Assert(!weightsMat.empty());
Mat wm;
weightsMat.copyTo(wm); // to handle the case of isContinuous() == false
wm = wm.reshape(1, blobs[0].dims, blobs[0].size);
wm = wm.reshape(1, blobs[0].size);
vkBlobs.push_back(wm.t());
Ptr<VkComBackendWrapper> inputWrap = inputs[0].dynamicCast<VkComBackendWrapper>();
+1 -1
View File
@@ -101,7 +101,7 @@ public:
const int defaultOutType = CV_BoolC1;
const int outType = Y.empty() ? defaultOutType : Y.type();
Y.create(X.dims, X.size.p, outType);
Y.create(X.size, outType);
const int depth = CV_MAT_DEPTH(X.type());
const size_t total = X.total();
+1 -1
View File
@@ -70,7 +70,7 @@ public:
const int defaultOutType = CV_BoolC1;
const int outType = (Y.empty() || Y.type() < 0) ? defaultOutType : Y.type();
Y.create(X.dims, X.size.p, outType);
Y.create(X.size, outType);
const int depth = CV_MAT_DEPTH(X.type());
const size_t total = X.total();
+1 -1
View File
@@ -26,7 +26,7 @@ static void tanh(const Mat &src, Mat &dst)
static void tanh(const Mat &src, Mat &dst)
{
dst.create(src.dims, (const int*)src.size, src.type());
dst.create(src.size, src.type());
if (src.type() == CV_32F)
tanh<float>(src, dst);
else if (src.type() == CV_64F)
+1 -1
View File
@@ -70,7 +70,7 @@ static void tanh(const Mat &src, Mat &dst)
//TODO: make utils method
static void tanh(const Mat &src, Mat &dst)
{
dst.create(src.dims, (const int*)src.size, src.type());
dst.create(src.size, src.type());
if (src.type() == CV_32F)
tanh<float>(src, dst);
+1 -1
View File
@@ -280,7 +280,7 @@ public:
}
if (useSoftmax) { // Yolo v2
Mat _inpBlob = inpBlob.reshape(0, outBlob.dims, outBlob.size);
Mat _inpBlob = inpBlob.reshape(0, outBlob.size);
softmax(outBlob, _inpBlob, -1, 5, classes);
}
else if (useLogistic) { // Yolo v3
+1 -1
View File
@@ -213,7 +213,7 @@ public:
{
reuse(bestBlobPin, lp);
dst = bestBlob.reshape(1, 1).colRange(0, targetTotal).reshape(1, shape);
dst.dims = shape.size();
dst.size.dims = dst.dims = shape.size();
return;
}
}
+2 -2
View File
@@ -626,7 +626,7 @@ void Net::Impl::allocateLayers(const std::vector<LayerPin>& blobsToKeep_)
{
type = CV_16F;
if (layers[0].dtype == CV_32F)
layers[0].outputBlobs[i].create(inp.dims, inp.size, CV_16F);
layers[0].outputBlobs[i].create(inp.size, CV_16F);
}
}
inputShapes.push_back(shape(inp));
@@ -1426,7 +1426,7 @@ void Net::Impl::updateLayersShapes()
preferableTarget == DNN_TARGET_OPENCL_FP16 &&
inputLayerData.dtype == CV_32F)
{
inp.create(inp.dims, inp.size, CV_16F);
inp.create(inp.size, CV_16F);
}
inputShapes.push_back(shape(inp));
inputTypes.push_back(inp.type());
@@ -1927,8 +1927,9 @@ Mat getMatFromTensor(const opencv_onnx::TensorProto& tensor_proto, bool uint8ToI
CV_LOG_ERROR(NULL, errorMsg);
return blob;
}
if (tensor_proto.dims_size() == 0)
blob.dims = 1; // To force 1-dimensional cv::Mat for scalars.
if (tensor_proto.dims_size() == 0) {
blob.size.dims = blob.dims = 1; // To force 1-dimensional cv::Mat for scalars.
}
return blob;
}
+6 -7
View File
@@ -2193,7 +2193,7 @@ void ONNXImporter::parseSqueeze(LayerParams& layerParams, const opencv_onnx::Nod
{
Mat inp = getBlob(node_proto, 0);
Mat out = inp.reshape(1, outShape);
out.dims = outShape.size(); // to workaround dims == 1
out.size.dims = out.dims = outShape.size(); // to workaround dims == 1
addConstant(node_proto.output(0), out);
return;
}
@@ -2465,7 +2465,7 @@ void ONNXImporter::parseShape(LayerParams& layerParams, const opencv_onnx::NodeP
int dims = static_cast<int>(inpShape.size());
if (isInput1D)
dims = 1;
Mat shapeMat(1, dims, CV_64S);
Mat shapeMat(1, &dims, CV_64S);
bool isDynamicShape = false;
for (int j = 0; j < dims; ++j)
{
@@ -2473,7 +2473,6 @@ void ONNXImporter::parseShape(LayerParams& layerParams, const opencv_onnx::NodeP
isDynamicShape |= (sz == 0);
shapeMat.at<int64_t>(j) = sz;
}
shapeMat.dims = 1; // FIXIT Mat 1D
if (isDynamicShape)
{
@@ -2508,7 +2507,7 @@ void ONNXImporter::parseCast(LayerParams& layerParams, const opencv_onnx::NodePr
}
Mat dst;
blob.convertTo(dst, type);
dst.dims = blob.dims;
//dst.size.dims = dst.dims = blob.dims;
addConstant(node_proto.output(0), dst);
return;
}
@@ -2918,8 +2917,8 @@ void ONNXImporter::parseElementWise(LayerParams& layerParams, const opencv_onnx:
LayerParams constParams;
constParams.name = node_proto.input(i);
constParams.type = "Const";
// Non-constant propagated layers cannot output 1-d or 0-d tensors.
inp.dims = std::max(inp.dims, 2);
// Non-constant propagated layers cannot output 0-d tensors.
inp.size.dims = inp.dims = std::max(inp.dims, 1);
constParams.blobs.push_back(inp);
opencv_onnx::NodeProto proto;
@@ -3870,7 +3869,7 @@ void ONNXImporter::parseQConcat(LayerParams& layerParams, const opencv_onnx::Nod
for (size_t i = 2; i < num_inputs; i += 3)
{
Mat blob = getBlob(node_proto, i);
if (blob.size.dims() > inputShape.size())
if (blob.size.dims > inputShape.size())
{
inputShape = shape(blob);
}
+1 -1
View File
@@ -106,7 +106,7 @@ static std::string dataType2str(int dt)
static Mat getMatFromTensor2(const opencv_onnx::TensorProto& tensor_proto, const std::string base_path="")
{
Mat m = getMatFromTensor(tensor_proto, false, base_path);
m.dims = (int)tensor_proto.dims_size();
m.size.dims = m.dims = (int)tensor_proto.dims_size();
return m;
}
+2 -2
View File
@@ -130,7 +130,7 @@ Mat TFLiteImporter::parseTensor(const Tensor& tensor)
Mat res = Mat(shape, dtype, const_cast<void*>(data));
// workaround for scalars support
if (!tensor_shape || shape.size() == 1)
res.dims = 1;
res.size.dims = res.dims = 1;
return res;
}
@@ -287,7 +287,7 @@ void TFLiteImporter::populateNet()
Mat dataFP32;
data.convertTo(dataFP32, CV_32F);
// workaround for scalars support
dataFP32.dims = data.dims;
dataFP32.size.dims = dataFP32.dims = data.dims;
allTensors[op_outputs->Get(0)] = dataFP32;
continue;
}
+17 -17
View File
@@ -100,7 +100,7 @@ TEST_P(Test_NaryEltwise_Int, random)
Mat re;
re = net.forward();
EXPECT_EQ(re.depth(), matType);
EXPECT_EQ(re.size.dims(), 4);
EXPECT_EQ(re.size.dims, 4);
EXPECT_EQ(re.size[0], input1.size[0]);
EXPECT_EQ(re.size[1], input1.size[1]);
EXPECT_EQ(re.size[2], input1.size[2]);
@@ -175,7 +175,7 @@ TEST_P(Test_Const_Int, random)
Mat re;
re = net.forward();
EXPECT_EQ(re.depth(), matType);
EXPECT_EQ(re.size.dims(), 4);
EXPECT_EQ(re.size.dims, 4);
EXPECT_EQ(re.size[0], input1.size[0]);
EXPECT_EQ(re.size[1], input1.size[1]);
EXPECT_EQ(re.size[2], input1.size[2]);
@@ -281,7 +281,7 @@ TEST_P(Test_ScatterND_Int, random)
Mat re;
re = net.forward();
EXPECT_EQ(re.depth(), matType);
EXPECT_EQ(re.size.dims(), 4);
EXPECT_EQ(re.size.dims, 4);
ASSERT_EQ(shape(input), shape(re));
std::vector<int> reIndices(4);
@@ -364,7 +364,7 @@ TEST_P(Test_Concat_Int, random)
Mat re;
re = net.forward();
EXPECT_EQ(re.depth(), matType);
EXPECT_EQ(re.size.dims(), 4);
EXPECT_EQ(re.size.dims, 4);
EXPECT_EQ(re.size[0], input1.size[0]);
EXPECT_EQ(re.size[1], input1.size[1] + input2.size[1]);
EXPECT_EQ(re.size[2], input1.size[2]);
@@ -441,7 +441,7 @@ TEST_P(Test_ArgMax_Int, random)
Mat re;
re = net.forward();
EXPECT_EQ(re.depth(), CV_64S);
EXPECT_EQ(re.size.dims(), 3);
EXPECT_EQ(re.size.dims, 3);
EXPECT_EQ(re.size[0], inShape[0]);
EXPECT_EQ(re.size[1], inShape[2]);
EXPECT_EQ(re.size[2], inShape[3]);
@@ -510,7 +510,7 @@ TEST_P(Test_Blank_Int, random)
Mat re;
re = net.forward();
EXPECT_EQ(re.depth(), matType);
EXPECT_EQ(re.size.dims(), 4);
EXPECT_EQ(re.size.dims, 4);
EXPECT_EQ(re.size[0], 2);
EXPECT_EQ(re.size[1], 3);
EXPECT_EQ(re.size[2], 4);
@@ -568,7 +568,7 @@ TEST_P(Test_Expand_Int, random)
Mat re;
re = net.forward();
EXPECT_EQ(re.depth(), matType);
EXPECT_EQ(re.size.dims(), 4);
EXPECT_EQ(re.size.dims, 4);
EXPECT_EQ(re.size[0], 2);
EXPECT_EQ(re.size[1], 3);
EXPECT_EQ(re.size[2], 4);
@@ -631,7 +631,7 @@ TEST_P(Test_Permute_Int, random)
Mat re;
re = net.forward();
EXPECT_EQ(re.depth(), matType);
EXPECT_EQ(re.size.dims(), 4);
EXPECT_EQ(re.size.dims, 4);
EXPECT_EQ(re.size[0], 2);
EXPECT_EQ(re.size[1], 4);
EXPECT_EQ(re.size[2], 5);
@@ -705,7 +705,7 @@ TEST_P(Test_GatherElements_Int, random)
Mat re;
re = net.forward();
EXPECT_EQ(re.depth(), matType);
EXPECT_EQ(re.size.dims(), 4);
EXPECT_EQ(re.size.dims, 4);
ASSERT_EQ(shape(indicesMat), shape(re));
std::vector<int> inIndices(4);
@@ -823,7 +823,7 @@ TEST_P(Test_Cast_Int, random)
Mat re;
re = net.forward();
EXPECT_EQ(re.depth(), outMatType);
EXPECT_EQ(re.size.dims(), 4);
EXPECT_EQ(re.size.dims, 4);
ASSERT_EQ(shape(input), shape(re));
normAssert(outputRef, re);
@@ -865,7 +865,7 @@ TEST_P(Test_Pad_Int, random)
Mat re;
re = net.forward();
EXPECT_EQ(re.depth(), matType);
EXPECT_EQ(re.size.dims(), 4);
EXPECT_EQ(re.size.dims, 4);
EXPECT_EQ(re.size[0], 2);
EXPECT_EQ(re.size[1], 3);
EXPECT_EQ(re.size[2], 5);
@@ -940,7 +940,7 @@ TEST_P(Test_Slice_Int, random)
Mat out = net.forward();
Mat gt = input(range);
EXPECT_EQ(out.size.dims(), 4);
EXPECT_EQ(out.size.dims, 4);
EXPECT_EQ(out.size[0], gt.size[0]);
EXPECT_EQ(out.size[1], gt.size[1]);
EXPECT_EQ(out.size[2], gt.size[2]);
@@ -981,7 +981,7 @@ TEST_P(Test_Reshape_Int, random)
Mat re;
re = net.forward();
EXPECT_EQ(re.depth(), matType);
EXPECT_EQ(re.size.dims(), 4);
EXPECT_EQ(re.size.dims, 4);
EXPECT_EQ(re.size[0], outShape[0]);
EXPECT_EQ(re.size[1], outShape[1]);
EXPECT_EQ(re.size[2], outShape[2]);
@@ -1022,7 +1022,7 @@ TEST_P(Test_Flatten_Int, random)
Mat re;
re = net.forward();
EXPECT_EQ(re.depth(), matType);
EXPECT_EQ(re.size.dims(), 2);
EXPECT_EQ(re.size.dims, 2);
EXPECT_EQ(re.size[0], inShape[0]);
EXPECT_EQ(re.size[1], inShape[1] * inShape[2] * inShape[3]);
@@ -1062,7 +1062,7 @@ TEST_P(Test_Tile_Int, random)
Mat re;
re = net.forward();
EXPECT_EQ(re.depth(), matType);
EXPECT_EQ(re.size.dims(), 4);
EXPECT_EQ(re.size.dims, 4);
EXPECT_EQ(re.size[0], inShape[0] * repeats[0]);
EXPECT_EQ(re.size[1], inShape[1] * repeats[1]);
EXPECT_EQ(re.size[2], inShape[2] * repeats[2]);
@@ -1142,7 +1142,7 @@ TEST_P(Test_Reduce_Int, random)
Mat re;
re = net.forward();
EXPECT_EQ(re.depth(), matType);
EXPECT_EQ(re.size.dims(), 3);
EXPECT_EQ(re.size.dims, 3);
EXPECT_EQ(re.size[0], inShape[0]);
EXPECT_EQ(re.size[1], inShape[2]);
EXPECT_EQ(re.size[2], inShape[3]);
@@ -1219,7 +1219,7 @@ TEST_P(Test_Reduce_Int, two_axes)
Mat re;
re = net.forward();
EXPECT_EQ(re.depth(), matType);
EXPECT_EQ(re.size.dims(), 2);
EXPECT_EQ(re.size.dims, 2);
EXPECT_EQ(re.size[0], inShape[0]);
EXPECT_EQ(re.size[1], inShape[2]);
+2 -2
View File
@@ -965,7 +965,7 @@ TEST_P(Scale_untrainable, Accuracy)
net.setPreferableBackend(DNN_BACKEND_OPENCV);
Mat out = net.forward();
Mat ref(input.dims, input.size, CV_32F);
Mat ref(input.size, CV_32F);
float* inpData = (float*)input.data;
float* refData = (float*)ref.data;
float* weightsData = (float*)weights.data;
@@ -1060,7 +1060,7 @@ TEST_P(Crop, Accuracy)
for (int i = axis; i < 4; i++)
crop_range[i] = Range(offsetVal, sizShape[i] + offsetVal);
Mat ref(sizImage.dims, sizImage.size, CV_32F);
Mat ref(sizImage.size, CV_32F);
inpImage(&crop_range[0]).copyTo(ref);
normAssert(out, ref);
}
+1 -1
View File
@@ -1438,7 +1438,7 @@ TEST_P(Layer_FullyConnected_Test, Accuracy_01D)
Mat input(input_shape, CV_32F);
randn(input, 0, 1);
Mat output_ref = input.reshape(1, 1) * weights;
output_ref.dims = input_shape.dims;
output_ref.size.dims = output_ref.dims = input_shape.dims;
std::vector<Mat> inputs{input};
std::vector<Mat> outputs;