Tracking white color using python opencv

72,441

Solution 1

I wrote this for tracking white color :

import cv2
import numpy as np

cap = cv2.VideoCapture(0)

while(1):

    _, frame = cap.read()
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

    # define range of white color in HSV
    # change it according to your need !
    lower_white = np.array([0,0,0], dtype=np.uint8)
    upper_white = np.array([0,0,255], dtype=np.uint8)

    # Threshold the HSV image to get only white colors
    mask = cv2.inRange(hsv, lower_white, upper_white)
    # Bitwise-AND mask and original image
    res = cv2.bitwise_and(frame,frame, mask= mask)

    cv2.imshow('frame',frame)
    cv2.imshow('mask',mask)
    cv2.imshow('res',res)

    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break

cv2.destroyAllWindows()

I tried to track the white screen of my phone and got this :

enter image description here

You can try changing the HSV values You might also try HSL color space as Legat said, it would be more accurate

Solution 2

Let's take a look at HSV color space:

enter image description here

You need white, which is close to the center and rather high. Start with

sensitivity = 15
lower_white = np.array([0,0,255-sensitivity])
upper_white = np.array([255,sensitivity,255])

and then adjust the threshold to your needs.

You might also consider using HSL color space, which stands for Hue, Saturation, Lightness. Then you would only have to look at lightness for detecting white and recognizing other colors would stay easy. Both HSV and HSL keep similar colors close. Also HSL would probably prove more accurate for detecting white - here is why:

enter image description here

Solution 3

Here's an HSV color thresholder script to determine the lower and upper bounds using sliders

enter image description here

Results

Using this sample image

With these lower/upper thresholds

lower_white = np.array([0,0,168])
upper_white = np.array([172,111,255])

We get isolated white pixels (left) and the binary mask (right)

Here's the script, remember to change the input image path

import cv2
import sys
import numpy as np

def nothing(x):
    pass

# Load in image
image = cv2.imread('1.jpg')

# Create a window
cv2.namedWindow('image')

# create trackbars for color change
cv2.createTrackbar('HMin','image',0,179,nothing) # Hue is from 0-179 for Opencv
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 to check if HSV min/max value changes
hMin = sMin = vMin = hMax = sMax = vMax = 0
phMin = psMin = pvMin = phMax = psMax = pvMax = 0

output = image
wait_time = 33

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 max HSV values to display
    lower = np.array([hMin, sMin, vMin])
    upper = np.array([hMax, sMax, vMax])

    # Create HSV Image and threshold into a range.
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(hsv, lower, upper)
    output = 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 output image
    cv2.imshow('image',output)

    # Wait longer to prevent freeze for videos.
    if cv2.waitKey(wait_time) & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()
Share:
72,441
user3429616
Author by

user3429616

Updated on October 02, 2020

Comments

  • user3429616
    user3429616 over 3 years

    I would like to track white color using webcam and python opencv. I already have the code to track blue color.

    _, frame = cap.read()
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    
    # define range of blue color in HSV
    lower_blue = np.array([110,100,100])
    upper_blue = np.array([130,255,255])
    
    #How to define this range for white color
    
    
    # Threshold the HSV image to get only blue colors
    mask = cv2.inRange(hsv, lower_blue, upper_blue)
    # Bitwise-AND mask and original image
    res = cv2.bitwise_and(frame,frame, mask= mask)
    
    cv2.imshow('frame',frame)
    cv2.imshow('mask',mask)
    cv2.imshow('res',res)
    

    what values should I give as lower bound and upper bound to track white color!!?? I tried changing values and I got other colors but no luck with the white color!!!

    is that HSV values or BGR values specified as lower and upper bounds???

    PS : I must get the last result as a binary image for further processing!!

    Please help me !!!

  • user3429616
    user3429616 about 10 years
    How to reduce the useless noise !!!! everythingis getting tracked when i use a webcam
  • Legat
    Legat about 10 years
    With new color components as well. You can set the thresholds higher. Let me edit the answer once more to clarify :)
  • Legat
    Legat about 10 years
    Ready. Used sensitivity instead of threshold. Lower sensitivity gives less noise.