I'm trying to mask colored features from a photograph so that I can do some other processing on them. I've played with a few packages (scikit-image, mahotas, and openCV) and have settled on Scikit-image because it plays well with scikit-learn.
I'd like to accomplish two things, eventually: (1) get colored features so that I can compute things like length, and (2) remove colored features from the image while retaining the white spidering-looking veins (the lattice-looking stuff around the margin of the image will need to go, but that can be a later endeavour).
I'm new to image processing in Python, and I think I've mislead myself by using strange color spaces. Perhaps it would have been better to define an upper and lower boundary for each colour, and mask the image array? I'm definitely open to any flexible solution to the problem. Eventually I'll be applying this to hundreds of photos..
from skimage import io, img_as_float, color, exposure img = img_as_float(io.imread('./images/testimage2.JPG')) # Isolate paint marks # Put image into LAB colour space image_lab = color.rgb2lab(img) img = exposure.rescale_intensity(img) # Colours of interest color_array = np.array([ [[[255, 255, 0.]]], # Yellow stuff [[[255, 190, 200.]]], # Pink stuff [[[255, 165, 0.]]], # Orange stuff [[[255, 0, 0.]]], # Red stuff ]) # Loop through the color array and pick out the colored features for i in range(0,color_array.ndim): # Compute distance between the color of interest and the actual image # http://scikit-image.org/docs/dev/api/skimage.color.html#skimage.color.deltaE_cmc # "The usual values are kL=2, kC=1 for “acceptability”" distance_color = color.deltaE_ciede2000(color_array[i], image_lab, kL=2, kC=1, kH=0.5) # Normalise distance distance_color = exposure.rescale_intensity(distance_color) # Mask image image_filtered = img.copy() image_filtered[distance_color > 0.5] = 0 # Plot it up print ("Filtered to: ", color_array[i]) f, (ax0, ax1, ax2) = plt.subplots(1, 3, figsize=(20, 10)) ax0.imshow(img) ax1.imshow(distance_color, cmap='gray') ax2.imshow(image_filtered) plt.show()