-
-
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
Blue noise sampling #3531
base: main
Are you sure you want to change the base?
Blue noise sampling #3531
Conversation
Hello @rougier! Thanks for updating the PR.
Comment last updated on November 04, 2018 at 17:41 Hours UTC |
Thanks, @rougier! It looks like this should also be added to To add a gallery example, make the directory |
skimage/util/noise.py
Outdated
Two-dimensional domain (width x height) over which to sample noise | ||
radius : float | ||
Minimum distance between samples | ||
k : int |
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.
k : int | |
k : int, optional |
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.
Thanks for submitting! I made several comments, most of them on the style, and few suggestions on the code itself.
skimage/util/noise.py
Outdated
Minimum distance between samples | ||
k : int | ||
Limit of samples to choose before rejection (typically k = 30) | ||
seed : int |
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.
seed : int | |
seed : int, optional |
skimage/util/noise.py
Outdated
|
||
This function implements the method introduced in "Fast Poisson Disk | ||
Sampling in Arbitrary Dimensions, Robert Bridson, Siggraph, 2007" for | ||
generating (fast) blue noise. |
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.
When we want to add a reference, we add a specific section for that. Take a look here for instance: https://github.com/scikit-image/scikit-image/blob/master/skimage/filters/thresholding.py#L318 Note also how to put a DOI.
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.
ok, done.
skimage/util/noise.py
Outdated
|
||
See also: | ||
--------- | ||
https://github.com/scikit-image/scikit-image/issues/2380 |
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.
The See also section is generally not used for that. Here, I would not refer to the issue...
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 removed it.
skimage/util/noise.py
Outdated
|
||
def blue_noise(shape, radius=0.01, k=30, seed=None): | ||
""" | ||
Function to add random noise of various types to a floating-point image. |
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.
Function to add random noise of various types to a floating-point image. | |
Add random noise of various types to a floating-point image. |
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.
Changed it (I wrongly copied it from the random_noise function)
skimage/util/noise.py
Outdated
|
||
""" | ||
|
||
def squared_distance(p0, p1): |
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.
That would be a bit overkill, no?
skimage/util/noise.py
Outdated
def in_limits(p): | ||
return 0 <= p[0] < width and 0 <= p[1] < height | ||
|
||
def neighborhood(shape, index, n=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.
Can you put comment to explain what the function is doing please?
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've added docstring for all of them.
skimage/util/noise.py
Outdated
I.remove([row, col]) | ||
return I | ||
|
||
def in_neighborhood(p): |
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.
def in_neighborhood(p): | |
def in_neighborhood(p, squared_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.
You're right. I've changed it but in the process some other functions are using implicit global variables. Would you prefer I tried to remove every inside function? I might be able to remove most of them (but not all).
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 think some of them are not necessary, especially the short ones, So, +1!
skimage/util/noise.py
Outdated
del points[i] | ||
Q = random_point_around(p, k) | ||
for q in Q: | ||
if in_limits(q) and not in_neighborhood(q): |
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.
if in_limits(q) and not in_neighborhood(q): | |
if in_limits(q) and not in_neighborhood(q, squared_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.
Done.
skimage/util/noise.py
Outdated
i = np.random.randint(len(points)) | ||
p = points[i] | ||
del points[i] | ||
Q = random_point_around(p, k) |
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.
Q = random_point_around(p, k) | |
Q = random_point_around(p, radius, k) |
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.
Done.
skimage/util/noise.py
Outdated
If provided, this will set the random seed before generating noise, | ||
for valid pseudo-random comparisons. | ||
|
||
Notes: |
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.
Dont use : signs in headers please :)
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.
Not sure I get this one...
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.
Sorry, I wanted to say title.
All titles must look like
title
-----
not
title:
------
:)
I've started to modify the source according to review but I think my code is too complicated and could probably be simplified. I'll try to look into that. |
Sounds great! Thanks @rougier |
skimage/util/noise.py
Outdated
---------- | ||
|
||
.. [1] Fast Poisson Disk Sampling in Arbitrary Dimensions, Robert Bridson, | ||
Siggraph, 2007. :DOI: 10.1145/1278780.1278807 |
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.
Siggraph, 2007. :DOI: 10.1145/1278780.1278807 | |
Siggraph, 2007. :DOI:`10.1145/1278780.1278807` |
I've found the implementation by @emulbreh (see https://github.com/emulbreh/bridson, MIT License) to be more clear and probably faster. I've slightly adapted it. |
skimage/util/noise.py
Outdated
queue.pop() | ||
for _ in range(k): | ||
|
||
# WARNING: p is not uniform sampled but we can live with it here |
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 still this line I don't understand, and you didn't reply to me about my suggestion
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.
Sorry, I did not see it. I need to pick k points around p in a torus (r,2r) and I used uniform polar coordinates introducing a bias when converted into Cartesian coordinates. I'll fix it and remove the comment.
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.
And the implementation by @emulbreh is right actually.
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'm not sure about the suggestion you're referring to
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.
LGTM.
The main task that remains is to right few unittests. This is necessary to include a new feature in scikit-image. Are you familiar with this? |
Yes. I will write some tests but I need to find relevant ones. Do I need to check both for potentially wrong arguments (this would require additional code for checking correctness of arguments such as for example negative sizes) and also expected statistical properties (approximate number of samples, mean distance between samples, etc.)? |
We usually do not perform extensive checks of parameters (you can have a look at other functions). IMO, it is not necessary to add more checks. I suggest to start by covering the existing code. Eventually, if other reviewers ask, we can add more. |
Hi sorry to jump in late. This code is very nice and I love the stippling application, but does it fit in the scope of scikit-image? I can't think of an application in biology, physics, astronomy etc. where one could use blue noise. If I'm wrong (please prove me wrong :-), the gallery example should try to show such a use case. Something like determining markers for a segmentation? |
A followup question: may it be of interest for SciPy integration? |
@emmanuelle No opinion on that. I'm fine if you prefer not to merge the PR. |
@rougier let's wait for other opinions; in #2380 both @jni and @JDWarner said that they saw places in the package where this could be used. But perhaps we need to be more explicit about the scope of scikit-image, for example in the contributers documentation (and I'm sure different devs have a slightly different view of the scope of the package: is it mostly for scientific applications? Also for some computer vision applications? Graphics applications? This makes it all the more important to talk and agree about the scope of scikit-image). |
@jni your thoughts here would be welcome |
Description
This PR implement blue noise sampling following proposal #2380. I'm not quite sure how to add the associated example in doc/examples.
Checklist
[It's fine to submit PRs which are a work in progress! But before they are merged, all PRs should provide:]
./doc/examples
(new features only)./benchmarks
, if your changes aren't covered by anexisting benchmark
[For detailed information on these and other aspects see scikit-image contribution guidelines]
References
[If this is a bug-fix or enhancement, it closes issue # ]
[If this is a new feature, it implements the following paper: ]
For reviewers
(Don't remove the checklist below.)
later.
__init__.py
.doc/release/release_dev.rst
.@meeseeksdev backport to v0.14.x