Machine Vision DISCUSSION

How do I choose HSV lower and upper bounds for colour detection with OpenCV inRange?

Started by amingholizad OpenCV HSV rangecv2.inRangecolour thresholdinghue wrap-aroundcolour segmentation
4 replies 248 views 5 participants
Latest activity · 30 Sep 2026

How do I choose HSV lower and upper bounds for colour detection with OpenCV inRange?

amingholizad Machine Vision Forum
#1

I want to segment red and green objects with OpenCV in Python. I took the values from an online colour picker (H = 0°, S = 100 %, V = 100 % for red) and used them as bounds, but cv2.inRange returns an almost empty mask. Green works poorly too, and the result changes when the room lighting changes.

What ranges does OpenCV actually use for H, S and V, and how should the limits be chosen so the mask is stable?

Community replies 4

Re: How do I choose HSV lower and upper bounds for colour detection with OpenCV inRange?

#2

OpenCV's 8-bit HSV scaling differs from colour pickers. Hue is stored as degrees divided by 2, so it runs from 0 to 179 rather than 0 to 360. Saturation and value run from 0 to 255 rather than 0 to 100 percent. A picker value of H = 120°, S = 50 %, V = 80 % becomes H = 60, S = 128, V = 204 in OpenCV.

Also check the conversion flag. Images loaded with cv2.imread are in BGR order, so use cv2.COLOR_BGR2HSV. Using the RGB flag on a BGR image swaps red and blue, and your red object ends up with a blue hue around 120.

Re: How do I choose HSV lower and upper bounds for colour detection with OpenCV inRange?

#3

Red is a special case because it sits at the wrap-around point of the hue circle: some red pixels have a hue near 0 and others near 179. One range cannot cover both, so build two masks and combine them, for example hue 0 to 10 and hue 170 to 179, each with the same S and V limits, then mask = cv2.bitwise_or(mask1, mask2).

Green is around hue 60 in OpenCV units (120°), so a starting range is roughly 40 to 80. Yellow is near 30 and blue near 120. Treat these as starting points and tune them on your own images.

Re: How do I choose HSV lower and upper bounds for colour detection with OpenCV inRange?

#4

Do not put a tight window around S and V. Hue is fairly stable under changes of brightness, but saturation and value are not: shadows lower V and highlights lower S. A practical starting set is a hue window of about ±10 around the target, S from roughly 80 to 255 and V from roughly 50 to 255. The lower S limit is what rejects white, grey and black areas, whose hue is meaningless and noisy; the lower V limit rejects dark pixels where hue is unreliable.

The quickest way to tune is a small script with six trackbars for the lower and upper limits showing the mask live, tested on images taken under the brightest and the dimmest conditions you expect.

Re: How do I choose HSV lower and upper bounds for colour detection with OpenCV inRange?

#5

For a stable result, fix the camera before fixing the thresholds. Auto white balance and auto exposure change the colours from frame to frame, so the same object drifts across your limits. Set white balance, exposure and gain manually if the camera allows it, and use constant lighting where possible.

Then clean the mask: a morphological opening removes isolated noise pixels and a closing fills small holes, for example with a 5 × 5 kernel through cv2.morphologyEx. Finally filter the contours by area so that small false detections are ignored.

TEP COMMUNITY