Reputation: 211
I've been struggling to create my own color masks that work using the following image
I am trying to isolate the red stop sign in this example. My initial strategy was to use a color picker to get a range of red values (HSV format):
Lower bound:
Upper bound:
Code:
import numpy as np
import cv2
img = cv2.imread("image.jpg")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([0, 59, 49])
upper = np.array([0, 100, 100])
mask = cv2.inRange(hsv, lower, upper)
result = cv2.bitwise_and(hsv, hsv, mask=mask)
cv2.imshow("image", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
The resulting image (result variable) is completely black, which I assume means that none of the red was detected. I assume this has something to do with the HSV values I chose, but I'm not sure what's wrong with them.
When I use 2 masks and modified HSV values (that I found online), it works very well; the stop sign and only the stop sign is highlighted in result:
import numpy as np
import cv2
img = cv2.imread("image.jpg")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([0, 50, 50])
upper = np.array([10, 255, 255])
lower2 = np.array([170, 50, 50])
upper2 = np.array([180, 255, 255])
mask = cv2.inRange(hsv, lower, upper)
mask2 = cv2.inRange(hsv, lower2, upper2)
mask = mask + mask2
result = cv2.bitwise_and(hsv, hsv, mask=mask)
cv2.imshow("image", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
So my question is why does the second example work so much better than the first? Should I always use 2 masks and add them? What should the first mask do versus what the second mask does? How can I choose better HSV values?
Upvotes: 0
Views: 2418
Reputation: 15365
Your first piece of code selects for exactly 0 degrees of hue. That stop sign will probably not have exactly that hue. Hence, not selected.
Your second piece of code gives some range of hues. That's why it can catch the stop sign.
The second piece of code has to split the hue range up into two segments because the desired hue goes from negative to positive (0 +- 20 degrees). cv.inRange
has no logic that would allow you to express that in a single range. Hence two pieces, or-ed together (addition).
Upvotes: 3