-
Notifications
You must be signed in to change notification settings - Fork 21
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
[Feature Request] Periodic connected_components #71
Comments
For ad-hoc usage, how about the "padding + f + cropping" strategy? # or `BorderArray` as lazy container
img_p = padarray(img, Pad(:circular,1,1)) # from ImageFiltering.jl
out = label_components(img_p)
out[2:end-1, 2:end-1] I'm not very sure if we want to expose a keyword to control the boundary condition; even if we do, we might just provide another wrapper function, e.g., # may not work, but you can get the idea
function with_border(f, img, boundary)
img_p = padarray(img, boundary)
out = f(img_p)
return out[axes(img)...]
end
with_border(img, Pad(:circular, 1, 1)) do img_p
f(img_p)
end This is more composable to me. For |
Hmm, this won't actually produce the correct behaviour, e.g. as:
You can see that e.g. clusters 10 and 12 should share a label. The resultant labelled image does contain the desired information though, if you scan along the edges and find the union of sets for each edge and it's off-dimension neighbours. I previously implemented things exactly like that - fairly performant, but clusmy and awkward to deal with extra dimensions. My implementation was as below... it's not pretty.
|
Thanks for pointing out the difference. From a performance perspective, how about separating the loop into the boundary part and inner part so that we can skip the additional I'm still very new to morphology so still don't know the |
The only issue I see with this solution is that I think the best we can do is something like:
This results in n+1 traversals of This would go in between the first and second pass of the CCL algorithm (e.g. here), but should function in much the same way as the first pass does. Do you know how to use ntuple to generate |
For most practical usages, edges only possess less than 1% pixels, right? How inefficient could it be?
Does |
The answer is "surprisingly efficient". For example, to access a 100x100 array at edge sites only using a
Whether you consider this good or not is trickier - a linear scaling here is pretty much the worst-case scenario. When we reverse the order of the loops, we get:
So definitely faster (by 5x). I wonder why that is - it should be much quicker the other way round, but maybe some weird optimisation is happening behind the scenes from getindex?
Yes, it looks like it works, but I think it's not known at compile time (vs ntuple?) |
Any developments on this since then? It would also be useful if the |
Yes, I wrote a version of this which works using TiledIteration.jl, as it has utilities to refer to edge regions of nD structures. I didn't really get a clean integration with ImageMorphology, but this gist does provide the functionality, and it seems to work for my use case. There's also a function which can operate on a subset of an array, |
I make a lot of use of connected_components in 2 and 3 dimensions, and for several problems it's useful to have periodic boundary conditions such that clusters can roll over, e.g the matrix on the left should return the labels on the right.
I already implemented this within ImageMorphology, but I'm struggling to integrate how it calls without disturbing default behaviour.
Two changes only:
As well,
half_pattern
needs afull_pattern
equivalent, e.g:Obviously this comes with a performance hit as we compare more indices, but it's not too serious and multiple dispatch should mean only users of the periodic feature have to suffer it.
Either way, if anybody knows how to integrate this sensibly, it'd be handy.
The text was updated successfully, but these errors were encountered: