9

我已经看到关于皮肤 HSV 颜色空间范围的所有问题
但我只能弄清楚这一点

代码 -

CvScalar  hsv_min = cvScalar(0, 30, 60, 0);
CvScalar  hsv_max = cvScalar(20, 150, 255, 0);
//range I am using is { 0,30,60,0 & 20,150,255,0 }
cvCvtColor(src, hsv_image, CV_BGR2HSV);
cvInRangeS (hsv_image, hsv_min, hsv_max, hsv_mask);
cvDilate(hsv_mask,hsv_mask,0,1);
cvErode(hsv_mask,hsv_mask,0,1);
cvSmooth( hsv_mask, hsv_mask, CV_MEDIAN);

这个范围 {0,30,60,0 & 20,150,255,0} )的问题是它甚至可以检测到红色,当您将手放在红色背景中时,它不会跟踪您的皮肤......
请帮助!

4

9 回答 9

9

据此: http: //matmdia.org/sibgrapi2009/media/posters/59928.pdf

通道 H 中的皮肤的特征值介于 0 和 50 之间,通道 S 中的值从 0.23 到 0.68 用于亚洲和高加索种族。

您必须格外小心图像中非常暗的部分,并且可能完全丢弃它们,因为 HSV 转换对于 V 的小值会变得非常嘈杂。

根据您的约束条件,您还可以考虑使用彩色手套(场景中不正常出现的某种颜色),或设置与红色不同颜色的背景,即远离肤色(洋红色、绿色、任何)。

于 2012-01-06T11:22:55.277 回答
7

基本上,很难有一个固定的皮肤颜色范围,因为即使你只想检测自己的皮肤,它的颜色实际上也会根据光照条件发生很大变化。

所以,也许你可以使用 2011 年这篇精彩的科学文章的想法:

http://www.robots.ox.ac.uk/~vgg/research/hands/

基本上,它们检测面部(使用 oepncv 很容易)。然后他们提取面部的肤色(这对图像上的人来说非常具体)。然后他们使用这种颜色检测皮肤。由于颜色非常具体,因此与固定颜色范围相比,它们的错误检测应该要少得多。

于 2012-01-06T10:55:41.463 回答
7

我已经尝试过
lower = np.array([0, 10, 60], dtype = "uint8") upper = np.array([20, 150, 255], dtype = "uint8") 它几乎给出了很好的结果。

于 2017-03-19T09:56:59.967 回答
5

我知道现在回复这个已经太晚了。但我也在做同样的事情,我使用 K 表示聚类来获取肤色。那就是首先你必须检测人脸,我正在使用 Haar 级联分类器来做这件事,然后根据人脸的坐标你可以裁剪人脸,然后用它作为源来聚类颜色。找出元素最多的集群,这将是你的肤色。或者在不指定一个特定值的情况下,您可以获得集群中心点,您可以通过减去和添加特定值将其用作范围。这将很有帮助http://answers.opencv.org/question/23196/k-mean-clustering-of-hsv-histogram-of-frames-of-a-video/

于 2015-12-03T04:57:34.160 回答
3

OpenCv 上存在自适应皮肤检测器,请参见 samples/c/adaptiveskindetector_sample.cpp

于 2012-01-22T20:42:42.780 回答
3

在您的代码中尝试此预处理功能:

def preprocess(action_frame):

    blur = cv2.GaussianBlur(action_frame, (3,3), 0)
    hsv = cv2.cvtColor(blur, cv2.COLOR_RGB2HSV)

    lower_color = np.array([108, 23, 82])
    upper_color = np.array([179, 255, 255])

    mask = cv2.inRange(hsv, lower_color, upper_color)
    blur = cv2.medianBlur(mask, 5)

    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (8, 8))
    hsv_d = cv2.dilate(blur, kernel)

return hsv_d

我已经使用这个几个月了。它可能永远解决你的问题。

于 2019-01-21T12:47:05.177 回答
1

如果您使用视频字幕,您应该担心在大多数情况下相机会自动调整对比度,这会对您的图像产生影响,因为您将有显着的色调差异,您还应该考虑阴影和影响皮肤的光源

于 2015-04-13T15:55:39.390 回答
1

Deepgaze 是一个除了其他功能外还具有皮肤检测功能的库。

DeepGaze Github

他用:

[0, 58, 50] lower bound skin HSV
[30, 255, 255] upper bound skin HSV

他在 Github 上的反应非常好,因此可以选择联系他并询问他是如何得出这些数字的。

于 2019-08-25T04:20:06.713 回答
1

这是皮肤检测的理想解决方案之一。

上面的大多数答案都适用于各种肤色,如深红色、浅黄色、浅橙色……。但这些颜色不应该是肤色,因为它们在图像中几乎看不到。

正如您在这张图片中看到的,红色范围在 350 到 20 之间。 在此处输入图像描述

因此,皮肤有两种可能的色调范围。

单纯疱疹病毒范围

#1st range of Hue
lower -> [0, 30, 53]
upper -> [20, 150, 255]

#2nd range of Hue (OpenCV converts 360 to 180)
lower2 -> [172, 30, 53]
upper2 -> [180, 180, 210]

完整代码:

import os, cv2
import numpy as np

image = cv2.imread(os.path.join('skin.png'))

# Covers both range
lower = np.array([0, 30, 53], dtype = "uint8")
upper = np.array([20, 180, 255], dtype = "uint8")

lower2 = np.array([172, 30, 53], dtype = "uint8")
upper2 = np.array([180, 180, 210], dtype = "uint8")

converted = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

skinMask = cv2.inRange(converted, lower, upper)
skinMask2 = cv2.inRange(converted, lower2, upper2)

#Gaussian Blur
skinMask = cv2.GaussianBlur(skinMask, (3, 3), 0)
skinMask2 = cv2.GaussianBlur(skinMask2, (3, 3), 0)

skin1 = cv2.bitwise_and(image, image, mask = skinMask)
skin2 = cv2.bitwise_and(image, image, mask = skinMask2)
skin = cv2.bitwise_or(skin1,skin2) #adding both ranges

# show the skin in the image along with the mask
cv2.imshow("images", np.hstack([frame, skin]))
cv2.waitKey(0)
于 2021-10-06T08:41:15.070 回答