-
-
Notifications
You must be signed in to change notification settings - Fork 56.4k
attempt to add 0d/1d mat support to OpenCV #23473
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
For 1D case I (and other people) expect
Also accessing values No need to design "something" just take a look on numpy. a = np.array([1,2,3], dtype=int)
print(a)
print(a.shape) # (3,)
print(a.shape[0]) # 3
print(a.shape[1]) # usage ERRORProblem is here: It should be vise versa. |
modules/ts/src/ts_func.cpp
Outdated
| { | ||
| CV_Assert(src.data != dst.data && "Inplace is not support in cvtest::transpose"); | ||
| CV_Assert(src.dims == 2); | ||
| CV_Assert(src.dims <= 2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
transpose() for 1D/0D should be prohibited to avoid coding mistakes.
User should reshape mat to 2D first in explicit way.
modules/core/test/test_arithm.cpp
Outdated
| CV_Assert(src.dims == 2); | ||
| dst.create(src.size(), src.type()); | ||
| CV_Assert(src.dims <= 2); | ||
| dst.create(src.dims, src.size.p, src.type()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
createSameSize()
| int n = 3; | ||
| Mat_<float> B(1, &n); B << 1, 2, 3; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
n
use self-described names.
int shapeB[1] = { 3 };
| inline | ||
| uchar* Mat::ptr(int i0, int i1) | ||
| { | ||
| CV_DbgAssert(dims >= 2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no sense to use both arguments for 1D/0D cases.
|
I believe this supersedes #21059 |
|
👀 |
… partly supported!
…t work * also fixed a few remaining failures (hopefully) in dnn & core
dmatveev
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks invasive but will focus more deeply on the g-api changes.
| int dims; | ||
| //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions | ||
| int rows, cols; | ||
| int dummy = 153; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will remove it in one of the subsequent commits in a different pull request;
Let it stay here for a few weeks/months to catch the situation when Mat.size.p (when it points to rows or cols) is accessed outside of those 2 fields
opencv-alalek
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In comparison with #18594 there are too much changes in tests (equals to broken user code).
| Cv3d.undistortPoints(src, dst, cameraMatrix, distCoeffs); | ||
|
|
||
| assertEquals(src.size(), dst.size()); | ||
| assertEquals(src.cols(), dst.rows()); | ||
| assertEquals(src.rows(), dst.cols()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we want to swap rows/cols?
This doesn't look like a convenient behavior.
| //add noise | ||
| Mat noise(1, (int)points2d.size(), CV_32FC2); | ||
| int sz = (int)points2d.size(); | ||
| Mat noise(1, &sz, CV_32FC2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Requirement of test modification means that we would broke user code.
We could add new tests easily, but not to modify it.
We need compatibility code to support both inputs (old and new).
| Mat m(5, 100, CV_8UC1, Scalar::all(0)); | ||
| const Mat row2D = m.row(2); | ||
| EXPECT_NO_THROW(m1.copyTo(row2D)); | ||
| EXPECT_NO_THROW(row2D.copyTo(m1_copy)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Idea is to write set of simple independent tests with common predefined variables.
This line violates that rule as it modifies common variable (result affects checks below).
| { | ||
| std::string s; | ||
| s = cv::utils::dumpInputArray(noArray()); | ||
| EXPECT_EQ(s, "InputArray: noArray()"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Signature for _EQ is ASSERT_EQ(expected_reference, actual_result);.
Correct order of parameters are required to emit valid error messages.
Reference: https://github.com/opencv/opencv/blob/4.0.0/modules/ts/include/opencv2/ts/ts_gtest.h#L8196-L8200
GTEST_API_ AssertionResult EqFailure(const char* expected_expression,
const char* actual_expression,
const std::string& expected_value,
const std::string& actual_value,
bool ignoring_case);
| if (shape.empty()) | ||
| return 0; | ||
| //if (shape.empty()) | ||
| // return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just return 1 for 0D tensor?
| axis = (axis < 0) ? (dims + axis) : axis; | ||
| CV_DbgCheck(axis, axis >= 0 && axis < dims, ""); | ||
| CV_Assert(dims >= 0); | ||
| CV_Check(axis, axis >= -dims && axis <= dims, ""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
axis <= dims
We should not allow axis == dims.
It is not allowed in classic index/stride rules (e.g. in Python)
>>> a = [1, 2, 3]
>>> a[-3]
1
>>> a[-2]
2
>>> a[-1]
3
>>> a[0]
1
>>> a[1]
2
>>> a[2]
3
>>> a[3]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
>>>
| TEST_P(Test_ONNX_layers, Quantized_MatMul) | ||
| { | ||
| testONNXModels("quantized_matmul_uint8_weights", npy, 0.005, 0.007); | ||
| testONNXModels("quantized_matmul_uint8_weights", npy, 0.008, 0.015); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is happened?
updated
This is another attempt to add 0D/1D Mat support to OpenCV. In the era of deep learning, ChatGPT etc. we want to support ONNX well, so we want Mat/UMat to be able to represent 1D and 0D data w/o 0D/1D=>2D hack.
The previous patch is here:
#18594. Unlike in 18594, here we don't add any special "1d" flag to the header. Instead, for 1D Mat the header looks like:
for 0D Mat (not tested yet) there should be
In other words, most of the functions that could process 2D Mat's by using their Mat::rows, Mat::cols, data and step's should handle 1D/0D Mat's just fine, but the check
dims == 2(if any) should be changed withdims <= 2. Also, the functions should create output array more carefully, via nD versions of Mat::create().so far, OpenCV core tests seem to pass.
Let's see whether any other tests fail
Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
Patch to opencv_extra has the same branch name.