I was altering an OpenCV 3.0 Python code in order to recognize hand gestures by drawing a contour around the fingers using convex-hull to recognize the points on fingertips.
Anyway, the code works but it just works with dark (blackish) backgrounds. The code uses threshold to binarize the image, so the brightest shape will be the hand (so the background is black and the hand shape white).
How can I alter threshold in order to binarize the image to just pick the skin color and not the brightest colors?
For example, when finished binarizing, the black part of the video stream image would be all of the colors that aren't skin-ish and the white part of the binarized image would be the skin-ish color.
Here's the code:
def readCamera(self):
_, self.original = self.cap.read()
self.original = cv2.flip(self.original, 1)
def threshold(self):
hsv = cv2.cvtColor(self.original, cv2.COLOR_BGR2HSV)
value = (31, 31)
blurred = cv2.GaussianBlur(hsv, value, 0)
_, self.thresholded = cv2.threshold(hsv[:,:,0], 0, 255,
cv2.THRESH_BINARY+cv2.THRESH_OTSU)
def extractContours(self):
_, self.contours, _ = cv2.findContours(self.thresholded.copy(),
cv2.RETR_TREE,
cv2.CHAIN_APPROX_SIMPLE)
Once you convert your frame to HSV, the skin colour gets a more greenish tinge. Apply an RGB filter on this image to filter out that skin portion. Use trackbars if necessary, as shown below:
import cv2
def nothing(x): #needed for createTrackbar to work in python.
pass
cap = cv2.VideoCapture(0)
cv2.namedWindow('temp')
cv2.createTrackbar('bl', 'temp', 0, 255, nothing)
cv2.createTrackbar('gl', 'temp', 0, 255, nothing)
cv2.createTrackbar('rl', 'temp', 0, 255, nothing)
cv2.createTrackbar('bh', 'temp', 255, 255, nothing)
cv2.createTrackbar('gh', 'temp', 255, 255, nothing)
cv2.createTrackbar('rh', 'temp', 255, 255, nothing)
while true
ret,img=cap.read()#Read from source
hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
bl_temp=cv2.getTrackbarPos('bl', 'temp')
gl_temp=cv2.getTrackbarPos('gl', 'temp')
rl_temp=cv2.getTrackbarPos('rl', 'temp')
bh_temp=cv2.getTrackbarPos('bh', 'temp')
gh_temp=cv2.getTrackbarPos('gh', 'temp')
rh_temp=cv2.getTrackbarPos('rh', 'temp')
thresh=cv2.inRange(hsv,(bl_temp,gl_temp,rl_temp),(bh_temp,gh_temp,rh_temp))
if(cv2.waitKey(10) & 0xFF == ord('b')):
break #break when b is pressed
cv2.imshow('Video', img)
cv2.imshow('thresh', thresh)