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? `
fillPoly() function of OpenCV is used to draw filled polygons like rectangle, triangle, pentagon over an image. This function takes inputs an image and endpoints of Polygon and color.
The imread function is a function of the OpenCV library. OpenCV is used for deep learning algorithms. It will read the image for further processing which will help in classification and analysis purposes. In order to use these images, the first step will be reading an image.
go through the first contour as it is listed until you hit the closest point. Then switch to the other list, starting from the closest point you go clockwise through the other contour until it is used up. switch back to the first contour and append the rest of their points. force them into cv2 contour format.
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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With