Skip to content

better accuracy for _rotatedRectangleIntersection() (proposal for #23546)#23690

Merged
asmorkalov merged 16 commits intoopencv:4.xfrom
chacha21:rotatedRectangleIntersection_precision
May 30, 2023
Merged

better accuracy for _rotatedRectangleIntersection() (proposal for #23546)#23690
asmorkalov merged 16 commits intoopencv:4.xfrom
chacha21:rotatedRectangleIntersection_precision

Conversation

@chacha21
Copy link
Copy Markdown
Contributor

@chacha21 chacha21 commented May 26, 2023

_rotatedRectangleIntersection() can be (statically) customized to use double instead of float for better accuracy

this is a proposal for experimentation around #23546

for better accuracy, _rotatedRectangleIntersection() could use double. It will still return cv::Point2f list for backward compatibility, but the inner computations are controlled by a typedef

  • I agree to contribute to the project under Apache 2 License.
  • 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
  • The PR is proposed to the proper branch
  • There is a reference to the original bug report and related work
  • There is accuracy test, performance test and test data in opencv_extra repository, if applicable
    Patch to opencv_extra has the same branch name.
  • The feature is well documented and sample code can be built with the project CMake

…ad of float for better accuracy

for better accuracy, _rotatedRectangleIntersection() could use double
it will still return cv::Point2f list for backward compatibility, but the inner computations are controlled by a typedef
dkurt
dkurt previously requested changes May 26, 2023
Copy link
Copy Markdown
Member

@dkurt dkurt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think that it might be overhead for this function. Is there a chance to find exact place where the corner points are missed? It seems to me that there is a logical bug somewhere rather than just precision issue.

@chacha21
Copy link
Copy Markdown
Contributor Author

chacha21 commented May 26, 2023

I do think that it might be overhead for this function. Is there a chance to find exact place where the corner points are missed? It seems to me that there is a logical bug somewhere rather than just precision issue.

I have logged all numeric values taken by the local variables of _rotatedRectangleIntersection, with a std::setprecision(19) precision.
There are differences in accuracy that will ultimately trigger different code paths.
For instance atfer

            const precision_t t1 = (vx2*y21 - vy2*x21)*detInvScaled;
            const precision_t t2 = (vx1*y21 - vy1*x21)*detInvScaled;

In double case, at some point, one can observe t1=0.9999999344595517092 while in float case it will be t1=1.000000119209289551. Juste after that, t1 is compared to 1, and different behaviour starts here.

I tried to reorder/change some computations to avoid accumulating too much error, but so far I could only get right results with double.

@chacha21
Copy link
Copy Markdown
Contributor Author

Interesting : I tried to add

normalizationScale = std::exp2(std::round(std::log2(normalizationScale)));

in order to force the normalizationScale to be a power of 2 and let it represented as an exact IEEE754 value, so that scaling by normalizationScale is just a shift in exponent.
In that case, results seem to be better even in float.

chacha21 added 2 commits May 26, 2023 15:04
…le instead of float for better accuracy"

This reverts commit 71d6f29.
forcing normalizationScale to be a power of 2 seems to be better for accuracy, since scaling by normalizationScale will result in a mere shift in exponent
@dkurt
Copy link
Copy Markdown
Member

dkurt commented May 26, 2023

@dkurt dkurt linked an issue May 26, 2023 that may be closed by this pull request
4 tasks
Added accuracy test for opencv#23546
@chacha21
Copy link
Copy Markdown
Contributor Author

chacha21 commented May 26, 2023

@chacha21, can you please add a testcase from #23546 to https://github.com/opencv/opencv/blob/4.x/modules/imgproc/test/test_intersection.cpp?

Done, but now there is a regression with accuracy_21659.
I am investigating

@chacha21
Copy link
Copy Markdown
Contributor Author

chacha21 commented May 26, 2023

After the fix of const float s = adjustToZero(...) , totally removing the "normalizationScale" brings no regression in test_intersection.
If it is confirmed and that no new test proves the utility of normalizationScale, it can be eventually removed.

@dkurt dkurt self-assigned this May 26, 2023
@dkurt dkurt dismissed their stale review May 26, 2023 16:12

done

chacha21 added 2 commits May 26, 2023 19:40
using adjustToZero(..., samePointEps) does not work, though, because samePointEps is not a fixed valeu and depend on the input.
using adjustToZero(..., samePointEps) triggers regressions in test_intersection
dkurt
dkurt previously approved these changes May 26, 2023
by ordering the computation of s=A*x+B*y+C differently, it seems that normalizationScale and adjustToZero can just be get rid of
@dkurt dkurt dismissed their stale review May 27, 2023 05:37

Need to check updated code

chacha21 added 2 commits May 28, 2023 14:50
fixed commented code to understand code history
only the sign of A*x+B*y+C is important, so the code can be simplified to save one arithmetic operation, perhaps avoiding one more accuracy error accumulation
Copy link
Copy Markdown
Member

@dkurt dkurt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, thank you!

no changes in computations, just comments and refactoring as suggested for the sake of clarity
@asmorkalov asmorkalov merged commit 93d4902 into opencv:4.x May 30, 2023
@asmorkalov asmorkalov added this to the 4.8.0 milestone May 30, 2023
@asmorkalov asmorkalov mentioned this pull request May 31, 2023
thewoz pushed a commit to thewoz/opencv that referenced this pull request Jan 4, 2024
…ction_precision

better accuracy for _rotatedRectangleIntersection() (proposal for opencv#23546) opencv#23690

_rotatedRectangleIntersection() can be (statically) customized to use double instead of float for better accuracy
this is a proposal for experimentation around opencv#23546

for better accuracy, _rotatedRectangleIntersection() could use double. It will still return cv::Point2f list for backward compatibility, but the inner computations are controlled by a typedef

- [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
thewoz pushed a commit to thewoz/opencv that referenced this pull request May 29, 2024
…ction_precision

better accuracy for _rotatedRectangleIntersection() (proposal for opencv#23546) opencv#23690

_rotatedRectangleIntersection() can be (statically) customized to use double instead of float for better accuracy
this is a proposal for experimentation around opencv#23546

for better accuracy, _rotatedRectangleIntersection() could use double. It will still return cv::Point2f list for backward compatibility, but the inner computations are controlled by a typedef

- [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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

rotatedRectangleIntersection does not return all intersection points as expected

4 participants