Choosing The Correct Upper And Lower HSV Boundaries For Color ...

    1. Home
    2. Questions
    3. Tags
    4. Users
    5. Companies
    6. Labs
    7. Jobs
    8. Discussions
    9. Collectives
    10. Communities for your favorite technologies. Explore all Collectives

  1. Teams

    Ask questions, find answers and collaborate at work with Stack Overflow for Teams.

    Try Teams for free Explore Teams
  2. Teams
  3. Ask questions, find answers and collaborate at work with Stack Overflow for Teams. Explore Teams

Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Get early access and see previews of new features.

Learn more about Labs Choosing the correct upper and lower HSV boundaries for color detection with`cv::inRange` (OpenCV) Ask Question Asked 12 years, 5 months ago Modified 1 year, 4 months ago Viewed 349k times 118

I have an image of a coffee can with an orange lid position of which I want to find. Here is it image.

gcolor2 utility shows HSV at the center of the lid to be (22, 59, 100). The question is how to choose the limits of the color then? I tried min = (18, 40, 90) and max = (27, 255, 255), but have got unexpected result

Here is the Python code:

import cv in_image = 'kaffee.png' out_image = 'kaffee_out.png' out_image_thr = 'kaffee_thr.png' ORANGE_MIN = cv.Scalar(18, 40, 90) ORANGE_MAX = cv.Scalar(27, 255, 255) COLOR_MIN = ORANGE_MIN COLOR_MAX = ORANGE_MAX def test1(): frame = cv.LoadImage(in_image) frameHSV = cv.CreateImage(cv.GetSize(frame), 8, 3) cv.CvtColor(frame, frameHSV, cv.CV_RGB2HSV) frame_threshed = cv.CreateImage(cv.GetSize(frameHSV), 8, 1) cv.InRangeS(frameHSV, COLOR_MIN, COLOR_MAX, frame_threshed) cv.SaveImage(out_image_thr, frame_threshed) if __name__ == '__main__': test1() Share Improve this question Follow edited Sep 13, 2021 at 2:46 nathancy's user avatar nathancy 46.3k15 gold badges131 silver badges153 bronze badges asked Jun 8, 2012 at 12:09 Student FourK's user avatar Student FourKStudent FourK 1,4032 gold badges11 silver badges7 bronze badges 3
  • I checked the values (22, 59, 100) as HSV, and they don't seem to match the any color similar to the ones of the lid. But as BGR, they make sense. How did you retrieve these values? – karlphillip Commented Jun 8, 2012 at 13:52
  • Here is screenshot with gcolor2 imageshack.us/photo/my-images/23/rgb2hsv.png. I then checked color number #FFA069 on yafla.com/yaflaColor/ColorRGBHSL.aspx?RGB=&Colors=,,,,,,,,, and the conversion is the same. – Student FourK Commented Jun 8, 2012 at 14:35
  • 6 This is probably due to different HSV ranges in OpenCV, namely H: 0 - 180, S: 0 - 255, V: 0 - 255. – Student FourK Commented Jun 8, 2012 at 14:39
Add a comment |

10 Answers 10

Sorted by: Reset to default Highest score (default) Trending (recent votes count more) Date modified (newest first) Date created (oldest first) 178

Problem 1 : Different applications use different scales for HSV. For example gimp uses H = 0-360, S = 0-100 and V = 0-100. But OpenCV uses H: 0-179, S: 0-255, V: 0-255. Here i got a hue value of 22 in gimp. So I took half of it, 11, and defined range for that. ie (5,50,50) - (15,255,255).

Problem 2: And also, OpenCV uses BGR format, not RGB. So change your code which converts RGB to HSV as follows:

cv.CvtColor(frame, frameHSV, cv.CV_BGR2HSV)

Now run it. I got an output as follows:

enter image description here

Hope that is what you wanted. There are some false detections, but they are small, so you can choose biggest contour which is your lid.

EDIT:

As Karl Philip told in his comment, it would be good to add new code. But there is change of only a single line. So, I would like to add the same code implemented in new cv2 module, so users can compare the easiness and flexibility of new cv2 module.

import cv2 import numpy as np img = cv2.imread('sof.jpg') ORANGE_MIN = np.array([5, 50, 50],np.uint8) ORANGE_MAX = np.array([15, 255, 255],np.uint8) hsv_img = cv2.cvtColor(img,cv2.COLOR_BGR2HSV) frame_threshed = cv2.inRange(hsv_img, ORANGE_MIN, ORANGE_MAX) cv2.imwrite('output2.jpg', frame_threshed)

