0

I am trying to draw a mask over an image, the mask is the result of the processing done by body-pix (in NodeJS). I want to use OpenCV to draw the masks, instead of htmlcanva for performance reasons.

    const segmentation = await net.segmentPersonParts(img, {
        flipHorizontal: false,
        internalResolution: 'medium',
        segmentationThreshold: 0.7
    });

    //Mask into opencv Mat
    const segmentationMask = new cv.Mat(segmentation.data, segmentation.height, segmentation.width, cv.CV_8UC4);
    const mask = segmentationMask.cvtColor(cv.COLOR_BGRA2BGR);
    //Application of mask
    const result = mat.bitwiseAnd(mask);
    cv.imwrite('mask.jpg', mask);
    cv.imwrite('result.jpg', result);

This works perfectly, and achieves the desired result of drawing a black mask (the semantic segmentation) over persons detected. However SegmentPersonParts is much slower than the method SegmentPerson, and I wish to use this last method. The problem is, the mask does not work. When doing:

    const segmentation = await net.segmentPerson(img, {
        flipHorizontal: false,
        internalResolution: 'medium',
        segmentationThreshold: 0.7
    });

    //Mask into opencv Mat
    const segmentationMask = new cv.Mat(segmentation.data, segmentation.height, segmentation.width, cv.CV_8UC4);
    const mask = segmentationMask.cvtColor(cv.COLOR_BGRA2BGR);
    //Application of mask
    const result = mat.bitwiseAnd(mask);
    cv.imwrite('mask.jpg', mask);
    cv.imwrite('result.jpg', result);

The result is just a black image, as the mask is not correctly built. How can I solve this?

patrol
  • 21
  • 5

1 Answers1

0

I have a script that can do that in images using OpenCV-Python:

import cv2

def pixelate(image):
    # Get input size
    height, width, _ = image.shape

    # Desired "pixelated" size
    h, w = (16, 16)

    # Resize image to "pixelated" size
    temp = cv2.resize(image, (w, h), interpolation=cv2.INTER_LINEAR)

    # Initialize output image
    return cv2.resize(temp, (width, height), interpolation=cv2.INTER_NEAREST)

# Load image
image = cv2.imread('1.png')

# ROI bounding box coordinates
x,y,w,h = 122,98,283,240

# Extract ROI
ROI = image[y:y+h, x:x+w]

# Pixelate ROI
pixelated_ROI = pixelate(ROI)

# Paste pixelated ROI back into original image
image[y:y+h, x:x+w] = pixelated_ROI

cv2.imshow('pixelated_ROI', pixelated_ROI)
cv2.imshow('image', image)
cv2.waitKey()

You need to get the boundingboxes coordinates and use it on the ROI.

stateMachine
  • 5,227
  • 4
  • 13
  • 29
Jasar Orion
  • 626
  • 7
  • 26