How to group contours in close proximity to each other?

Hi all, first time on here.

As per the attached diagram, I’m trying to use openCV commands to group together all proximal blobs in an image, box them with a minimal rectangle and return size of the largest group of blobs (minimal rectangle) and the coordinates of its X and Y position on the screen. Origin is at top left. Ideally, it would also return order of size; largest to smallest, of all blob groups and their respective X and Y centroid coordinates.

Any assistance much appreciated.

Hi,
There is no really answer to your question, except Brute Force method.
Some methods give you an approach answer. Have a look in clustering module and machine learning module and kmeans

clustering is right. flann might be useful in this situation. I disagree with k-means, since there is no k here.

maybe you want to use mean shift.

Thanks for that Laurent! I wonder whether it might be worth blurring the image in order to make the clustered groups of contours appear as one contour - do you think that might be worth trying as a simpler approach and which commands would you suggest? I have used cv2.medianblur but can’t seem to get enough blurriness in the result. cheers.

if you want a simple approach, do a “morphological closing” with an appropriate kernel and number of iterations.

do not blur. wrong operation here.

I like the sound of that crackwitz (great name by the way). simple approach is best here with this, as it does not have to be super accurate at this stage. I’ll have a play and see if this solves it, so many thanks. Interested to know why some sort of blur wouldn’t work on this? cheers.

I don’t see how a blur would help anything at all, but it might hurt the situation.

that’s the case for most things one could do (such as, make a cup of tea, or walk around a tree seven times). they simply don’t make sense to do. and it is hard to explain why those things don’t make sense… because they don’t make sense, there are no arguments to be made.

anything a blur might somehow accomplish, if followed by the right operations, is done better with other operations that actually move you towards the solution.

basically, I consider the suggestion to be unfounded. it is tedious to argue against something that hasn’t been argued for.

morphological closing does that. morph. ops aren’t blurs though. a blur doesn’t quite do that, and not even completely. and a median blur doesn’t even remotely do what you want.

I lack the words to express how much I want to dissuade you from continuing this line of thought.

I just realized, you posted a sketch of your real situation. you should always try to present real data or come close to it.

morph ops work on grayscale data and binary data (just black and white). that’s different from the illustration which just has (unfilled) circles.

That’s fine, I’ll follow up on the morph ops. The only thing is that the closing morph seems to require the shapes to be in the same bound shape in order to close on them. Now that I look back at my attached image, I should have included a before and after ops image to make it clearer. As you’ll see in the attached, I actually start with a collection of separate blobs which are in close proximity to each other. The red dotted line is the red minimum rectangle which is done by the processing, as well as the centroid. From this, am I right in assuming that the morph would not work on this problem?
start with this image…


process to get this image. ie. with centroids of clustered blobs ordered by size, to get the original image i posted.

I don’t understand what you’re asking. “bound shape” doesn’t mean anything.

do you have a raster image of blobs, or do you have centroids and covariances?

The best way I can explain it was by putting in the second image, attached to my reply to you. I actually found something that I think will work on it which you might find interesting. Here’s the link. https://dsp.stackexchange.com/questions/2564/opencv-c-connect-nearby-contours-based-on-distance-between-them

I’m using the first answer with the two code options in it. Haven’t got it working yet but it seems to be the way to go, unless there are commands out there that will do the job more rapidly, as this seems a bit slow from what I’ve read in that post.

I’m not asking for clarification, I’m asking for real data instead of the illustration. your illustration uses ellipses. real data would look like the questioner’s picture on the stack overflow question.

please don’t. that first answer uses explicit loops. that’s a good indication that the solution is inefficient, if not outright wrong. besides, you must have had a picture before you can have contours. it makes absolutely NO sense to calculate contours and then incur O(n^2) cost due to a silly approach from someone on Stack Overflow

how about simply running a morphological closing? the second answer proposes exactly that.

please post actual sample data so I can demonstrate this to you.

Here’s an example binary image of the type of thing I’m looking for, so this is what the cv2.findcontours command uses as input.

this is a 9x9 kernel and 16 iterations. I think you see where this goes.

Exackery Crackwitz! apologies for misunderstanding the use of dilution but I too tried it yesterday and indeed it did a pretty good job! I assume that the kernel size represents effectively the ‘paint brush size’ and the iterations, how many times you need to go around with that paint brush size to fill the area out…only an analogy but you get what i mean. is that about right? also, i assume if you use the same parameters of kernel and iterations then you can erode the diluted shapes back to the original size of the blob grouped mass? cheers.

Many belated thanks for all your help on this Senor Crackwitz!! The dilution command worked extremely well!