Sourav
Sourav

Reputation: 43

Open CV Hand Recognition - Making the backProjection of the palm more accurate?

I'm using a histogram back projection to detect my palm in a webcam video feed. I perfectly get the contours for the palm. The problem is, my face and other "skin colour" like objects are also getting detected. How do I make my histogram detect just my palm and nothing else(Increasing histogram accuracy)?

I use a region of the image of my palm to calculate the histogram before I run the program. enter image description here

Notice the door and face getting detected in the background:

Picture of the video feed: notice the door and face getting detected in the background

cap = cv2.VideoCapture(0)
while True:
    _, frame = cap.read()
    frame = cv2.flip(frame, 1)
    cv2.putText(frame, "Place region of the {} inside the box".format(objectName), (30,50), cv2.FONT_HERSHEY_SIMPLEX, 0.85, (255,0,105), 1, cv2.LINE_AA)
    cv2.rectangle(frame, (100, 100), (150, 150), (255, 0 , 255), 2)
    cv2.imshow("Video Feed", frame)
    key = cv2.waitKey(10)
    if key == 108:
        objectColor = frame[100:150, 100:150]
        break
    if key == 27:
        cv2.destroyAllWindows()
        cap.release()
        break
hsvObjectColor = cv2.cvtColor(objectColor, cv2.COLOR_BGR2HSV)
objectHist = cv2.calcHist([hsvObjectColor], [0,1], None, [12,15], [0,180,0,256])
cv2.normalize(objectHist, objectHist, 0,255,cv2.NORM_MINMAX)

The following code segment detects the palm using the above histogram.

hsvFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

objectSegment = cv2.calcBackProject([hsvFrame], [0,1], objectHist, [0,180,0,256], 1)
disc = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
cv2.filter2D(objectSegment, -1, disc, objectSegment)
_, threshObjectSegment = cv2.threshold(objectSegment,70,255,cv2.THRESH_BINARY)

threshObjectSegment = cv2.merge((threshObjectSegment,threshObjectSegment,threshObjectSegment))
locatedObject = cv2.bitwise_and(frame, threshObjectSegment)

locatedObjectGray = cv2.cvtColor(locatedObject, cv2.COLOR_BGR2GRAY)
_, locatedObjectThresh = cv2.threshold(locatedObjectGray, 70, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
locatedObject = cv2.medianBlur(locatedObjectThresh, 5)

Upvotes: 1

Views: 1785

Answers (2)

BasuruK
BasuruK

Reputation: 61

You can use Haarcascade to detect face and then just put a mask and remove it

Upvotes: 0

Prakhar Mohan
Prakhar Mohan

Reputation: 21

Since you are using color histogram, it is very difficult to prevent other similar color objects from getting segmented. So once the image segmentation is done and the hand and other stuffs are segmented,u can use connected components and then separate out hand region (by feature matching {hand's features will be different that the noise features}).

Another thing you can explore is temporal superpixel matching. If you can find the exact boundary of the hand in the first frame, you can segment it in consecutive frames using histogram and then locate the hand region by temporally matching the superpixels.

Upvotes: 1

Related Questions