【问题标题】:Exact Skin color HSV range准确的肤色 HSV 范围
【发布时间】:2012-02-03 22:42:36
【问题描述】:

我已经看到关于皮肤 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 } )它是否甚至可以检测到红色,并且当您将手放在红色背景中时,它不会跟踪您的皮肤...
请帮助!!!

【问题讨论】:

  • 那么非裔美国人呢(如果这不再是正确的术语的话)?还是美洲原住民?还是印度人?还是澳大利亚原住民?还是小绿人?
  • 我说的是一般...应该是针对人类皮肤的...如果是这种情况,请给我不同的范围...我认为我们可以将 cvInRangeS 用于多个范围...跨度>
  • 这就是你的问题。由于您只对人类感兴趣(而且我假设您不赞同一些将其他种族视为非人类的奇怪种族主义哲学),我们只能数出小绿人。这仍然留下了一个大量颜色范围来满足。现在我假设这是用照片或视频做一些事情(告诉皮肤和其他所有东西之间的区别)所以,除非你的照片以某种方式被标记为只包含白种人或原住民之类的东西,否则能够分辨出差异的机会人类与非人类之间的差距很小。即使是多范围。
  • 现在这可能是可行的,如果有更多的限制,或者我假设你的实际需要完全错误。在这种情况下,请告诉我们。
  • @paxdiablo 我想追踪手...基本上是手表的AR...在那个用户将他的手保持在手的模板图像中,我们得到手腕与数字的距离。我们可以做的更多是让用户点击特定位置并获取 hsv 值...请帮助我....

标签: image-processing opencv computer-vision skin hsv


【解决方案1】:

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

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

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

根据您的限制条件,您还可以考虑使用彩色手套(场景中未正常显示的某种颜色),或设置与红色不同颜色的背景,即远离肤色(洋红色,绿色,随便)。

【讨论】:

  • 链接已失效,但this 似乎是同一篇文章。
【解决方案2】:

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

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

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

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

【讨论】:

  • 刚刚阅读您的评论并喜欢这个想法...因为我正在尝试做...让我看看您提供的链接...非常感谢您的回答... .
【解决方案3】:

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      OpenCv 上存在自适应皮肤检测器 见样本/c/adaptiveskindetector_sample.cpp

      【讨论】:

        【解决方案6】:

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

        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
        

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

        【讨论】:

        • 您是如何得出上下限的?你能看看我下面的回答,告诉我你对 deepgaze 边界的看法吗?
        • 我想知道你是使用 Mat 还是 IplImage 导致 OpenCV 将颜色转换为 BGR 而不是 RGB 所以 hsv 应该是 hsv = cv2.cvtColor(blur, CV_BGR2HSV)。
        • 为什么饱和度和值是255?这些也会检测到非常饱和的颜色。皮肤通常不是鲜红色。
        • 此解决方案不适用于深红色或浅橙色图像
        【解决方案7】:

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

        【讨论】:

          【解决方案8】:

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

          DeepGaze Github

          他使用:

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

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

          【讨论】:

            【解决方案9】:

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

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

            正如您在这张图片中看到的,红色范围在 350 到 20 之间。

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

            HSV 范围

            #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)
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-09-03
              • 1970-01-01
              • 2014-06-19
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多