Image processing 图像中给定像素的皮肤概率
给定一幅图像的所有像素的RGB值,我们如何才能找到给定像素是肤色的概率以及图像中肤色的百分比。在谷歌上闲逛告诉我,白种人的肤色通常,或者通常,或者有时符合以下规则:Image processing 图像中给定像素的皮肤概率,image-processing,computer-vision,Image Processing,Computer Vision,给定一幅图像的所有像素的RGB值,我们如何才能找到给定像素是肤色的概率以及图像中肤色的百分比。在谷歌上闲逛告诉我,白种人的肤色通常,或者通常,或者有时符合以下规则: Blue channel: 140-180 Green channel: Blue * 1.15 Red channel: Blue * 1.5 因此,考虑到这一点,我使用以下命令行制作了一些与ImageMagick对应的色样: #!/bin/bash for b in $(seq 140 5 180); do g=$(
Blue channel: 140-180
Green channel: Blue * 1.15
Red channel: Blue * 1.5
因此,考虑到这一点,我使用以下命令行制作了一些与ImageMagick对应的色样:
#!/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。现在,只要你能看到,我会把我所发现的石灰绿色的颜色涂成肤色,用它正好在色调范围的中间:
convert -fuzz 5% face1.jpg -fill lime -opaque "rgb(240,184,160)" out.jpg
嗯,不太好。也许会增加模糊性
嗯,还是很垃圾——只捡了一部分皮肤和一些白衬衫领子。也许是不同的面孔
好的,检测他的能力还不错,虽然注意到它完全无法检测到他的右脸,但是我们从粉色凯迪拉克上可以看出,仍然存在一些问题:
还有下面的小猪小姐
也许我们可以在搜索中更具针对性,虽然我不能用3D绘制它,但我可以用2-D来解释,而不是在我们的范围内瞄准一个大的圆(实际上是三维空间中的球体),也许我们可以瞄准一些沿着我们的范围传播的小圆圈,从而包括更少的外来颜色……洋红色代表模糊的程度。与其说是这样,不如说:
我们可以这样做:
使用此命令:
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值很难找到肤色,我甚至还没有开始解决不同种族、不同照明等问题
另一种方法可能是使用不同的颜色空间,如HSL-色调饱和度和亮度。我们对明度不太感兴趣,因为这只是曝光的一个函数,所以我们寻找与皮肤颜色相匹配的色调,以及一定程度的饱和度,以避免褪色。您可以使用ImageMagick这样做:
#!/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),只保留阈值色调和阈值饱和度层。现在把这些放在彼此的上面,选择最小值并保存。关键是色调或饱和度层可用于选哪个像素
以下是文件,首先是色调(h.png
):
接下来是饱和度(s.png
):
现在是组合输出文件
一旦你把决定哪些像素是皮肤颜色的算法整理好,你就需要对它们进行计数,以计算出你想要的百分比。这很简单。。。我们所要做的就是将所有不是石灰绿的东西都更改为黑色(因此在平均值中它为零),然后将图像调整为单个像素,并将其颜色作为文本:
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%的像素符合我们对肤色的描述
如果你想变得更复杂,你可能需要观察形状、纹理和上下文,或者训练一个皮肤分类器,在OpenCV或类似的东西中写一大堆东西……在谷歌上闲逛告诉我,白种人的肤色通常,或者可能是一般的,或者有时可能符合以下规则:
Blue channel: 140-180
Green channel: Blue * 1.15
Red channel: Blue * 1.5
因此,考虑到这一点,我使用以下命令行制作了一些与ImageMagick对应的色样:
#!/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。现在,只要你能看到,我会把我所发现的石灰绿色的颜色涂成肤色,用它正好在色调范围的中间:
convert -fuzz 5% face1.jpg -fill lime -opaque "rgb(240,184,160)" out.jpg
嗯,不太好。也许会增加模糊性
嗯,还是很垃圾——只捡了一部分皮肤和一些白衬衫领子。也许是不同的面孔
好的,检测他的能力还不错,虽然注意到它完全无法检测到他的右脸,但是我们从粉色凯迪拉克上可以看出,仍然存在一些问题:
还有下面的小猪小姐
也许我们可以在搜索中更具针对性,虽然我不能用3D绘制它,但我可以用2-D来解释,而不是在我们的范围内瞄准一个大的圆(实际上是三维空间中的球体),也许我们可以瞄准一些沿着我们的范围传播的小圆圈,从而包括更少的外来颜色……洋红色代表模糊的程度。与其说是这样,不如说:
我们可以这样做:
使用此命令:
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值很难找到肤色,我甚至还没有开始解决不同种族、不同照明等问题
另一种方法可能是使用不同的颜色空间,如HSL-色调饱和度和亮度。我们对明度不太感兴趣,因为这只是曝光的一个函数,所以我们寻找与皮肤颜色相匹配的色调和一定程度的饱和度,以避免水洗