2
$\begingroup$

I use python3 script to find out the area proportion of pixel clusters, threads and points in my image. They are originally 8-bit greyscale TIFF images with a resolution of 2048x2168 pixels. I have binarised it into an image composing of the matrix (white) and component particles (black). The particles have random morphologies. I would like to widely categorise them as:

  • Points which can range between 1x1 to 3x3 blocks of independent square pixels completely surrounded by the matrix
  • Threads which are linear or diagonal sets of continuous pixels of at least 3 pixels in length and at most 3 pixels in width
  • Clusters which are any randomly shaped closed morphologies with more than 10 pixels in overall area (or any arbitrary high value)
  • Others which by any chance is not included the three listed above

Here is an Example(400x400) portion of the image.

First of all, I am confused about the order of progress in this situation. I could scan the whole image pixel by pixel and extract the points in my first step. A second scanning can see for threads and final scanning can look for clusters using boundary tracing.

As you can see, the component is spread in a very uneven manner. To a human eye, the threads appear as blocks with very low aspect ration (AR). Points as noises and clusters as blocks of distinguishable larger areas. Therefore the accuracy level of this classification scheme does not needfully be a high score. The objective, however, is minimal user interaction (fully automatic). One another thing to note is that holes within clusters or threads (that does not break it) can be ignored. The ultimate aim is to get the area percentage of each of the objects so that the detection method can be limited keeping it in mind.

Some specific questions:

  1. Let us say that I identify a large cluster of pixels within the image. How can I split this into a component cluster (high AR) and thread (low AR)? (something similar to Watershed Algorithm)
  2. Should I go for the OpenCV contouring method like Border Following or border tracing (and later ignoring the holes) or something more suitable
  3. I was curious to know if there have been approaches in the past that used random sampling of pixels instead of a pixel by pixel scanning across the entire image.

I would like to know the steps a computer scientist would follow in such a scenario. I am a beginner in image processing and any reference material would be appreciated. For anybody interested in metallography, the images are micrographs and what we see are defects. I am trying to separate cracks, porosities and other openings based on pixel density.

$\endgroup$
  • $\begingroup$ What prevents you from simply implementing the rules you've listed? Those rules seem clear and straightforward to code up. You just test for each pixel which of those four cases it falls into. It's easy to use a connected components algorithm to find all components of connected shapes ("particles"). I don't know whether those specific rules will do what you want or not, but it seems easy enough to implement. Is that right, or am I misunderstanding something? $\endgroup$ – D.W. Jan 2 at 21:04
  • $\begingroup$ Regarding your second question, in this domain, the best way to find out if a technique will work well is often to try it and find out, so I suggest you try border following or border tracing and see if it meets your needs. That might be more complex than you need and simple connected components might suffice. $\endgroup$ – D.W. Jan 2 at 21:06
  • $\begingroup$ I have made a few edits as per your suggestion. It hopefully improves clarity. The reason why I hesitate to simply execute my straight forward requirements is that it feels like a brute force way to scan my images multiple times and it made me feel doubtful if I was overlooking some simple logic. For example, maybe I could save the neighbour list of pixels in the first scan while looking for the "points" to run the second scanning step lighter. $\endgroup$ – abk Jan 3 at 0:53
  • $\begingroup$ About splitting the surface (or clusters), sometimes my particles appear connected and widely spread around with threads attached to it. I could either stick with my initial rules OR find these threads that may have larger pixel densities than my original rules by finding the contours of closed particles and splitting it based on a sudden drastic difference of aspect ratio. Does that make any good sense? It would be like a parallel scanning of the cluster detected during the original scan to isolate these threads or something more intelligent. $\endgroup$ – abk Jan 3 at 1:10
  • $\begingroup$ OK. See my updated answer. $\endgroup$ – D.W. Jan 3 at 2:23
1
$\begingroup$

I would suggest decomposing the black pixels into connected components using standard algorithms. (For instance, OpenCV has an implementation of this, I believe.) Then, classify each component based on your rules.

(I'm not seeing what boundary tracing offers over connected component labelling, but you could try it too if you wanted.)

I recommend you try it and see how well it works. This should be pretty straightforward to try. I'd caution against over-thinking things and try to figure out the perfect solution before trying anything. In this domain, often multiple rounds of "try something, identify its shortcomings, and improve" are necessary, because it can be hard to predict how something might fail.

If this works, it will be very efficient (it runs in linear time) and quite simple, so you don't need to worry about it being a "brute force" or "naive" method. I wouldn't worry about micro-optimizations at this stage. Instead, implement it and see how well its results seem to be. Only after you are happy with the quality of the results should you even begin to think about potentially optimizing it -- but I would expect that it might be so fast that there is no point in spending any energy trying to optimize it.

You might discover that the connected components are too large and include both clusters and threads. If so, that's telling you that your rules aren't quite right yet, and you'll need to investigate more sophisticated solutions. One possible approach might be to apply a morphological operation, such as a thinning operation or erosion, to remove the threads, compute connected components on the result, and use that to identify clusters. You might also be able to compute a skeletonization of the shapes, and use that to identify threads (e.g., compute the "thickness" of the shape at each point: for each point $p$ on the skeleton, compute the distance to the boundary in the direction perpendicular to the direction of the skeleton at $p$). Once you've identified each shape separately, you might be able to compute its bounding box and the fraction of pixels within the bounding box that are black, and use a threshold on that fraction to distinguish clusters from threads -- if you can separate the cluster from the thread. You might need to experiment a bit to see what works well for your images.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.