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

后端 未结 2 1407
甜味超标
甜味超标 2020-11-27 12:42

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 t

相关标签:
2条回答
  • 2020-11-27 12:49

    The following code would be helpful for cropping the images and get them in a white background.

    import cv2
    import numpy as np
    
    # load the image
    image_path = 'input image path'
    image = cv2.imread(image_path)
    
    # create a mask with white pixels
    mask = np.ones(image.shape, dtype=np.uint8)
    mask.fill(255)
    
    # points to be cropped
    roi_corners = np.array([[(0, 300), (1880, 300), (1880, 400), (0, 400)]], dtype=np.int32)
    # fill the ROI into the mask
    cv2.fillPoly(mask, roi_corners, 0)
    
    # The mask image
    cv2.imwrite('image_masked.png', mask)
    
    # applying th mask to original image
    masked_image = cv2.bitwise_or(image, mask)
    
    # The resultant image
    cv2.imwrite('new_masked_image.png', masked_image)
    

    Input Image:

    Mask Image:

    Resultant output image:

    0 讨论(0)
  • 2020-11-27 12:54

    *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)
    
    0 讨论(0)
提交回复
热议问题