It gives the same result as above. But code is much more simpler.

Share Improve this answer Follow edited Jun 7, 2019 at 9:41 lmiguelmh's user avatar lmiguelmh 3,1921 gold badge39 silver badges53 bronze badges answered Jun 8, 2012 at 14:52 Abid Rahman K's user avatar Abid Rahman KAbid Rahman K 52.6k31 gold badges147 silver badges158 bronze badges 7
  • +1 Excellent, once again. If you could add the full source code with your modifications it would be awesome. – karlphillip Commented Jun 8, 2012 at 14:55
  • Thank you. But i don't think there is much excellency here.:) (OK, i will do it) – Abid Rahman K Commented Jun 8, 2012 at 14:56
  • 1 Great! It works for me now as well, although I believe your S and V min-max ranges are too relaxed. I also have got good lid coverage with min (5, 100, 255) and max (15, 200, 255). – Student FourK Commented Jun 8, 2012 at 16:21
  • Good to know. I took S,V values just to show the result, to show this solution works. Good you found better ones. Also try to move onto cv2 interface. It is more simpler and faster. You can find some good tutorials here: opencvpython.blogspot.com. And if it solves your problem, accept the answer and close this session. – Abid Rahman K Commented Jun 8, 2012 at 18:34
  • This is the place where every one commits mistakes when they are newbies to OpenCv. – nbsrujan Commented Nov 11, 2013 at 7:44
| Show 2 more comments 104

Ok, find color in HSV space is an old but common question. I made a hsv-colormap to fast look up special color. Here it is:

enter image description here

The x-axis represents Hue in [0,180), the y-axis1 represents Saturation in [0,255], the y-axis2 represents S = 255, while keep V = 255.

To find a color, usually just look up for the range of H and S, and set v in range(20, 255).

To find the orange color, we look up for the map, and find the best range: H :[10, 25], S: [100, 255], and V: [20, 255]. So the mask is cv2.inRange(hsv,(10, 100, 20), (25, 255, 255) )

Then we use the found range to look for the orange color, this is the result:

enter image description here

The method is simple but common to use:

#!/usr/bin/python3 # 2018.01.21 20:46:41 CST import cv2 img = cv2.imread("test.jpg") hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) mask = cv2.inRange(hsv,(10, 100, 20), (25, 255, 255) ) cv2.imshow("orange", mask);cv2.waitKey();cv2.destroyAllWindows()

Similar answers:

  1. How to define a threshold value to detect only green colour objects in an image :Opencv

  2. Choosing correct HSV values for OpenCV thresholding with InRangeS

Share Improve this answer Follow answered Jan 21, 2018 at 13:18 Kinght 金's user avatar Kinght 金Kinght 金 18.3k5 gold badges62 silver badges77 bronze badges 4
  • second link behaving oddly? – jtlz2 Commented Feb 14, 2020 at 12:25
  • 1 @jtlz2: They simply linked back to this answer. Perhaps in mistake. – Martijn Pieters Commented Feb 14, 2020 at 13:46
  • A bit late but wondering how you determined the V value. In my application I'm using histograms to determine H/S values but wasn't sure about V. Regarding 0-100% being dark/light I guess in a decently lit room we'd just go for a median value? – Jacob David C. Cunningham Commented Dec 8, 2020 at 9:51
  • Very nice figure! Though I think you used matplotlib which shows colors in BGR rather than RGB by default so these colors are a bit wrong. The ends should be blue. – Matt Ellis Commented Jul 31 at 15:34
Add a comment | 87

Here's a simple HSV color thresholder script to determine the lower/upper color ranges using trackbars for any image on the disk. Simply change the image path in cv2.imread(). Example to isolate orange:

enter image description here

