图像给定像素的皮肤概率 [英] Skin probability of a given pixel of a image

查看:104
本文介绍了图像给定像素的皮肤概率的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出图像中所有像素的RGB值,我们如何才能找到给定像素具有肤色的概率以及图像所占百分比是肤色的概率。

Given RGB value's of all pixels of a image , how can we find the probability that the given pixel is of skin color and what percentage of the image is of skin color .

推荐答案

在Google上闲逛的人告诉我,白人肤色通常(或可能总体而言)或有时符合以下规则:

Noodling around on Google tells me that caucasian skin tones often, or maybe generally, or maybe sometimes conform to the following sort of rule:

Blue channel:  140-180
Green channel: Blue * 1.15
Red channel:   Blue * 1.5

因此,考虑到这一点,我使用以下命令行制作了一些与ImageMagick对应的色板:

So, with that in mind, I made some colour swatches that correspond to that with ImageMagick, using this command line:

#!/bin/bash
for b in $(seq 140 5 180); do
  g=$(echo "$b * 1.15/1" | bc)
  r=$(echo "$b * 1.5/1"  | bc)
  convert -label "R:$r,G:$g,B:$b" -size 200x200 xc:"rgb($r,$g,$b)" miff:-
done | montage - -frame 5 -tile 3x swatches.png

得到了:

好吧,那些看起来还算合理,现在我再次尝试通过ImageMagick使用那些来检测肤色。就目前而言,这样您就可以看到它,我将使用检测到的任何颜色将柠檬绿色作为肤色,使用此颜色,它位于上面确定的色调范围的中间:

Ok, those look kind of reasonable, now I try to use those to detect skin tones, again with ImageMagick. For the moment, and just so you can see it, I am going to colour lime-green everthing I detect as a skin-tone, using this which is right in the middle of the tonal range identified above:

convert -fuzz 5% face1.jpg -fill lime -opaque "rgb(240,184,160)" out.jpg

嗯,不是很好。

嗯,还是很垃圾-只吸收一部分皮肤和一些白衬衫领子。

Mmmm, still pretty rubbish - picking up only part of the skin and some of the white shirt collar. Different face maybe?

好吧,虽然发现他完全没法检测到他的脸的右侧,但在检测他方面还不错,但是从粉红色中我们仍然可以看到一些问题。卡迪拉克:

Ok, not bad at detecting him, although notice it completely fails to detect the right side of his face, however there are still a few problems as we can see from the pink cadillac:

和下面的Piggy小姐...

and Miss Piggy below...

也许我们可以在搜索中更具针对性,尽管我无法绘制它在3-D中,我可以在2-D中进行解释。而不是瞄准范围中心的单个大圆圈(实际上是3D空间中的球体),也许我们可以瞄准沿范围分布的一些较小的圆圈,从而包含较少的外来颜色...洋红色表示起毛程度。因此,而不是这样:

Maybe we can be a bit more targeted in our search, and, though I can't draw it in 3-D, I can explain in 2-D. Instead of targeting a single large circle (actually sphere in 3-D space) in the middle of our range, maybe we could target some smaller circles spread along our range and thereby include fewer extraneous colours... the magenta represents the degree of fuzz. So rather than this:

我们可以这样做:

使用以下命令:

convert -fuzz 13% face1.jpg -fill lime \
   -opaque "rgb(219,168,146)"          \
   -opaque "rgb(219,168,146)"          \
   -opaque "rgb(255,198,172)" out.jpg

因此,您可以发现很难找到皮肤色调只是使用RGB值,我什至没有开始处理不同的种族,不同的照明等。

So, you can see it is pretty hard to find skin-tones just by using RGB values and I haven't even started to address different races, different lighting etc.

另一种方法可能是使用不同的色彩空间,例如HSL-色相饱和度和亮度。我们对明度并不是很感兴趣,因为那只是曝光的函数,因此我们寻找与皮肤相匹配的色相并在一定程度上达到饱和,以避免褪色。您可以使用ImageMagick这样操作:

Another approach may be to use a different colourspace, such as HSL - Hue Saturation and Lightness. We are not so interested in Lightness because that is just a function of exposure, so we look for hues that match those of skin and some degree of saturation to avoid washed out colours. You can do that with ImageMagick like this:

#!/bin/bash
convert face1.jpg -colorspace hsl -separate          \
   \( -clone 0 -threshold 7% -negate +write h.png \) \
   \( -clone 1 -threshold 30% +write s.png        \) \
   -delete 0-2 -evaluate-sequence min out.png

就是说...将图像 face1.jpg 转换为HSL色彩空间,然后分离各层,这样我们的堆栈中便有了3张图像。 图像0 是色相,图像1 是饱和度,图像2 是亮度。下一行。取色相层并将其阈值限制为7%,这表示为粉红色,将其反转并保存为 h.png (以便于查看)。下一行。以饱和度层为例,并说 30%以上的任何饱和度对我来说都足够,然后另存为文件 s.png 。下一行。从原始图像中删除3个原始图层(HS& L),仅保留阈值色相和阈值饱和度层。现在,将这些放置在彼此的顶部,然后选择最小的一个并保存。关键是色相或饱和度图层均可用于门控选定了哪些像素。

That says this... take the image face1.jpg and convert it to HSL colorspace, then separate the layers so we now have 3 images in our stack. image 0 is the Hue, image 1 is the Saturation and image 2 is the Lightness. Next line. Take the Hue layer and threshold it at 7% which means pinky-reds, invert it and save it (just so you can see it) as h.png. Next line. Take the Saturation layer, and say "any saturation over 30% is good enough for me", then save as file s.png. Next line. Delete the 3 original layers (HS&L) from the original image leaving just the thresholded Hue and thresholded Saturation layers. Now put these ontop of each other and choose whichever is the minimum and save that. The point is that either the Hue or the Saturation layer can be used to gate which pixels are selected.

此处是文件,首先是色相( h.png ):

Here are the files, first the Hue (h.png):

下一个饱和度( s.png ):

,现在是合并的输出文件。

and now the combined output file.

一旦您对算法进行了分类,可以确定哪些像素是肤色的,则需要对它们进行计数,以计算出所需的百分比。这很容易...我们要做的就是将不是灰绿色的所有内容更改为黑色(因此在平均中它算为零),然后将图像调整为单个像素并将其颜色显示为文本:

Once you have got your algorithm sorted out for deciding which pixels are skin coloured, you will need to count them to work out the percentages you seek. That is pretty easy... all we do is change everything that is not lime-green to black (so it counts for zero in the averaging) and then resize the image to a single pixel and get its colour as text:

convert -fuzz 13% face1.jpg -fill lime      \
    -opaque "rgb(219,168,146)"              \
    -opaque "rgb(219,168,146)"              \
    -opaque "rgb(255,198,172)"              \
    -fill black +opaque lime -resize 1x1! txt:

# ImageMagick pixel enumeration: 1,1,255,srgb
0,0: (0,92,0)  #005C00  srgb(0,92,0)

我们可以毫不奇怪地看到,没有红色也没有蓝色,绿色像素的平均颜色为92/255 ,因此36%的像素与我们对肤色的描述相符。

We can see there is, not surprisingly, no red and no blue and the average colour of the green pixels is 92/255, so 36% of pixels match our description of skin-toned.

如果您想变得更复杂,则可能必须查看形状,纹理和上下文,或者训练皮肤分类器并在OpenCV或类似语言中编写大量内容...

If you want to get more sophisticated you may have to look at shapes, textures and contexts, or train a skin classifier and write a whole bunch of stuff in OpenCV or somesuch...

这篇关于图像给定像素的皮肤概率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