-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Added float support for radius and centre in circle_perimeter funct... #1441
base: main
Are you sure you want to change the base?
Conversation
skimage/draw/_draw.pyx
Outdated
|
||
cdef double dceil = 0 | ||
cdef double dceil_prev = 0 | ||
cdef Py_ssize_t y = <int> round(radius) |
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 would add in the docstring that float values are rounded.
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 don't know if it's not correct, but for sure, not ideal :)
For Bresenham, we must consider the closest pixels from the circle. For Andres, it might be more subtle.
And the same work must be done for other shapes for consistency.
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.
69f1532
to
dc52ded
Compare
Seems good to me. @stefanv Can you have a look ? |
skimage/draw/_draw.pyx
Outdated
@@ -392,12 +383,16 @@ def circle_perimeter(Py_ssize_t cy, Py_ssize_t cx, Py_ssize_t radius, | |||
d = d + 2 * (y - x - 1) | |||
y = y - 1 | |||
x = x + 1 | |||
|
|||
ry = (np.array(rr, dtype=np.float_) + cy) |
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.
float
or np.float64
That looks fine to me. |
skimage/draw/tests/test_draw.py
Outdated
[1, 1, 1, 1, 1, 0, 0, 0], | ||
[0, 0, 0, 0, 0, 0, 0, 0], | ||
[0, 0, 0, 0, 0, 0, 0, 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.
looks like a square. A larger radius perhaps?
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.
@bewithaman
Maybe you can choose a large matrix and set it's values by using the equation of a circle x**2 + y**2 = r**2
for testing
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.
@vighneshbirodkar Are you suggesting to match just few points or whole matrix, because in the second case I think tests will fail.
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.
@bewithaman I think @vighneshbirodkar is suggesting that you make the circle large enough that a person can see it is an actual circle (because here it looks like a square)
@jaimefrio \ cc @stefanv |
|
||
ry = (np.array(rr, dtype=np.float) + cy) | ||
rx = (np.array(cc, dtype=np.float) + cx) | ||
ry = np.round(ry) |
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.
Would it make sense to do ry = np.round(ry).astype(int)
here to avoid allthe astype
calls further down? Same for rx
.
Some general comments:
And a major objection: I'm afraid the implementation is not correct... I haven't been able to find a copy of the Andres paper that isn't behind a paywall, but the Bresenham algorithm, as implemented, makes lots of implicit assumptions on it working on integers. Translating everything to floating point verbatim and then rounding isn't going to necessarily work, especially given the following behavior of
i.e. ties are resolved to the nearest even number. If you give it an integer radius and at least one of the center coordinates has fractional part 0.5, you are going to get an awful result:
You could reimplement the algorithm, keeping a floating point error, but still using integer coordinates. But I don't think you can get away with computing 1/8-th of the circle only, or with doing the computations for the circle centered at Before going down that route I'd reassess the need for floating point values in this function... |
@jaimefrio I don't think whether you specify the radius as a floating point value or as an integer makes much of a difference--the circle path will always be "along" non-integers. It may be that Bresenheim was always broken for circles, in which case we should rewrite it anyway. float vs int -- np.float should translate to double anyway, no? I don't think we've set any policy around this so far. |
@jaimefrio Oh, and thank you for spotting this oversight! |
Oh yes, The issue with the interface is that, with its current implementation, floating point values passed in will raise an error. After this PR they won't for I don't think Bresenham is broken. The issue with this PR is that it is selecting a sequence of non-integral points that it then rounds. There is the issue with numpy's round pointed above. My other concern is that Bresenham's algorithm is supposed to select consecutive pixels where |
For the record, NumPy's rounding behavior is correct per IEEE standards. You have to do it that way to minimize systematic error. I'm not intimately familiar with the Brensham algorithm though, so I'll defer judgement on the rest of the discussion. |
@jaimefrio Indeed, we need a contiguous circle. |
798411d
to
ee3b431
Compare
I don't think the Bresenham algorithm required integer parameters. @jaimefrio Could you take another look, also at this? |
Would a different rounding algorithm (not round to even— |
...ion
Fixes #1415