0

Given an image that contains several irregularly sized and shaped images (shown here as circles for the sake of simplicity):

image with images

...how can I:

  1. Detect sub-images
  2. Split and save sub-images as separate files?

enter image description here

Ideally I'm looking for a python solution. I've tried "connected component analysis" algorithms, and centroid measurement but the first breaks down for non-uniform images like those given, and I'm not sure how to apply the second to extract separate images.

Note, I'm not asking about splitting an image into equally-sized, uniform parts, which has been asked and answered many times on SO.

Thanks for any help you can give.

Allyl Isocyanate
  • 13,306
  • 17
  • 79
  • 130

1 Answers1

2

If we can assume that the background is uniform and distinct from the sub-images, the following approach should work:

  1. Perform background subtraction by simply masking the background color (also, if the inner parts of the sub-images can contain the background color, flood-fill algorithm will work better here).

  2. Perform connected components analysis.

Here is an example in python for the image given above:

from scipy import ndimage
import matplotlib.pyplot as plt

# Load
img = ndimage.imread("image.png")

# Threshold based on pixel (0,0) assumed to be background
bg = img[0, 0]
mask = img != bg
mask = mask[:, :, 0]  # Take the first channel for RGB images

# Connected components
label_im, nb_labels = ndimage.label(mask)

# Plot
plt.figure(figsize=(9, 3))
plt.subplot(131)
plt.imshow(img, cmap=plt.cm.gray)
plt.axis('off')
plt.subplot(132)
plt.imshow(mask, cmap=plt.cm.gray)
plt.axis('off')
plt.subplot(133)
plt.imshow(label_im, cmap=plt.cm.spectral)
plt.axis('off')
plt.subplots_adjust(wspace=0.02, hspace=0.02, top=1, bottom=0, left=0, right=1)
plt.show()

and result for your images (with arbitrary shapes): enter image description here

Now, the remaining task is to save/store each sub-image based on the label_im values.

Andrzej Pronobis
  • 33,828
  • 17
  • 76
  • 92
  • looks great, thanks!! If the background is mostly uniform (for example a picture of objects on a white table), is there a better way to determine the background mask? – Allyl Isocyanate May 17 '15 at 19:38
  • There are many approaches, but you can check out my answer here: http://stackoverflow.com/a/30283109/1576602 for a suggestion. Basically, most of those methods work by building a model of color distribution of the background and the foreground and then perform segmentation. – Andrzej Pronobis May 17 '15 at 20:28