import cv2 import numpy as np def nothing(x): pass # Load image image = cv2.imread('1.jpg') # Create a window cv2.namedWindow('image') # Create trackbars for color change # Hue is from 0-179 for Opencv cv2.createTrackbar('HMin', 'image', 0, 179, nothing) cv2.createTrackbar('SMin', 'image', 0, 255, nothing) cv2.createTrackbar('VMin', 'image', 0, 255, nothing) cv2.createTrackbar('HMax', 'image', 0, 179, nothing) cv2.createTrackbar('SMax', 'image', 0, 255, nothing) cv2.createTrackbar('VMax', 'image', 0, 255, nothing) # Set default value for Max HSV trackbars cv2.setTrackbarPos('HMax', 'image', 179) cv2.setTrackbarPos('SMax', 'image', 255) cv2.setTrackbarPos('VMax', 'image', 255) # Initialize HSV min/max values hMin = sMin = vMin = hMax = sMax = vMax = 0 phMin = psMin = pvMin = phMax = psMax = pvMax = 0 while(1): # Get current positions of all trackbars hMin = cv2.getTrackbarPos('HMin', 'image') sMin = cv2.getTrackbarPos('SMin', 'image') vMin = cv2.getTrackbarPos('VMin', 'image') hMax = cv2.getTrackbarPos('HMax', 'image') sMax = cv2.getTrackbarPos('SMax', 'image') vMax = cv2.getTrackbarPos('VMax', 'image') # Set minimum and maximum HSV values to display lower = np.array([hMin, sMin, vMin]) upper = np.array([hMax, sMax, vMax]) # Convert to HSV format and color threshold hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) mask = cv2.inRange(hsv, lower, upper) result = cv2.bitwise_and(image, image, mask=mask) # Print if there is a change in HSV value if((phMin != hMin) | (psMin != sMin) | (pvMin != vMin) | (phMax != hMax) | (psMax != sMax) | (pvMax != vMax) ): print("(hMin = %d , sMin = %d, vMin = %d), (hMax = %d , sMax = %d, vMax = %d)" % (hMin , sMin , vMin, hMax, sMax , vMax)) phMin = hMin psMin = sMin pvMin = vMin phMax = hMax psMax = sMax pvMax = vMax # Display result image cv2.imshow('image', result) if cv2.waitKey(10) & 0xFF == ord('q'): break cv2.destroyAllWindows()

HSV lower/upper color threshold ranges

(hMin = 0 , sMin = 164, vMin = 0), (hMax = 179 , sMax = 255, vMax = 255)

Once you have determined your lower and upper HSV color ranges, you can segment your desired colors like this:

import numpy as np import cv2 image = cv2.imread('1.png') hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) lower = np.array([0, 164, 0]) upper = np.array([179, 255, 255]) mask = cv2.inRange(hsv, lower, upper) result = cv2.bitwise_and(image, image, mask=mask) cv2.imshow('result', result) cv2.waitKey() Share Improve this answer Follow edited Mar 30, 2022 at 20:00 answered Jan 25, 2020 at 3:44 nathancy's user avatar nathancynathancy 46.3k15 gold badges131 silver badges153 bronze badges 6
  • 9 This was extremely helpful. Made figuring out an appropriate HSV range 20x faster. Many mahalos! – DChaps Commented May 1, 2020 at 19:24
  • 6 Wow! Extremely helpful as commented already. Thanks for sharing! – KlopDesign Commented May 29, 2020 at 14:36
  • 6 Pure awesomeness! Thank you very much – Seminko Commented Nov 15, 2020 at 11:29
  • 2 Just want to echo the above comments and say that this colorpicker is amazing. Super helpful for getting 90% of the way to accurate HSV thresholding, many many thanks. – BeginnersMindTruly Commented Nov 6, 2021 at 21:14
  • Amazingly useful, thanks so much for this! – William Smith Commented Dec 11, 2022 at 23:35
| Show 1 more comment 33

I Created this simple program to get HSV Codes in realtime

import cv2 import numpy as np cap = cv2.VideoCapture(0) def nothing(x): pass # Creating a window for later use cv2.namedWindow('result') # Starting with 100's to prevent error while masking h,s,v = 100,100,100 # Creating track bar cv2.createTrackbar('h', 'result',0,179,nothing) cv2.createTrackbar('s', 'result',0,255,nothing) cv2.createTrackbar('v', 'result',0,255,nothing) while(1): _, frame = cap.read() #converting to HSV hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV) # get info from track bar and appy to result h = cv2.getTrackbarPos('h','result') s = cv2.getTrackbarPos('s','result') v = cv2.getTrackbarPos('v','result') # Normal masking algorithm lower_blue = np.array([h,s,v]) upper_blue = np.array([180,255,255]) mask = cv2.inRange(hsv,lower_blue, upper_blue) result = cv2.bitwise_and(frame,frame,mask = mask) cv2.imshow('result',result) k = cv2.waitKey(5) & 0xFF if k == 27: break cap.release() cv2.destroyAllWindows() Share Improve this answer Follow answered Sep 25, 2014 at 16:58 Aruldd's user avatar ArulddAruldd 5096 silver badges6 bronze badges 1
  • 9 LOL, I had written same code with printing the final HSV values used github.com/saurabheights/ImageProcessingExperimentScripts/blob/… – saurabheights Commented Oct 15, 2016 at 4:48
