4

I was looking at this question:

How to detect blue color object using opencv

Yet after much trial and error, I still can't figure out how to detect blue objects.

Here is my code:

import cv2
import numpy as np

cam=cv2.VideoCapture(0)
n=0

while True:
    print n
    returnVal,frame=cam.read()

    img=cv2.GaussianBlur(frame, (5,5), 0)
    img=cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

    blue_lower=np.array([150,150,0],np.uint8)
    blue_upper=np.array([180,255,255],np.uint8)
    blue=cv2.inRange(img,blue_lower,blue_upper)

    cv2.imshow('img',blue)

    n=n+1
    key = cv2.waitKey(10) % 0x100
    if key == 27: break #ESC 

I can detect red objects by setting the following lines:

red_lower=np.array([0,150,0],np.uint8)
red_upper=np.array([10,255,255],np.uint8)

When I put a blue piece of paper in front of my webcam using the first code, it just shows up black.

Can someone please help me to convert RGB for blue colours into HSV?

Many thanks in advance,

7
  • Maybe your blue paper has a smaller hue or less saturation. Have you tried increasing the ranges below h=150 and s = 150? Commented Jul 26, 2013 at 9:56
  • @w.m Rather counter-intuitively, the following values appear to work: blue_lower=np.array([100,150,0],np.uint8) blue_upper=np.array([120,255,255],np.uint8). Why is blue not between 150 and 180??? Commented Jul 26, 2013 at 10:02
  • upload.wikimedia.org/wikipedia/commons/a/a0/Hsl-hsv_models.svg Commented Jul 26, 2013 at 10:07
  • I've been playing around with your code, and it seems like it's not storing the values for colour in the way you think it is (or how i'd assume it would...) Commented Jul 26, 2013 at 10:12
  • I would say it almost certainly has to do with the RGB bytes being reversed... IF you swap R&B, it's equivalent to inverting the hue space. Commented Jul 26, 2013 at 10:17

3 Answers 3

8

Blue is represented in HSV at a hue of around 240 degrees out of 360. The Hue range in OpenCV-HSV is 0-180, to store the value in 8 bits. Thus, blue is represented in OpenCV-HSV as a value of H around 240 / 2 = 120.

To detect blue correctly, the following values could be chosen:

blue_lower=np.array([100,150,0],np.uint8)
blue_upper=np.array([140,255,255],np.uint8)
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much - saved the day!
2

Your colour model is set by the line:

   img=cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

To be using Hue, Saturation and Value, rather than the default Blue, Green, Red that OpenCV uses by default. See how the colour model works here.

Comments

0

There is a lot of trial and error involved in getting "your" blue tone. That's why i made this little routine to get those values. Think of it like a color picker for the range you want to display.

Think of this routine as a collab from every other response to this topic to create a tool that allows a bit of customization to your color selecting process

import cv2
import numpy as np

cap = cv2.VideoCapture(1, cv2.CAP_DSHOW)
cap.set(3,1280)
cap.set(4,1024)
     

cv2.namedWindow("Hsv Capture")

# create trackbars for color change
# IMPORTANT: You have to define the correct HSV opencv range hence 179,255,255
cv2.createTrackbar('H', 'Hsv Capture', 0, 179, nothing)
cv2.createTrackbar('S', 'Hsv Capture', 0, 255, nothing)
cv2.createTrackbar('V', 'Hsv Capture', 0, 255, nothing)

cv2.createTrackbar('H1', 'Hsv Capture', 0, 179, nothing)
cv2.createTrackbar('S1', 'Hsv Capture', 0, 255, nothing)
cv2.createTrackbar('V1', 'Hsv Capture', 0, 255, nothing)

while(True):

    ret, frame = cap.read()
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

    # Trackbars realtime position
    h1 = cv2.getTrackbarPos('H', 'Hsv Capture')
    s1 = cv2.getTrackbarPos('S', 'Hsv Capture')
    v1 = cv2.getTrackbarPos('V', 'Hsv Capture')

    h2 = cv2.getTrackbarPos('H1', 'Hsv Capture')
    s2 = cv2.getTrackbarPos('S1', 'Hsv Capture')
    v2 = cv2.getTrackbarPos('V1', 'Hsv Capture')

    #How to store the min and max values from the trackbars
    blue_MIN = np.array([h1, s1, v1], np.uint8)
    blue_MAX = np.array([h2, s2, v2], np.uint8)

    #After finding your values, you can replace them like this
    #blue_MIN = np.array([102, 73, 145], np.uint8)
    #blue_MAX = np.array([123, 182, 242], np.uint8)
            
    #Using inRange to find the desired range
    hsvCapture = cv2.inRange(frame,  blue_MIN, blue_MAX)

    cv2.imshow('Hsv Capture', hsvCapture)
    
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.