Fill the outside of contours OpenCV
12,337
Here's how you can fill an image with black color outside of a set of contours:
import cv2
import numpy
img = cv2.imread("zebra.jpg")
stencil = numpy.zeros(img.shape).astype(img.dtype)
contours = [numpy.array([[100, 180], [200, 280], [200, 180]]), numpy.array([[280, 70], [12, 20], [80, 150]])]
color = [255, 255, 255]
cv2.fillPoly(stencil, contours, color)
result = cv2.bitwise_and(img, stencil)
cv2.imwrite("result.jpg", result)
UPD.: The code above exploits the fact that bitwise_and
with 0-s produces 0-s, and won't work for fill colors other than black. To fill with an arbitrary color:
import cv2
import numpy
img = cv2.imread("zebra.jpg")
fill_color = [127, 256, 32] # any BGR color value to fill with
mask_value = 255 # 1 channel white (can be any non-zero uint8 value)
# contours to fill outside of
contours = [ numpy.array([ [100, 180], [200, 280], [200, 180] ]),
numpy.array([ [280, 70], [12, 20], [80, 150]])
]
# our stencil - some `mask_value` contours on black (zeros) background,
# the image has same height and width as `img`, but only 1 color channel
stencil = numpy.zeros(img.shape[:-1]).astype(numpy.uint8)
cv2.fillPoly(stencil, contours, mask_value)
sel = stencil != mask_value # select everything that is not mask_value
img[sel] = fill_color # and fill it with fill_color
cv2.imwrite("result.jpg", img)
Can fill with another image as well, for example, using img[sel] = ~img[sel]
instead of img[sel] = fill_color
would fill it with the same inverted image outside of the contours:
Author by
Bill
Updated on June 16, 2022Comments
-
Bill almost 2 years
I am trying to color in black the outside region of a contours using openCV and python language. Here is my code :
contours, hierarchy = cv2.findContours(copy.deepcopy(img_copy),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) areas = [cv2.contourArea(c) for c in contours] max_index = np.argmax(areas) cnt=contours[max_index] # how to fill of black the outside of the contours cnt please? `
-
Bill almost 8 yearsThanks bro', I appreciate. Whenever, you're in denver, ping me I'll make you a favor
-
Miki almost 8 years@Bill please accept / upvote if this answer your question. No need to make favours ;D
-
Headcrab almost 8 years@Miki, hands off my favours, decline yours when you get them! :)
-
Miki almost 8 years@Headcrab I'm truly sorry... Whenever you are in Milan, ping me.. I'll make you a favor ;D
-
Headcrab about 4 years@Mvk1312 That depends on the image type. Why, do you want to fill with white instead of black?
-
MathanKumar about 4 yearsHey @Headcrab actually i'm trying to detect the shape region(table) on an image.Afterwards, has to return only that region and excluded non shape region from an image.
-
Headcrab about 4 years@Mvk1312 If you just load an average jpeg with
cv2.imread()
function, white is probably going to be[255, 255, 255]
. Or, for a single channel image, just255
. -
MathanKumar about 4 years@Headcrab , Actually i tried your solution. The result is different from my requirements. My need is except detected table region , all regions should be in white background. Could you help me!
-
Headcrab about 4 years@Mvk1312 If you have a shape/contour and want to fill everything else with a background color - see the second (updated) piece of code in my answer. Otherwise, I don't quite understand your requirements, try asking a separate question, then.
-
MathanKumar about 4 yearsOkay i will try that solution @Headcrab and can you tell me the array values for white colour to fill outside regions