Add a comment | 11

I created a simple (more proper) tool using opencv-python for this purpose. Thought it would be useful for someone stumbled here like I did earlier this year

enter image description here

Since the tool itself is written using python cv2, it would be guaranteed to use the same range. Also there's a slider for erode and dilate since usually computer vision project need these two feature

You can clone the tool from here https://github.com/hariangr/HsvRangeTool

Share Improve this answer Follow answered Oct 10, 2021 at 14:09 Hari Anugrah's user avatar Hari AnugrahHari Anugrah 5441 gold badge7 silver badges13 bronze badges 2
  • awesome tool, thanks for sharing, what does the copy button does?, I was expecting to copy the values – Joe Cabezas Commented Oct 15, 2021 at 5:19
  • 1 @JoeCabezas I completely forgot about the button, I just implemented it to print the hsv range to console. Thank you. – Hari Anugrah Commented Oct 19, 2021 at 9:54
Add a comment | 6

OpenCV HSV range is: H: 0 to 179 S: 0 to 255 V: 0 to 255

On Gimp (or other photo manipulation sw) Hue range from 0 to 360, since opencv put color info in a single byte, the maximum number value in a single byte is 255 therefore openCV Hue values are equivalent to Hue values from gimp divided by 2.

I found when trying to do object detection based on HSV color space that a range of 5 (opencv range) was sufficient to filter out a specific color. I would advise you to use an HSV color palate to figure out the range that works best for your application.

HSV color palate with color detection in HSV space

Share Improve this answer Follow answered Mar 1, 2017 at 0:27 Sami Dalati's user avatar Sami DalatiSami Dalati 1611 silver badge4 bronze badges Add a comment | 6

To find the HSV value of Green, try following commands in Python terminal

green = np.uint8([[[0,255,0 ]]]) hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV) print hsv_green [[[ 60 255 255]]] Share Improve this answer Follow answered Oct 31, 2018 at 6:47 Masum Billah's user avatar Masum BillahMasum Billah 2,3891 gold badge23 silver badges21 bronze badges Add a comment | 2

You can use GIMP or PaintDotNet to get the exact range of HSV. But the problem is that the HSV range in graphics software is different from the same range in OpenCV, so you need a function to correct this for you. For this purpose, you can use the following function.

def fixHSVRange(h, s, v): # Normal H,S,V: (0-360,0-100%,0-100%) # OpenCV H,S,V: (0-180,0-255 ,0-255) return (180 * h / 360, 255 * s / 100, 255 * v / 100)

enter image description here

For example you can use it something like this:

im=cv2.imread("image.jpg",1) im_hsv = cv2.cvtColor(im, cv2.COLOR_BGR2HSV) color1 = fixHSVRange(h=10, s=20, v=0) color2 = fixHSVRange(h=30, s=70, v=100) mask = cv2.inRange(im_hsv, color1, color2) cv2.imwrite("mask.jpg",mask)

enter image description here

Share Improve this answer Follow edited Aug 20, 2021 at 5:35 answered May 7, 2021 at 10:19 Shamshirsaz.Navid's user avatar Shamshirsaz.NavidShamshirsaz.Navid 2,3623 gold badges24 silver badges39 bronze badges Add a comment | 0

Most of the methods mentioned above usually require some knowledge of the colour range for a particular colour followed by trial and error to get the right range. But the official documentation of OpenCV suggests a better way to find HSV lower and upper bounds even for the colours that are not very common.

How to find HSV values to track?

This is a common question found in stackoverflow.com. It is very simple and you can use the same function, cv.cvtColor(). Instead of passing an image, you just pass the BGR values you want. For example, to find the HSV value of Green, try the following commands in a Python terminal:

You can find the exact pixel values (BGR) of the required object and use them for example green (0, 255, 0)

green = np.uint8([[[0,255,0 ]]]) hsv_green = cv.cvtColor(green,cv.COLOR_BGR2HSV) print(hsv_green) [[[60 255 255]]]

Now you take [H-10, 100,100] and [H+10, 255, 255] as the lower bound and upper bound respectively. Apart from this method, you can use any image editing tools like GIMP or any online converters to find these values, but don't forget to adjust the HSV ranges.

Source: OpenCV Colorspaces and Object Tracking GIMP - Image Manipulating Tool

Share Improve this answer Follow answered Feb 22, 2022 at 16:56 Shreyas Vedpathak's user avatar Shreyas VedpathakShreyas Vedpathak 4506 silver badges11 bronze badges Add a comment | 0

