Why is this simple mask not working?

asked 2014-04-05 21:00:00 -0500

ss32 gravatar image

I'm in the process of learning how to use masking and the bitwise_and function. I have some tutorial code that works but mine is not and I can't see why. The source image I'm using is here

import numpy as n
import cv2 

# Import the image
im = cv2.imread('orange.jpg')

hsv = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)

upper = n.array([-20,100,100])
lower = n.array([25,100,255])

mask = cv2.inRange(hsv,lower,upper)
result = cv2.bitwise_and(im,im, mask= mask)

# Display the image, esc to kill the window
edit retag flag offensive close merge delete



inRange works like a bandpass filter - you get , what's left between the bounds. you are confusing upper and lower bounds here, and having the same value for both leaves no space inbetween (no matter, if you put 100 for both or 15).

also, hue is in the [0..180] range (full circle, but divided by 2, to fit into a byte) and can't be negative

berak gravatar imageberak ( 2014-04-06 06:47:18 -0500 )edit

I'm not sure I follow you on the lower/upper arrays. The example code I have acts like I would expect, placing lower and upper limits on HSV values.

# Convert BGR to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

lower_red = np.array([0,100,100])
upper_red = np.array([20,255,255])

# Threshold the HSV image to get only red colors
mask2 = cv2.inRange(hsv, lower_red, upper_red)

I tried changing the lower/upper arrays in my original code to this:

lower = n.array([0,0,0])
upper = n.array([20,100,255])

And it works, but not well. The resulting mask is extremely rough, and the resulting image is still black, like the mask wasn't applied at all.

ss32 gravatar imagess32 ( 2014-04-06 09:22:08 -0500 )edit

mask = cv2.inRange(hsv,(0,50,50),(30,255,255))

berak gravatar imageberak ( 2014-04-06 10:33:00 -0500 )edit

I solved it. Here's the code that got it working. My bounds were off

# Convert to HSV colorspace
hsv = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)

# Define color range for masking
lower = n.array([0,100,100])
upper = n.array([20,255,255])

# Apply the mask
mask = cv2.inRange(hsv, lower, upper)

    #(source, destination, mask to apply)
result = cv2.bitwise_and(im,im, mask=mask)
ss32 gravatar imagess32 ( 2014-04-06 17:43:34 -0500 )edit