10
votes

I am working on identifying the color yellow using openCV in python. I have come to this step where I have to define the lower and upper range of the color yellow in HSV.

Example for defining the range of Blue:

lower_blue = np.array([110,50,50])
upper_blue = np.array([130,255,255])

The HSV is usually defined in percentage, I want to know how to define the range for yellow like the example.

This is the colorspaces tutorial I've been following.

Edit: There are some suggestions in the blog mentioned above, but it does not give me the desired output.

6
have a look at i.stack.imgur.com/gCNJp.jpg . hue values are given in degrees. Opencv uses range 0..180 instead of 0..360 so you have to divide the degree values by 2. Choose any range around your target value. for example yellow has hue val 60 degrees. So your hue range might be from 60/2 - 10 to 60/2 + 10 OR from 60/2-5 to 60/2+5 depends on how far you want to go away from perfect yellow.Micka

6 Answers

14
votes

It's Simple. You can use the function, cv2.cvtColor().

Instead of passing an image, you just pass the BGR values which you want to convert to hsv.

For Example, to find the HSV value of Green, type the following command

import numpy as np
import cv2

green = np.uint8([[[0, 255, 0]]]) #here insert the bgr values which you want to convert to hsv
hsvGreen = cv2.cvtColor(green, cv2.COLOR_BGR2HSV)
print(hsvGreen)

lowerLimit = hsvGreen[0][0][0] - 10, 100, 100
upperLimit = hsvGreen[0][0][0] + 10, 255, 255

print(upperLimit)
print(lowerLimit)

Now, the Upper Limit will be [H+10, 100,100]

and Lower Limit will be [H-10, 255, 255]

Official documentation (see the last part of following webpage) https://docs.opencv.org/3.1.0/df/d9d/tutorial_py_colorspaces.html

10
votes

take a look at this page you will find HSV values of the color you want.

For HSV, Hue range is [0,179], Saturation range is [0,255] and Value range is [0,255]. Different softwares use different scales. So if you are comparing OpenCV values with them, you need to normalize these ranges.

i guess you are searching the values like below for yellow

lower_blue = np.array([25,50,50])
upper_blue = np.array([32,255,255])
2
votes

You can use this sample color palette. First value is the upper limit and second value is the lower limit

color_dict_HSV = {'black': [[180, 255, 30], [0, 0, 0]],
              'white': [[180, 18, 255], [0, 0, 231]],
              'red1': [[180, 255, 255], [159, 50, 70]],
              'red2': [[9, 255, 255], [0, 50, 70]],
              'green': [[89, 255, 255], [36, 50, 70]],
              'blue': [[128, 255, 255], [90, 50, 70]],
              'yellow': [[35, 255, 255], [25, 50, 70]],
              'purple': [[158, 255, 255], [129, 50, 70]],
              'orange': [[24, 255, 255], [10, 50, 70]],
              'gray': [[180, 18, 230], [0, 0, 40]]}
1
votes

if i want to do it ,first find rgb numbers for yellow (i use 'Edit colors 'in paint) then change them to HSV whith this method:

 u = np.uint8([[[0,236,236]]])
 # define range of blue color in HSV
 lower_yellow = np.array(cv2.cvtColor(l,cv2.COLOR_BGR2HSV))
 upper_yellow = np.array( cv2.cvtColor(u,cv2.COLOR_BGR2HSV))```

0
votes

If you take pictures from a camera, it will depend on lighting condition. If your aim is to track some objects, you should always update your HSV values. My advise is keep your boundary as narrow as possible in your lighting condition.

0
votes

COLOR RANGE

color_dict_HSV = {'black': [[180, 255, 30], [0, 0, 0]],
              'white': [[180, 18, 255], [0, 0, 231]],
              'red1': [[180, 255, 255], [159, 50, 70]],
              'red2': [[9, 255, 255], [0, 50, 70]],
              'green': [[89, 255, 255], [36, 50, 70]],
              'blue': [[128, 255, 255], [90, 50, 70]],
              'yellow': [[35, 255, 255], [25, 50, 70]],
              'purple': [[158, 255, 255], [129, 50, 70]],
              'orange': [[24, 255, 255], [10, 50, 70]],
              'gray': [[180, 18, 230], [0, 0, 40]]}

CREDITS:

Ali Hashemian

HOW TO REMOVE A COLOR FROM YOUR IMAGE USING OPENCV

Since most of you would like to do that, i.e. in my case the task was to remove blue color from the image, I used the following code, to remove blue ink stamps and, blue tick marks from my image in order for proper OCR using Tesseract.

[COLOR REMOVAL] CODE

import cv2
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

# image path:    
#path = "D://opencvImages//"
#fileName = "out.jpg"

# Reading an image in default mode:
inputImage = cv2.imread('0.jpg')

# Convert RGB to grayscale:
grayscaleImage = cv2.cvtColor(inputImage, cv2.COLOR_BGR2GRAY)

# Convert the BGR image to HSV:
hsvImage = cv2.cvtColor(inputImage, cv2.COLOR_BGR2HSV)

# Create the HSV range for the blue ink:
# [128, 255, 255], [90, 50, 70]
lowerValues = np.array([90, 50, 70])
upperValues = np.array([128, 255, 255])

# Get binary mask of the blue ink:
bluepenMask = cv2.inRange(hsvImage, lowerValues, upperValues)
# Use a little bit of morphology to clean the mask:
# Set kernel (structuring element) size:
kernelSize = 3
# Set morph operation iterations:
opIterations = 1
# Get the structuring element:
morphKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (kernelSize, kernelSize))
# Perform closing:
bluepenMask = cv2.morphologyEx(bluepenMask, cv2.MORPH_CLOSE, morphKernel, None, None, opIterations, cv2.BORDER_REFLECT101)

# Add the white mask to the grayscale image:
colorMask = cv2.add(grayscaleImage, bluepenMask)
_, binaryImage = cv2.threshold(colorMask, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
cv2.imwrite('bwimage.jpg',binaryImage)
thresh, im_bw = cv2.threshold(binaryImage, 210, 230, cv2.THRESH_BINARY)
kernel = np.ones((1, 1), np.uint8)
imgfinal = cv2.dilate(im_bw, kernel=kernel, iterations=1)
cv2.imshow(imgfinal)

BEFORE [Original Image]

Original Image

Blue Mark Extraction

Blue Tick Marks Determined

Final Image

enter image description here

Here you can see that all of the tick marks are almost, removed the reason is that because there is always room for improvement, but this, as it seems, is the best we can get because even removing these little marks is not going to have a profound effect on the OCR using Tesseract.

HOPE THAT HELPS!