简体   繁体   中英

How do I create a white mask displaying only black in an image?

I am trying to get the outline of an album cover and edge detectors (Canny, Laplace) pick up too much noise. I don't fully understand how image masking works and would like put a white mask over the image so I see only the black pixels

I have applied a GaussianBlur 5x5 and converted the image to hsv values. I have a range of values which are black, and I have filtered these out.

# imported image and processing (shorthand here)
image = cv2.imread(args["image"])
blur = cv2.GaussianBlur(image, (5,5), 0)
blur_hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)

# set regions of color 
boundaries = [
    # black 
    ([0,0,0],[180, 255, 40])

    #pink
    #([151, 80, 50], [174, 255, 255])   
]

# loop over the boundaries
for (lower, upper) in boundaries:
    # create NumPy arrays from the boundaries
    lower = np.array(lower, dtype = "uint8")
    upper = np.array(upper, dtype = "uint8")

    # find the colors within the specified boundaries and apply
    mask = cv2.inRange(blur_hsv, lower, upper)  
    output = cv2.bitwise_and(image, image, mask = mask)

    # show the images
    cv2.imshow("images", np.hstack([image, output]))

I was hoping for some distinction in the final output, but the window is just black. How can I create a different color mask?

Edit:

Not the exact image, but a sample LEFT: original; RIGHT: processed

测试标记轮廓图+输出

From my understanding, you want to obtain a mask where all colored pixels (non-black) are white. When we use cv2.inRange() , we give it a lower/upper threshold that returns all pixels within the bounds in white . Then when we use cv2.bitwise_and() with the mask and the original image, the resulting image will be the areas where both the mask and original image are white. Essentially any pixels in white are the areas that we want to keep.

Your current output shows all areas in the original picture that have pixels between the lower/upper threshold. But if your goal is to display all non-black pixels, then you can simply invert the mask. Here's a visualization:

Here's your current mask and represents all pixels within the thresholds in the original image as white.

We can simply invert the mask or use cv2.bitwise_not() to get your desired mask. This new mask represents all colored pixels not within your lower/upper threshold as white. Therefore this mask is all the colored pixels.

final_mask = 255 - mask

Remember, any pixels that we want to keep, we should make it white whereas any pixels we want to throw away, we make it black. So if we cv2.bitwise_and() this new mask with the original image, we get this

Here's a good tutorial on bitwise operations and masking

import cv2
import numpy as np

image = cv2.imread('1.png')
blur = cv2.GaussianBlur(image, (5,5), 0)
blur_hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)

# create NumPy arrays from the boundaries
lower = np.array([0,0,0], dtype = "uint8")
upper = np.array([180,255,40], dtype = "uint8")

# find the colors within the specified boundaries and apply
mask = cv2.inRange(blur_hsv, lower, upper)  
mask = 255 - mask
output = cv2.bitwise_and(image, image, mask = mask)

# show the images
cv2.imshow("output", output)
cv2.imshow("mask", mask)
cv2.waitKey()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM