Video Capture & Switching Colorspaces RGB / HSV
HSV, unlike RGB, separates the image intensity (lima), from the color information (chroma). This can be very useful if we want to focused on the intensity component, and leave the color components alone. Actually, in computer vision, we sometimes want to separate color components from intensity for various reasons, such as robustness to lighting changes, or removing shadows.
Picture source: HSL_and_HSV
Note: For HSV, Hue range is [0,179], Saturation range is [0,255] and Value range is [0,255].
"The big reason is that it separates color information (chroma) from intensity or lighting (luma). Because value is separated, you can construct a histogram or thresholding rules using only saturation and hue. This in theory will work regardless of lighting changes in the value channel. In practice it is just a nice improvement. Even by singling out only the hue you still have a very meaningful representation of the base color that will likely work much better than RGB. The end result is a more robust color thresholding over simpler parameters."
- from Why is color segmentation easier on HSV?
In OpenCV, there are several colorspace conversions (more thant 150): RGB ↔ GRAY, RGB ↔ CIE, RGB ↔ YCrCb, RGB ↔ HSV, RGB ↔ HSL etc. But in this chapter, we'll be focused on the most widely used ones: BGR ↔ Gray and BGR ↔ HSV.
To convert colorspace, we'll use cv2.cvtColor(input_image, flag) where flag determines the type of conversion:
- BGR → Gray : cv2.COLOR_BGR2GRAY
- BGR → HSV :cv2.COLOR_BGR2HSV
The following code is to capture video which could be either live stream or file stream. To capture a video, we need to create a VideoCapture object. Its argument can be either the device index or the name of a video file. Device index is just the number to specify which camera. Normally one camera will be connected (index = 0) or the 2nd camera (index = 1).
# capture.py import numpy as np import cv2 # Capture video from camera # cap = cv2.VideoCapture(0) # Capture video from file cap = cv2.VideoCapture('BlueUmbrella.webm') while(cap.isOpened()): # Capture frame-by-frame ret, frame = cap.read() # Our operations on the frame come here gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # Display the resulting frame cv2.imshow('frame',gray) if cv2.waitKey(1) & 0xFF == ord('q'): break # When everything done, release the capture cap.release() cv2.destroyAllWindows()
The video is available: BlueUmbrella.webm.
In next section, we will modify the code slightly to play with color space.
In this section, we want to track blue umbrella from the Pixar movie clip. How?
After converting BGR image to HSV, we extract a blue colored object. The reason for convderting to HSV colorspace is because it is more easier to represent a color than RGB colorspace. Here are the steps to take:
- Take each frame of the video.
- Convert from BGR to HSV color-space.
- We threshold the HSV image for a range of blue color.
- Now extract the blue object alone, we can do whatever on that image we want.
# cspace.py import cv2 import numpy as np cap = cv2.VideoCapture('BlueUmbrella.webm') while(1): # Take each frame _, frame = cap.read() # Convert BGR to HSV hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) # define range of blue color in HSV lower_blue = np.array([110,50,50]) upper_blue = np.array([130,255,255]) # 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) k = cv2.waitKey(5) & 0xFF if k == 27: break cv2.destroyAllWindows()
Here is the output from the code:
- Original image
- Threshold the HSV image to get only blue colors - mask
- Bitwise-AND mask and original image - res
Original files in other formats:
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization