Mattia Strocchi
Mattia Strocchi

Reputation: 45

Color display error while applying a mask

I am trying to filter an image in OpenCV (with Python) but I get a blue region instead of black after the application of a mask.

Shortly, the code changes the color space of the image from BGR to LAB, then creates a mask with the function cv2.inRange and reverses it with cv2.bitwise_not. After that, the mask gets applied with the function cv2.bitwise_and. Here are the original and filtered frame:

https://i.sstatic.net/6pGym.png

In the beginning, I thought that could be a problem between the BGR/RGB image representation but blue region excluded, the colors of the image are correct.

Here is the code:

# Parameter "frame": BGR image.
# Parameter "min": min LAB val.
# Parameter "max": max LAB val.
# Return filtered frame in BGR.
def applyFilter(frame, min, max):

    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2LAB)

    mask = cv2.inRange(frame, min, max)
    mask = cv2.bitwise_not(mask)

    filtered_frame = cv2.bitwise_and(frame, frame, mask=mask)

    return cv2.cvtColor(filtered_frame, cv2.COLOR_LAB2BGR)

Upvotes: 1

Views: 459

Answers (1)

api55
api55

Reputation: 11420

LAB colorspace has 3 channels, L which goes from 0-100%, a which goes from -128 to 128 and b which goes from -128 to 128. OpenCV values in LAB for a uint8 image are as follows:

enter image description here

Your problem is that in OpenCV the value (0,0,0) in LAB is in reality (0, -128, -128) which one can look in an online colorpicker and see that is blue.

When you apply the mask, what is not in the mask stays "black"(0,0,0) and once it is converted from LAB to BGR it is then blue. If the idea is to leave what is not selected in black you have 2 solutions:

1) apply the mask to the original image

2) convert the 0,0,0 pixels to 0,128,128

For 1) the code will be like this:

# Parameter "frame": BGR image.
# Parameter "min": min LAB val.
# Parameter "max": max LAB val.
# Return filtered frame in BGR.
def applyFilter(frame, min, max):

    tempFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2LAB)

    mask = cv2.inRange(tempFrame, min, max)
    mask = cv2.bitwise_not(mask)

    filtered_frame = cv2.bitwise_and(frame, frame, mask=mask)

    return filtered_frame

Upvotes: 1

Related Questions