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
attempt to add 0d/1d mat support to OpenCV #23473
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 ERROR Problem is here:
It should be vise versa. |
modules/ts/src/ts_func.cpp
Outdated
@@ -515,7 +515,7 @@ void extract(const Mat& src, Mat& dst, int coi) | |||
void transpose(const Mat& src, Mat& dst) | |||
{ | |||
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 };
@@ -726,7 +727,6 @@ const _Tp* Mat::ptr(int y) const | |||
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
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.
@@ -2134,6 +2147,7 @@ class CV_EXPORTS Mat | |||
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
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.
@@ -40,7 +40,8 @@ PERF_TEST_P(PointsNum_Algo, solvePnP, | |||
projectPoints(points3d, rvec, tvec, intrinsics, distortion, points2d); | |||
|
|||
//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).
@@ -2432,6 +2439,7 @@ TEST(Mat1D, DISABLED_basic) | |||
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
>>>
@@ -1899,7 +1905,7 @@ TEST_P(Test_ONNX_layers, Quantized_Convolution) | |||
|
|||
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.