Skip to content

Instantly share code, notes, and snippets.

@nhomble
Last active October 22, 2017 22:42
Show Gist options
  • Save nhomble/4daf95d7954be969c330177719b0d712 to your computer and use it in GitHub Desktop.
Save nhomble/4daf95d7954be969c330177719b0d712 to your computer and use it in GitHub Desktop.
demonstrate easy color extraction with HSV rather than RGB
import cv2
import numpy as np
import matplotlib.pyplot as plt
"""
Starting motivation [https://docs.opencv.org/3.2.0/df/d9d/tutorial_py_colorspaces.html]
RGB has no concept of hue unlike HS* (in this case we will do HSV). While we can extract it, it's not as straightforward
as with HSV. In our image, let's say we want to find the green parts. In HSV, we can do a pretty good job by just with
just an arc in the hue and then a fixed saturation range and value. Green can only exist in ~[90,150] degrees. Given
that arc length, the green can be lighter or darker, more or less green, but it's green. For RGB, given a G value of
say (guessing) > 120, you can pick many values of green as a function of R, B and likewise many values of color with
G > 120 that really are closer to white if R=B=G.
To really see this, let's extract the red colors (the flower buds) and we'll also check the histogram of the resulting
image. We'll notice that for a small range of hue we see a variety of RGB values which shows the difficulty in doing
color extraction strictly from RGB.
"""
def rgb_hist(img):
return [cv2.calcHist([img], [c], None, [256], [0, 256]) for c in [0, 1, 2]]
monet = cv2.imread("./monet.jpg")
hsv = cv2.cvtColor(monet, cv2.COLOR_BGR2HSV)
# it's a circle
mask = cv2.bitwise_or(
cv2.inRange(hsv, np.array([0, 100, 100]), np.array([20, 256, 220])),
cv2.inRange(hsv, np.array([160, 100, 100]), np.array([180, 256, 220]))
)
res = cv2.bitwise_and(monet, monet, mask=mask)
cv2.imshow("raw", monet)
cv2.imshow("mask", mask)
cv2.imshow("extracted", res)
ignore_length = 1
hists = rgb_hist(res)
c = ['b', 'g', 'r']
for i, h in enumerate(hists):
plt.plot(range(256 - ignore_length), h[ignore_length:], c[i])
plt.show(block=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment