how to upsample the superpixels to have all one shape?

Question:

Consider I have an image

original

with shape (240, 320, 4) and after applying the slic method function to superpixels.

I want to resize those superpixels in (segments 2)

2

in order to have the same shape.

How to upsample these segments to all have super pixel size, it’s ok to insert to zeros in the edges?

 num_segments = 400
 img = img_as_float(imread('1.png'))
 #if len(img.shape) > 2 and img.shape[-1] == 4:
     # img = img[:, :, :3]
 segments = slic(img, compactness=30, n_segments=num_segments)
 superpixels_ids = np.unique(segments)
 for id in superpixels_ids:
    pixels_per_sp = img[segments == id]
    print(pixels_per_sp.shape)

 plt.figure()
 plt.imshow(mark_boundaries(img, segments))
 plt.show()

the pixels_per_sp.shape have different sizes when they are plotted

(199, 3)
(203, 3)
(195, 3)
(232, 3)
(211, 3)
(211, 3)
(210, 3)
(210, 3)
(210, 3)
(210, 3)
(210, 3)
(210, 3)
(210, 3)
(210, 3)
(202, 3)
(210, 3)
(210, 3)
(210, 3)
(210, 3)
(210, 3)
(210, 3)
(210, 3)
(210, 3)
(180, 3)
(198, 3)
(196, 3)

I would like to upscale the superpixels all to have exactly one size
like if I can ad zeros in the edges of each superpixel

Another question: is there a way that I can keep the image as RGBA and apply slic still?
thnaks

Asked By: user4556432

||

Answers:

If I understood your question correctly, you want to have your superpixels all the same size.

Edit 2: I just saw that your pixels_per_sp are 1D arrays where it doesn’t make sense to pad zeros at the end because you don’t have any spatial structure in it.
I did adjust my answer below to retrieve the superpixel together with spatial neighborhood information.

So I would suggest you do the following:

  • compute the minimal size of an array which still fits in all superpixels
  • create such one for all of the superpixels and initialize it with zeros (your paddings)
  • fill in the data of your superpixels
# compute max shape
max_shape = np.zeros((len(img.shape[:-1]),), dtype=int)

for id in superpixels_ids:
    # get indices of superpixel's pixels
    pixels_indices = np.argwhere(segments == id)

    # get bounding box of superpixel
    xymin = np.min(pixels_indices , axis=0)
    xymax = np.max(pixels_indices , axis=0)

    # update max shape
    max_shape = np.max(np.stack([(xymax - xymin)+1, max_shape]), axis=0)


# create your superpixels with zero paddings

new_super_pixels = np.zeros((len(superpixels_ids), ) + tuple(max_shape) + (img.shape[-1],), dtype=img.dtype)

for i, id in enumerate(superpixels_ids):
    # get indices of superpixel's pixels
    pixels_indices = np.argwhere(segments == id)

    # get bounding box of superpixel (again)
    xymin = np.min(pixels_indices, axis=0)

    # broadcast superpixel data in our new_super_pixels array (use index instead of id)
    new_super_pixels[i][tuple((pixels_indices-xymin).T)] = img[tuple(pixels_indices.T)]

Now you got your array with superpixels of the same shape and padded zeros.

Does this help you?

Edit:

If you would like to upsample using some interpolation method, you might want to check out another question/contribution of mine.

Answered By: Ruben
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.