Skip to content

LineVirtualIterator #13869

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

Merged
merged 30 commits into from
Apr 13, 2020
Merged

LineVirtualIterator #13869

merged 30 commits into from
Apr 13, 2020

Conversation

chacha21
Copy link
Contributor

Proposal of LineVirtualIterator, an alternative to "LineIterator not attached to any mat".
This is basically the same implementation, replacing the address difference by a single "offset" variable. elemsize becomes irrelevant and considered to be 1. "step" is thus equal to size.width since no stride is expected.

related to #13843

Proposal of LineVirtualIterator, an alternative to "LineIterator not attached to any mat".
This is basically the same implementation, replacing the address difference by a single "offset" variable. elemsize becomes irrelevant and considered to be 1. "step" is thus equal to size.width since no stride is expected.
fixed warning
Copy link
Member

@alalek alalek left a comment

Choose a reason for hiding this comment

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

Please add some accuracy tests.


s = dy < 0 ? -1 : 0;
dy = (dy ^ s) - s;
istep = (istep ^ s) - s;
Copy link
Member

Choose a reason for hiding this comment

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

"undefined behavior"

Lets try to avoid that.
Compilers are smart enough (or at least this is not required in non "heavy" constructor calls).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure to understand this one. This is the LineIterator implementation; is there a problem here ?

instead of being too conservative, the new implementation gets rid of "offset/step" and only keeps a "Point currentPos" up to date.

left_to_right is renamed to forceLeftToRight as suggested (even for the old LineIterator)

assert() replaced by CV_Assert() (even for the old LineIterator)
@chacha21
Copy link
Contributor Author

chacha21 commented Feb 23, 2019

some suggested improvements have been made in the new commit.
However, adding "accuracy tests" is a new step for me in my learning curve of OpenCV contributing, I still have to learn it.

[edit]
current commit is broken, I had implemented a broken test that mislead me

[edit2]
fixed

+fixed last commit so that LineVirtualIterator gives at least the same results as LineIterator

+added a new constructor that does not require any Size, so that no clipping is done and iteration occurs from pt1 to pt2. This is done by adding a spatial offset to pt1 and pt2 so that the same implementation is used, the size being in that case the spatial size between pt1 and pt2
fixed warnings
fixed whitespace
trailing whitespace
+added a new constructor that takes a Rect rather than a Size. It computes the line pt1->pt2 that clips that rect.
Yet again, this is still based on the same implementation, thanks to the Size and the currentPosOffset that can artifically consider the origin of the rect at (0,0)
@chacha21
Copy link
Contributor Author

chacha21 commented Feb 24, 2019

I still did not update the doc in the source code, I am first waiting to know whether the pull request is accepted or not

@alalek alalek mentioned this pull request Mar 13, 2019
@asmorkalov
Copy link
Contributor

@chacha21 Do you have a chance to work on some tests for the new feature?

@asmorkalov asmorkalov requested a review from VadimLevin January 10, 2020 07:21
Copy link
Contributor

@VadimLevin VadimLevin left a comment

Choose a reason for hiding this comment

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

Thanks for your work!

There is a couple of improvements those can be done.

Also consider to use const where it is possible and add spaces between math operators e.g. pos.x+offset.x%2 is quite unreadable.

@@ -4717,7 +4717,7 @@ class CV_EXPORTS LineIterator
not to depend on the ordering of pt1 and pt2 parameters
*/
LineIterator( const Mat& img, Point pt1, Point pt2,
int connectivity = 8, bool leftToRight = false );
int connectivity = 8, bool forceLeftToRight = false );
Copy link
Contributor

Choose a reason for hiding this comment

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

Documentary string should be updated too (forceLeftToRight).

@asmorkalov asmorkalov removed the pr: needs test New functionality requires minimal tests set label Jan 14, 2020
Added offset as random test data.
@VadimLevin
Copy link
Contributor

Thank you for your work!
Please, fix documentary string for LineIterator because you've changed the parameter name and add documentary strings for implemented functionality. But I suppose, last item should be done after @alalek approve code changes.

@vpisarev
Copy link
Contributor

vpisarev commented Feb 3, 2020

@chacha21, thank you for the contribution! I think, in this class it makes sense to modify implementation of Bresenham algorithm to operate directly on the pixel coordinates. With current implementation it's so slow that we can basically use the original class, just add an extra constructor to it.

