简体   繁体   中英

Computer vision: Creating mask of hand using OpenCv and Python

I am trying to create the mask from hand (black - background, white - hand)

This is the first original image 1 :

在此处输入图片说明

This is my code:

hand = cv2.imread('hand.jpg')

blur = cv2.GaussianBlur(hand, (3, 3), 0)

hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)

mask2 = cv2.inRange(hsv, np.array([2, 0, 0]), np.array([20, 255, 255]))

kernel = np.ones((7, 7))
dilation = cv2.dilate(mask2, kernel, iterations=1)
erosion = cv2.erode(dilation, kernel, iterations=1)

filtered = cv2.GaussianBlur(erosion, (5, 5), 0)

ret, thresh = cv2.threshold(filtered, 90, 255, 0)

cv2.imshow('Threshold', thresh)

And the result is:

在此处输入图片说明

But I need have better result - like that:

在此处输入图片说明

What should I do?

[EDIT]

second image with different background:

在此处输入图片说明

Result using @Rotem code:

在此处输入图片说明

1 Ajay Kumar. IIT Delhi Palmprint Image Database version 1.0. 2007

You may solve it by applying threshold on the red color channel.

The background color is dark blue and green, and the hand color is bright and tend to red color, so using only the red color channel may give better results than converting to HSV.

The solution below uses the following stages:

  • Extract red color channel - use the red channel as Grayscale image.
  • Apply binary threshold using automatically selected threshold (using cv2.THRESH_OTSU parameter).
  • Use "opening" morphological operation for clearing some small dots (noise).
    Opening is equivalent to applying erode and than dilate.
  • Use "closing" morphological operation for closing small gaps (I chose disk shaped mask).
    Closing is equivalent to applying dilate and than erode.

Here is the code:

import cv2

img = cv2.imread('hand.jpg')

# Extract red color channel (because the hand color is more red than the background).
gray = img[:, :, 2]

# Apply binary threshold using automatically selected threshold (using cv2.THRESH_OTSU parameter).
ret, thresh_gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

# Use "opening" morphological operation for clearing some small dots (noise)
thresh_gray = cv2.morphologyEx(thresh_gray, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3)))

# Use "closing" morphological operation for closing small gaps
thresh_gray = cv2.morphologyEx(thresh_gray, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9,9)))

# Display result:
cv2.imshow('thresh_gray', cv2.resize(thresh_gray, (thresh_gray.shape[1]//2, thresh_gray.shape[0]//2)))
cv2.waitKey(0)
cv2.destroyAllWindows()

Result:
在此处输入图片说明

I think you may improve the result by finding the contour of the hand, and proximate it to polygon with less vertices (but it might be an over-fitting).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM