0

I have a image where I have defined some boundaries. I am trying to mask these different boundaries.

enter image description here

So, I want to create mask for green circle (eye) and blue region and yellow regions. How can I do that? I also have the x,y coordinates for these boundries, but I am not able to mask.

so far i have this

img = cv2.imread(path + filenames[0], cv2.IMREAD_COLOR)
RGB_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

plt.imshow(RGB_img)

#color boundaries [B, G, R]
lower = np.array([0,90,0])
upper = np.array([50,235,100])
# threshold on green color
thresh = cv2.inRange(RGB_img, lower, upper)
plt.imshow(thresh)

and I get this enter image description here

user1631306
  • 4,350
  • 8
  • 39
  • 74

2 Answers2

2

Here is one way to do that in Python/OpenCV.

  • Read the input image
  • Choose one of your colors and set up lower and upper ranges for them. Then use cv2.inRange() to threshold on that color.
  • Then get external contours and draw them as white filled on a black background (usual polarity for masks).
  • Optionally invert the mask so you have black regions on a white background
  • Save the mask

Input:

enter image description here

import cv2
import numpy as np

# read the input image
img = cv2.imread('fish_outlines.png')

# specify outline color and threshold on it
# yellow
upper = (50,255,255)
lower = (0,180,180)
thresh = cv2.inRange(img, lower, upper)

# get external contours
contours = cv2.findContours(thresh , cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]

# draw white filled contours on black background
mask = np.zeros_like(img)
for cntr in contours:
    cv2.drawContours(mask, [cntr], 0, (255,255,255), -1)

# invert so black regions on white background if desired
mask = 255 - mask

# save result
cv2.imwrite('fish_outlines_yellow_mask.png', mask)

# show results
cv2.imshow('thresh', thresh)
cv2.imshow('mask', mask)
cv2.waitKey(0)

Resulting Mask:

enter image description here

If you have lists of outline coordinates, that could be used. It would be easy for single regions. For the ones like the yellow with multiple regions, you would need separate lists for each individual yellow region.

fmw42
  • 46,825
  • 10
  • 62
  • 80
1

Refer to this answer How to define a threshold value to detect only green colour objects in an image with Python OpenCV?

We can get a clolor map of HSV : enter image description here

In your case, you search for the color pure blue, yellow green. We can fix the S and V between (180, 255), and H is in (10, 130).

img = cv2.imread(path + filenames[0], cv2.IMREAD_COLOR)
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower =  np.array([10, 180, 180])
upper = np.array([130, 255, 255])
mask= cv2.inRange(hsv_img, lower, upper)
masked = cv2.bitwise_and(img,img, mask=mask)
cv2.imshow("img", masked)

Will give you this :

enter image description here

HMH1013
  • 1,216
  • 2
  • 13
  • That is awesome. how can I make individual masking, like just green, yellow and blue in 3 different images and also, how can I fill them up with black or keep the background white? – user1631306 Apr 05 '23 at 15:38