Image Segmentation Using Color Spaces
In many deep learning imaging projects, we are required to extract all kind of parts of the image. In medical imaging, for example, it’s very common to have marking as name, date and meta data on the images. Here I use example from my last project, were we had to extract signal data from graph images.
Very interesting, where is the code ?https://github.com/naomifridman/fetus_stress_detection_FHR_UC/blob/master/exctract_signal_from_img.ipynb
In this post, we will extract the FHR, signal’s from their images. Googling this problem, will give you the popular stackoverflow, with shv boundaries. But how to find them is not clear. Here we focus on how to analyze your specific image set, and find the suitable boundaries for your image set.
Visualizing image Color Space
First lest visualize image in RGB color space
If we had only few pixels in the desired color we want to filter, we could have filtered it by calculating Euclidean distance from a set of pixels. But in this case, as in most cases, color space is quit reach. So we seek solution in the HSV color space.
Our goal is to find bounding box of the signal’s color’s. To make it easier, lets focus on the color we want to extract, and crop ROI part of the image.
HSV visualization of the cropped image:
To find the bounding box of the colors we want to extract, lets project the 3d color spacing on 2d:
We can see that Hue can be bounded between 80–100 to 120
we can try bound Saturation to be > 50. Applying boundaries, we get:
Full code of the analysis is in the git. The main function, is listed below:
def exctract_blue_signal(im):
hsv_im = cv2.cvtColor(im, cv2.COLOR_RGB2HSV)
lower_blue = np.array([78, 50, 100])
upper_blue = np.array([100, 255, 230])
mask = cv2.inRange(hsv_im, lower_blue, upper_blue)
res = cv2.bitwise_and(im,im,mask)
mask3 = np.repeat(mask[:,:,np.newaxis], 3, axis=2)/255
masked_im = im*mask3/255.
return mask, masked_im
Calling the function, we get:
Another example, with its HSV visualization:
According to the HSV visualization, we can see that we will need 2 bounding boxes to filter the red signal. Analyzing the signal’s image, as we did before, summarize to the following function:
def exctract_red_signal(im):
hsv_im = cv2.cvtColor(im, cv2.COLOR_RGB2HSV)
lower_red = np.array([160, 160, 200])
upper_red = np.array([180, 255, 255])
mask0 = cv2.inRange(hsv_im, lower_red, upper_red)
lower_red = np.array([0, 200, 200])
upper_red = np.array([20, 255, 255])
mask1 = cv2.inRange(hsv_im, lower_red, upper_red)
mask = mask0+mask1
res = cv2.bitwise_and(im,im,mask)
mask3 = np.repeat(mask[:,:,np.newaxis], 3, axis=2)/255
masked_im = im*mask3/255.return mask, masked_im
Applying this function on the signal’s image, we get:
Some small color space is still missing, continue analyze :-)