I was also struggling to find what HSV values to choose (to ultimately select regions). With quite some googling I made this small script to inspect HSV values in my image.

It opens your image (adjust the path at cv2.imread). When you click at a point of interest in the image, it prints the location of mouse-click and HSV values at that location in the image.

import cv2 def on_mouse(event, x, y, flags, param): if event == cv2.EVENT_LBUTTONDOWN: hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) print("HSV values at ({}, {}): {}".format(x, y, hsv[y, x])) img = cv2.imread(‘\path\to\your\image\piccie.png’) cv2.namedWindow("image") cv2.setMouseCallback("image", on_mouse) while True: cv2.imshow("image", img) if cv2.waitKey(1) & 0xFF == ord('q'): break cv2.destroyAllWindows() Share Improve this answer Follow answered Jul 3, 2023 at 17:55 Danielle_Z's user avatar Danielle_ZDanielle_Z 311 silver badge4 bronze badges Add a comment | Highly active question. Earn 10 reputation (not counting the association bonus) in order to answer this question. The reputation requirement helps protect this question from spam and non-answer activity.

Not the answer you're looking for? Browse other questions tagged or ask your own question.

  • The Overflow Blog
  • We'll Be In Touch - A New Podcast From Stack Overflow!
  • The app that fights for your data privacy rights
  • Featured on Meta
  • More network sites to see advertising test
  • We’re (finally!) going to the cloud!
  • Call for testers for an early access release of a Stack Overflow extension...

Linked

2 Finding exact HSV values of colors 1 how to i specify the upper and the lower value of a color in HSV opencv python 0 Get range of HSV values from selected portion of an image in python 0 Extracting GREY colour from image openCv 0 Cleaning image by keeping one specific color <np.where python image processing> 36 How can I define a threshold value to detect only green colour objects in an image with Python OpenCV? 5 How to find the RED color regions using OpenCV? 7 Remove green background screen from image using OpenCV/Python 2 how to fill the hollow lines opencv 4 Remove everything of a specific color (with a color variation tolerance) from an image with Python See more linked questions 2 HSV colour space and CvInRangeS function 3 HSV color range detection 17 Identifying the range of a color in HSV using OpenCV 3 Get right HSV color inRange in OpenCV (Java) 8 OpenCV inRange() is working for RGB but not HSV color space 8 OpenCV: Choosing HSV thresholds for color filtering 0 What HSV color range should I use in openCV to filter out blue pixels? 1 HSV colour range in openCV 3 Correct colorspace for cv2.inRange() function 1 How to define boundaries for HSV color in OpenCV

Hot Network Questions

  • Discrimination on the grounds of unsavoury religious beliefs?
  • What is it called when you have a hobby where you're good enough at to impress others but you yourself know you're only beginning?
  • Why does C#'s Thread.MemoryBarrier() use "lock or" instead of mfence?
  • Is there a theorem in metaphysics that basically says, "Biting the bullet will be inevitable in any metaphysical theory?"
  • Stable points in GIT: geometric picture
  • Why do some people write text all in lower case?
  • Categories in which isomorphism of stalks does not imply isomorphism of sheaves
  • Why am I getting no output in tcpdump even though there is data being sent and received when using network namespaces?
  • How to create a thesis flowchart using Mathematica?
  • Is recursive variable assignment bad even if recursively assigning single row?
  • Where in the Gospels does Jesus explain what 'The Truth' is?
  • Can I protect my EV car charger's cable with aluminum tape and a stainless steel hose helix?
  • Can we use the simple present tense to express a habit that starts just about 24 hours or less ago?
  • What is the Calvinist/Reformed solution to the Problem of Hell?
  • Why does 写真に収めとこ mean take a picture? And what is the purpose of とこ in this case?
  • Can a storage device completely erase itself while performing the erase?
  • Why would you not issue orders to a facility?
  • The Talking Dog's Treats
  • Testing Puzzles for Puzzle Book: Enigmatic Puzzle
  • How SMA (or RF) connector's impedance is measured and rated?
  • Why the second C in "recyceln" is pronounced [k] instead of [ts]?
  • Understanding Linux 'top' command: Memory vs Swap display format confusion
  • Get number of pixels in raster layer with valid data
  • endless looping in minimax
more hot questions Question feed Subscribe to RSS Question feed

To subscribe to this RSS feed, copy and paste this URL into your RSS reader.

lang-py

Từ khóa » Hsv Color Space Python