0

I'm trying to do semantic segmentation using a SLIC variant and want to create a mask for the original image where each segment is colored (according to its class) based on available point-based annotations. If there is no point-based annotation in that segment, then leave is as 0.

I currently have x, y points and their associated labels for an image and a (slow) method that finds and colors the desired segments. I'm familiar with vectorization or the 'pythonic' was of doing things, but I can't seem to speed up this last for-loop and would love some advice or references on optimization. Thanks.


# Point-based annotations
annotation = pd.read_csv("a_dataframe.csv") # [X, Y, Label]
color_label = {'class 1' : 25, 'class 2' : 50, 'class 3' : 75}

# Uses CPU to create single segmented image with current params
slic = SlicAvx2(num_components = n_segments, compactness = n_compactness)
segmented_image = slic.iterate(cv2.cvtColor(each_image, cv2.COLOR_RGB2LAB)) 

# Finds the segments of interest and records their ID
X = np.array(each_annotation.iloc[:, 0], dtype = 'uint8')
Y = np.array(each_annotation.iloc[:, 1], dtype = 'uint8')
L = np.array(each_annotation.iloc[:, 2], dtype = 'str')  # Labels
DS = segmented_image[X, Y]                               # Desired Segments

# Empty mask, marks the segments of interest with the classes of the point in them
mask = np.zeros(each_image.shape[:2], dtype = "uint8")

# Would ideally like to find a more quickly way of doing this
for (index, segVal) in enumerate(DS):
   mask[segmented_image == segVal] = color_label.get(L[index])

I have essentially what I would like to replace that loop with here:

[mask[segmented_image == s] for i, s in enumerate(DS)]

but I'm not able to assign X, Y locations with the appropriate Label in mask. I thought it would be something similar to this:

[mask[segmented_image == s] for i, s in enumerate(DS)] = color_label.get(L[i])

but it appears that I'm trying to assign a color value to the lists I'm generating...

  • You can't convert that for loop to a list comprehension because it doesn't construct a list. Also, list comprehensions are not much faster than for loops, because the bulk of the time in your loop is not spent iterating but instead performing the operation. (List comprehensions save a very small amount of time when iterating to construct a new list, but that is not what you are doing here.) – iz_ Jul 25 '19 at 18:48
  • Hey @Tomothy32, I see what you mean [here](https://stackoverflow.com/questions/10291997/how-can-i-do-assignments-in-a-list-comprehension). I was confused with what list comprehension is. Thanks for your feedback. – JordanMakesMaps Jul 25 '19 at 18:57

1 Answers1

0

Are you looking for ind2rgb?
A way to convert an indexed map (one index per slic segment, possible same index for multiple regions) and convert it to RGB image based on a map from index to color.

Shai
  • 111,146
  • 38
  • 238
  • 371
  • Thanks for the reply Shai; not quite, I don't think. Obtaining the final product is completed, it's just that I want to be able to do the last part (the for-loop) in a more efficient way. In the code above, `s` is a list of desired segments (identified by their unique ID), and for each one, the corresponding location within the mask is colored with the appropriate color. But the for-loop is really slow when working with thousands of segments. – JordanMakesMaps Jul 24 '19 at 18:25