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
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)
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:
Edged image:
contours found:
mask:
Final image:
Also you can change color of the mask fill.