-
-
Notifications
You must be signed in to change notification settings - Fork 55.8k
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
Fixes matrix expression bug which happens when Scalar in addition pas… #16597
base: 3.4
Are you sure you want to change the base?
Conversation
I missed the superres test on my VM, seems it was disabled because of long-ness. Problem is here where SSIM is calculated for the test case. I'll take a look. |
@saskatchewancatch Could add test for the bug to prove the solution? |
Some code for tests:
Current 3.4.9/4.2.0 output
|
I propose integrating alalek's suggestion like such: diff --git a/modules/core/test/test_operations.cpp b/modules/core/test/test_operations.cpp
index dd91617537..d2ff870559 100644
--- a/modules/core/test/test_operations.cpp
+++ b/modules/core/test/test_operations.cpp
@@ -292,6 +292,16 @@ bool CV_OperationsTest::TestMat()
CHECK_DIFF(4.0 * (maskMat1 | maskMat1), maskMat4);
CHECK_DIFF((maskMat4 | maskMat4)/4.0, maskMat1);
+ //Multi-channel Scalar addition tests
+ Mat multiChannel_2x2__1_2_3(Size(2, 2), CV_8UC3, Scalar(1, 2, 3));
+ Mat multiChannel_2x2__6_2_3(Size(2, 2), CV_8UC3, Scalar(6, 2, 3));
+ Mat multiChannel_2x2__7_9_11(Size(2, 2), CV_8UC3, Scalar(7, 9, 11));
+ Mat multiChannel_2x2__11_7_3(Size(2, 2), CV_8UC3, Scalar(11, 7, 3));
+
+ CHECK_DIFF(multiChannel_2x2__6_2_3, multiChannel_2x2__1_2_3 + 5);
+ CHECK_DIFF(multiChannel_2x2__7_9_11, 2 * multiChannel_2x2__1_2_3 + 5);
+ CHECK_DIFF(multiChannel_2x2__11_7_3, multiChannel_2x2__1_2_3 + 5 * Scalar(2, 1, 0));
+
#if !MSVC_OLD
CHECK_DIFF(2.0 * (maskMat1 * 2.0) , maskMat4);
#endif |
Right. It is better to create separate test case (it is hard to maintain or debug huge tests), like:
|
Thank you for test suggestions @alalek Between the tests you provided and the ones that already exist in test_operations.cpp, the optimization branches that were touched in this PR are tested. |
if (e.a.channels() == 1) | ||
cv::add(dst, e.s, dst); | ||
else | ||
cv::add(dst, e.s[0], dst); |
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.
Both code branches are equal to:
cv::add(dst, e.s[0], dst);
so proposed condition doesn't make sense.
The real problem is how input "double" is stored through Scalar
:
5
isScalar(5, 0, 0, 0)
- or
5
isScalar:all(5)
- also tests should properly handle
+ Scalar(5, 0, 0, 0)
andScalar:all(5)
.isReal()
check is not correct if we try to use Scalar::all(5)
approach.
Probably we should raise exceptions on operations like multichannel_mat + just scalar
.
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.
@alalek Thanks for review, to address your feedback:
-
Yes, that if/else is redundant. I will just replace with
cv::add(dst, e.s, dst);
This is what will properly handle OP'smulti-channel Mat + multi-channel scalar
issue. -
Raising exception in case of
mulitchannel_mat + just_scalar
is fine imo but I think it's better handled in a separate PR, whereisReal()
issue can be fully sorted out. That may take longer as the solution cannot be implemented inside matrix_expressions.cpp and probably requires handling inside lower level arithmetic operation handlers. -
As for this PR, I will change the tests above so that the
just scalar
is changed to the Scalar form: ex)res = multiChannel_2x2__1_2_3 + Scalar(5, 0, 0);
, and then add the tests Scalar::all test you suggested.
This PR at least will fix OP's alpha blending issue and strengthen against regressions with the added tests. Is this fine?
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.
Patch is fine.
But it explodes another problem: multiChannel + 5.0
result is not well defined.
Need to take a look on this in details.
The superres test is the problem. In the test, a multichannel matrix is being added to a double constant. As per issue 16739, and above discussion, this is a grey area. I propose this adjustment for diff --git a/modules/superres/test/test_superres.cpp b/modules/superres/test/test_superres.cpp
index b0d4122f6e..b98258484f 100644
--- a/modules/superres/test/test_superres.cpp
+++ b/modules/superres/test/test_superres.cpp
@@ -154,8 +154,8 @@ void DegradeFrameSource::reset()
double MSSIM(cv::InputArray _i1, cv::InputArray _i2)
{
- const double C1 = 6.5025;
- const double C2 = 58.5225;
+ const Scalar C1(6.5025, 6.5025, 6.5025);
+ const Scalar C2(58.5225, 58.5225, 58.5225);
const int depth = CV_32F; This makes all tests pass. |
Right. |
jenkins cn please retry a build |
…ses isReal test
Fixes #16538
Unit test is under work. Coming shortly.
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.