NumPy/OpenCV 2: how do I crop non-rectangular regi

2019-01-10 13:06发布

问题:

I have a set of points that make a shape (closed polyline). Now I want to copy/crop all pixels from some image inside this shape, leaving the rest black/transparent. How do I do this?

For example, I have this:

and I want to get this:

回答1:

*edit - updated to work with images that have an alpha channel.

This worked for me:

  • Make a mask with all black (all masked)
  • Fill a polygon with white in the shape of your ROI
  • combine the mask and your image to get the ROI with black everywhere else

You probably just want to keep the image and mask separate for functions that accept masks. However, I believe this does what you specifically asked for:

import cv2
import numpy as np

# original image
# -1 loads as-is so if it will be 3 or 4 channel as the original
image = cv2.imread('image.png', -1)
# mask defaulting to black for 3-channel and transparent for 4-channel
# (of course replace corners with yours)
mask = np.zeros(image.shape, dtype=np.uint8)
roi_corners = np.array([[(10,10), (300,300), (10,300)]], dtype=np.int32)
# fill the ROI so it doesn't get wiped out when the mask is applied
channel_count = image.shape[2]  # i.e. 3 or 4 depending on your image
ignore_mask_color = (255,)*channel_count
cv2.fillPoly(mask, roi_corners, ignore_mask_color)
# from Masterfool: use cv2.fillConvexPoly if you know it's convex

# apply the mask
masked_image = cv2.bitwise_and(image, mask)

# save the result
cv2.imwrite('image_masked.png', masked_image)