Last active
October 22, 2017 22:42
-
-
Save nhomble/4daf95d7954be969c330177719b0d712 to your computer and use it in GitHub Desktop.
demonstrate easy color extraction with HSV rather than RGB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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