I'm trying to automatically calculate particles sizes histogram for images like this one:
Common threshold and segmentation doesn't seem to work. What filters and algorithms do you suggest to be used?
Signal Processing Stack Exchange is a question and answer site for practitioners of the art and science of signal, image and video processing. It only takes a minute to sign up.
Sign up to join this communityHere is what I experimented with:
Use ELSD to generate elliptic contours. You could basically use any edge detector, but since in the following stages I will benefit from circle detectors, it is good to already have some geometrical edges. Here is what the output looks like:
Collect all circular (also non-circular) edges via collecting the channels into a single image. This can also be done via simple thresholding. Again, the output looks like:
I will denote this image to be $C$.
We will now compute the circular hough transform on this image. However, there are many spheres (which appear to be circular) in varying radii. Thus, we select a range $\mathbf{r}=\{9, 12, 15..150\}$ to be the expected radii per hough transform. The pseudocode looks like:
$c_x$ $\leftarrow$ $\emptyset$, $c_y$ $\leftarrow$ $\emptyset$
for all ($r_i \in \mathbf{r}$) $\{$
{x, y} = hough_circles($C$, $r_i$)
$c_x \leftarrow \{c_x \cup x \}$
$c_y \leftarrow \{c_y \cup y \}$
$\}$
Depending on the peaks of the accumulator, Hough might report multiple center locations. A simple clustering might help avoiding this (Just average the close-by centers).
The final image with the resulting centers overlayed (in different colors), looks like:
You could customize the radius to be robust to different circles. Moreover, one can use elliptic Hough transform to have a better coverage of the particles (as some of them are not circular). Finally, the much-occluded large circles can be obtained after masking out the small ones - even with the help of a distance transform. If the false circle hypothesis are desired to be eliminated, you can always reduce the Hough sensitivity. Or you could always render the contours of the circle and compare to the detected edges.