JuliaImages / ImageSegmentation.jl

Partitioning images into meaningful regions
Other
47 stars 23 forks source link

Added normalized graph cut #8

Closed tejus-gupta closed 5 years ago

tejus-gupta commented 7 years ago

Segments graph using recursive two-way normalized graph cut as described in this paper - Normalized Cuts and Image Segmentation

tejus-gupta commented 7 years ago

Since adjacency matrix for grid connectivity based graphs are sparse, the paper used Lanczos solver. For small matrices eigs(D-W, D, nev = 2) (this uses Lanczos solver for real symmetric matrices) wasn't giving accurate results. What could I be doing wrong? Should I read how Lanczos algorithm works? This step is the slowest step in the algorithm.

timholy commented 7 years ago

I assume you're using the eigs implementation in Base? If you have a good test case that demonstrates the problem, I'd definitely report it as a bug. There are folks who know that part of Julia better than me, and perhaps they might help. I assume you noticed the tol and maxiter keyword arguments, but they didn't help?

One other general comment: since this is purely graph-theoretical, have you considered whether this part of the algorithm should live in a different repository? I'm not at all opposed to having it here, but if it's of use outside of image processing perhaps it would be better in a graphs-oriented package?

tejus-gupta commented 7 years ago

As far I know, the normalized graph-cut problem and the algorithm were first introduced in the context of image segmentation. If this algorithm is more generally used, I agree that this should be in a graph-oriented package.

timholy commented 7 years ago

From reading the algorithm, to me it looks generally useful. Perhaps @sbromberger could comment?

sbromberger commented 7 years ago

This looks very interesting.

@tejus-gupta - We'd have to adapt it a bit to be generally applicable to LightGraphs, but if you're up for the discussion, please feel free to file a WIP PR at https://github.com/JuliaGraphs/LightGraphs.jl and we can start the review.

One thing to start: we should not assume that weights will always return a SparseMatrixCSC – the guarantee is that it's something that is "Array-like" (supports a 2-dimensional getindex.

sbromberger commented 7 years ago

cc @jpfairbanks to weigh in here since this is squarely in one of his (many) areas of expertise.

timholy commented 7 years ago

I interpret the above discussion as saying that the core graph algorithm should live in LightGraphs, and the image-related preparation/postprocessing can go here. Please link any LightGraphs PR to this issue.

jpfairbanks commented 7 years ago

@timholy Yes, normalized graph cut is a generic graph algorithm that can go in lightgraphs. The parts that are image specific would be calculating the edge set and weights from the pixel values. We would not want an algorithm in lightgraphs that took an image as the input. But once you have extracted a graph (with or without weights), then LG can take over. Turning the segments back into sets of pixel locations or whatever you want to do with them should live in this package.

tejus-gupta commented 7 years ago

I am sorry for the delayed reply. I will open the pull request right away.

timholy commented 5 years ago

Is this entirely superseded by https://github.com/JuliaGraphs/LightGraphs.jl/pull/736, or is there an image-specific component here?

tejus-gupta commented 5 years ago

I didn't include the code for constructing a region adjacency graph from an image and so this is entirely replaced by https://github.com/JuliaGraphs/LightGraphs.jl/pull/736.

I think we should add a generic function to create a region adjacency graph from an image and advice the user to use graph clustering methods available in other packages. G = region_adjacency_graph(img, weight_fn, r) will construct graph G with nodes as each pixel in img and edges between each pair of pixel index i and j if |i-j|<r with weight weight_fn(i, img[i], j, img[j]). We can include an example of constructing G from an image and using normalized_cut to segment it.

timholy commented 5 years ago

Thanks. I'll close this, and we can implement those good ideas in separate PRs.