Reputation: 23
I'm working on greyscale images of some alloys microstructures taken with optical microscope, etc. My goal is to analyse the amount (%) of areas with given threshold (pixel count), as well as the number, size, etc. of these segments. For last I use: from skimage import measure, morphology, which finds these segments and each segment has unique integer in labels matrix, which has same shape as pic. I can do all, except coloring those segments on original image without a for
loop..
import numpy as np
import matplotlib.pyplot as plt
grains = np.array([[1,3], [2,5], [6,2]] )
labels=np.array([[1,1,0,0,0],[1,0,0,2,0],[0,0,2,2,2],[0,0,0,2,0],[6,6,0,0,0]])
im = np.array([[223, 222, 225, 224, 227],[222, 224, 218, 220, 221],[216, 221, 219, 223, 225],[228, 226, 231, 224, 228],[226, 228, 225, 218, 225]])
image=np.stack((im, im, im), axis=2) # greyscale sample image
color = [0, 0, 255] # rgb blue color
for i in grains:
B=np.full((i[1],3), color).astype('int')
image[labels==i[0]]=B
plt.imshow(image)
plt.show()
Is there any efficient 'numpy way', which won't include 'for' loop, and would, therefore, be much faster.
Upvotes: 1
Views: 150
Reputation: 8152
If the output is correct already, then you can turn the pixels flagged in labels
blue like so:
import numpy as np
import matplotlib.pyplot as plt
labels = np.array([[1,1,0,0,0],
[1,0,0,2,0],
[0,0,2,2,2],
[0,0,0,2,0],
[6,6,0,0,0]])
im = np.array([[223, 222, 225, 224, 227],
[222, 224, 218, 220, 221],
[216, 221, 219, 223, 225],
[228, 226, 231, 224, 228],
[226, 228, 225, 218, 225]])
image = np.stack((im, im, im), axis=2)
image[labels >= 1] = [0, 0, 255]
plt.imshow(image)
Which gives the same output you have:
But it seems like you are trying to do something else — so that label = 1
looks different from label = 2
. As you can see, I didn't use grains
at all. If you can explain how you want the final image to look, there's almost certainly a way to do it without loops.
Upvotes: 3