Detect lines transitioning to blobs in images I have the following images (in high resolution, uncompressed). When the process starts, the left image is displayed and it ends something similar to the right image.





The first image shows labyrinth-kind-of strucutres with sometimes only bright borders, sometimes dark borders and sometimes both. The second, middle image shows the transition to the last image: The lines are getting shorter and disconnect. In the end nearly all of the lines will be gone and little circles will be present.

My goal is to detect the transition from lines to blobs, so basically the center image. I need to know when the lines are vanishing or when the blobs are appearing (let's say there are more than 5). The detection doesn't have to be super precise, I just want roughly to know when the first bubbles start coming. Also the detection should be as fast as possible.



What I have tried so far

I am very new to signal processing, so I'm not very sure how to start. I am using python.

My own solution (doesn't work)

In my naive way I thought "These contrasts should be easy to detect.". So I played around with blurring the image a little bit (to remove noise, even though there is very few noise) and then comparing each pixel value to a threshold. I encountered three problems: 


There is a (varying) gradient in the background.
The contrast of the top left lines compared to their environment is a different than the contrast
of the lines on the bottom right (because of the gradient)
The lines are bright or dark


I then tried to somehow get the "local" contrast, so to compare the pixel value to the pixels around. I created a mask that selects only parts of the image, but this was (in my implementation) super slow. So I stopped with this way.

In addition I think it is harder to detect vanishing lines than appearing bubbles (?).

Blob detection

I found a blob detection page on scikit-image.org. I tried to use their algorithm and it is pretty good. I get the following result:



I used the transition image (the middle one of the top three images). The Difference Of Gaussian seems like what I want. But it is still detecting bigger "blobs" as you can see on the bottom right of the image wich I don't want. Also I'm not sure if this is the "default way to go" or if there are a lot better things which I'm just not thinking of.

Edit: The blob detection is very slow on my original data. So this is not an option except it can be speeded up a lot.

Canny edge detector

I tried to use the canny edge detector method as mentioned in the comments. But after some trying around I didn't get any good results. I end up with either way too much edges or no edges. Even after playing around and trying to smooth the image before or subtract, divide or multiply a smoothed image. But that may also just be because I don't know exactly how to do this. Out of my very limited knowledge I would say that the contrast is not good enough. But I don't know how to fix that.





So, to conclude: What is the best method to detect those blobs? And maybe, in addition: Is there a best python module to use? And if so, which one is it?
If you are not interested in picking out the frame that bubbles start forming and since the transition is (clearly) from order (clearly formed shapes) to disorder (mostly noise), you can use a feature based approach. That is, characterise the whole image with a few numbers.
An obvious feature here is image entropy. The typical (but not the only) way to calculate entropy of an image / signal is through its normalised histogram (you need to normalise it, to get to a probability).
Are there any differences between the histograms of the images?
Yes there are (at least, the ones that come with the question):

From left to right, we have the image with the well defined shapes (ordered), the middle state and on the right the final state where there is mostly background plus some noise.
The striking feature here is that when the image is ordered, the ridges that are well defined because they create contrast with their background create a bimodal histogram. One mode corresponds to the background (the lower one) and one mode corresponds to the &quot;foreground&quot; (the one that forms a &quot;shelf&quot; towards the right) or the worm-like ridges.
You can catch these differences in many different ways including (of course) distance from Gaussian distribution, skewness, etc. Where the image is going to end up is a set of pixels distributed normally, any deviation from that &quot;profile&quot; must be due to formation of those ridges (in this particular context).
If you try to measure (Shannon) entropy over these images, you get the following three values:
    Ordered: 7.2331079063161425
    Middle:  6.734680695379271
    Noise:   6.591988661960253

(These measurements come from skimage.measure.shannon_entropy() )
This number looks at the frequencies of occurence of the pixels and returns the number of bits required to describe the value of a pixel.
You might feel here that these numbers are contradicting: Low entropy means more order, high entropy means less order. &quot;Less order&quot; here means closer to an absolutely uniform distribution. That is, you cannot really predict what comes next, the image is entirely random.
But at the same time, this description might also help understanding what is going on here: The &quot;Ordered&quot; image alternates between two means (more preference on the lower ofcourse) and spans a wider range of highly probable grey tones and the &quot;Noisy&quot; image is basically $128 \pm \approx 70$ with diminishing probability.
Shannon entropy evaluated in this way looks at the pixel values independently of each other. But they are not. The meandering structure forms straight and curved points to the extent that if one pixel is &quot;on&quot;, it is highly likely that the pixel next to it is on as well. So, we are not talking about single pixel probablities any more.
To &quot;catch&quot; this kind of differences, you need a measure of entropy that is sensitive to them. One of them is Entropy as calculated through the co-occurence matrix.
The name is kind of self-descriptive but very briefly: The co-occurence matrix describes how the values of two different pixels that are some distance appart co-vary. Additionally, since we now talk about the distance between two pixels, we can also define a bearing. This offset, implies that the co-occurence matrix describes co-occurence along a direction.
The corresponding values now are:
    Ordered: 14.197350713914734
    Middle : 13.128723041575485
    Noisy  : 12.824963198002461

(These measurements come from mahotas.features.haralick() with return_mean=True. Otherwise, you get the value of each feature for each direction considered (typically, the 4 directions around a pixel))
We observe a similar trend.
The difference between the two ways of computing the entropy here is robustness and sensitivity. We do not have a long enough sample here, but it is likely that the haralick features would be more sensitive to structural changes than a single histogram.
Therefore, you can get a long enough set of images from the experiments, &quot;map&quot; how the value of this feature varies and then set up &quot;alarms&quot; by setting thresholds around specific ranges.
Hope this helps.