Home > Mobile >  create mask with filled color using opencv
create mask with filled color using opencv

Time:11-17

I have an input image where I have drawn the green boundaries which I need to mask. I am able to identify the boundary, but my mask is all black with baground is black. how can I fill the boundary region with different color. May be keep the background white and mask region as black

Input image enter image description here

im = cv2.imread(imagePath)
plt.imshow(im)
#color boundaries [B, G, R]
lower = np.array([0,120,0])
upper = np.array([200,255,100])

# threshold on green color
thresh = cv2.inRange(im, lower, upper)
plt.imshow(thresh)
# get largest contour
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)
x,y,w,h = cv2.boundingRect(big_contour)

# draw filled contour on black background
mask = np.zeros_like(im)
cv2.drawContours(mask, [big_contour], 0, (255,255,255), cv2.FILLED)
plt.imshow(mask)
# apply mask to input image
new_image = cv2.bitwise_and(im, mask)

Generated Output enter image description here

I am expecting the green countor will be filled with some different color. May be white background with black countour. or transparent background

CodePudding user response:

To fill the contours drawn on the mask you should use the opencv's fillPoly function :

im = cv2.imread(imagePath)
plt.imshow(im)
#color boundaries [B, G, R]
lower = np.array([0,120,0])
upper = np.array([200,255,100])

# threshold on green color
thresh = cv2.inRange(im, lower, upper)
plt.imshow(thresh)
# get largest contour
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)
x,y,w,h = cv2.boundingRect(big_contour)

# draw filled contour on black background
mask = np.zeros_like(im)
# cv2.drawContours(mask, [big_contour], 0, (255,255,255), cv2.FILLED)
mask = cv2.fillPoly(mask, pts =[big_contours], color=(255,255,255)) # fill the polygon
plt.imshow(mask)
# apply mask to input image
new_image = cv2.bitwise_and(im, mask)

CodePudding user response:

This code generated canny image and then generates contours, then it generates mask and after this all it shows the output as the mixture of original and the mask image: import cv2 import numpy as np

image = cv2.imread('image.png')
cv2.waitKey(0)

# Grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Find Canny edges
edged = cv2.Canny(gray, 30, 200)
cv2.waitKey(0)

# Finding Contours
# Use a copy of the image e.g. edged.copy()
# since findContours alters the image
contours, hierarchy = cv2.findContours(edged,
    cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

cv2.imshow('Canny Edges After Contouring', edged)


print("Number of Contours found = "   str(len(contours)))

# Draw all contours
# -1 signifies drawing all contours
cv2.drawContours(image, contours, -1, (0, 0, 255), 2)

mask = np.zeros_like(image)
# cv2.drawContours(mask, [big_contour], 0, (255,255,255), cv2.FILLED)
cv2.fillPoly(mask, pts =contours, color=(0,255,0)) # fill the polygon

new_image = cv2.bitwise_and(image, mask)

while True:
    cv2.imshow('Contours', image)
    cv2.imshow('mask', mask)
    cv2.imshow('new_image', new_image)
    cv2.waitKey(1)
# cv2.destroyAllWindows()

Original image:

enter image description here

Edged image:

enter image description here

contours found:

enter image description here

mask:

enter image description here

Final image:

enter image description here

Also you can change color of the mask fill.

  • Related