const int offset = minusStep + (plusStep & mask);
const size_t flattenedCoord = (currentPos.y - currentPosOffset.y) * size.width + (currentPos.x - currentPosOffset.x) + offset;
currentPos.y = static_cast<int>((flattenedCoord / size.width) + currentPosOffset.y);
currentPos.x = static_cast<int>((flattenedCoord % size.width) + currentPosOffset.x);
Copy link
Contributor

@vpisarev vpisarev Feb 3, 2020

Choose a reason for hiding this comment

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

basically, I mean that these 2 lines (currentPos.y=...; currentPos.x=...;) should be removed; instead, you should update currentPos directly using the Bresenham algorithm

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The current implementation is rather far from standard Bresenham's algorithm descriptions, so it is not that straightfoward to rewrite differently all the cases in both 4 and 8 connectivity.

@asmorkalov
Copy link
Contributor

@chacha21 @vpisarev do you have consensus on the solution?

@vpisarev
Copy link
Contributor

@chacha21, @asmorkalov, I've updated the implementation, made it one class, not two. Hopefully, it's good enough to be merged

Copy link
Member

@alalek alalek left a comment

Choose a reason for hiding this comment

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

See comments in previous patch about that: #13843 (mentioned in PR description)

added one perfectly predictable check; in theory, since ptmode is set in the end of the constructor in the header file, the compiler can figure out that it's always true/false and eliminate the check from the inline `LineIterator::operator++()` completely
in the most common case (CV_8UC3) eliminated the check from the loop
@vpisarev
Copy link
Contributor

vpisarev commented Apr 8, 2020

@alalek, can we merge it?

@alalek alalek merged commit f351653 into opencv:master Apr 13, 2020
@chacha21 chacha21 deleted the LineVirtualIterator branch April 13, 2020 07:28
a-sajjad72 pushed a commit to a-sajjad72/opencv that referenced this pull request Mar 30, 2023
* LineVirtualIterator

Proposal of LineVirtualIterator, an alternative to "LineIterator not attached to any mat".
This is basically the same implementation, replacing the address difference by a single "offset" variable. elemsize becomes irrelevant and considered to be 1. "step" is thus equal to size.width since no stride is expected.

* Update drawing.cpp

fixed warning

* improvement of LineVirtualIterator

instead of being too conservative, the new implementation gets rid of "offset/step" and only keeps a "Point currentPos" up to date.

left_to_right is renamed to forceLeftToRight as suggested (even for the old LineIterator)

assert() replaced by CV_Assert() (even for the old LineIterator)

* fixed implementation

+fixed last commit so that LineVirtualIterator gives at least the same results as LineIterator

+added a new constructor that does not require any Size, so that no clipping is done and iteration occurs from pt1 to pt2. This is done by adding a spatial offset to pt1 and pt2 so that the same implementation is used, the size being in that case the spatial size between pt1 and pt2

* Update imgproc.hpp

fixed warnings

* Update drawing.cpp

fixed whitespace

* Update drawing.cpp

trailing whitespace

* Update imgproc.hpp

+added a new constructor that takes a Rect rather than a Size. It computes the line pt1->pt2 that clips that rect.
Yet again, this is still based on the same implementation, thanks to the Size and the currentPosOffset that can artifically consider the origin of the rect at (0,0)

* revert changes

revert changes on  original LineIterator implementation, that will be superseded by the new LineVirtualIterator anyway

* added test of LineVirtualIterator

* More tests

* refactoring

Use C++11 chained constructors
Improved code style

* improve test

Added offset as random test data.

* fixed order of initialization

* merged LineIterator and VirtualLineIterator

* merged LineIterator & VirtualLineIterator

* merged LineIterator & VirtualLineIterator

* merged LineIterator & VirtualLineIterator

* made LineIterator::operator ++() more efficient

added one perfectly predictable check; in theory, since ptmode is set in the end of the constructor in the header file, the compiler can figure out that it's always true/false and eliminate the check from the inline `LineIterator::operator++()` completely

* optimized Line() function

in the most common case (CV_8UC3) eliminated the check from the loop

Co-authored-by: Vadim Pisarevsky <vadim.pisarevsky@gmail.com>
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.

5 participants