最好的选择是处理 HSV 色彩空间中的图像(请参阅here http://www.cs.rit.edu/~ncs/color/t_convert.html用于 RGB - HSV 转换)。所有种族的肤色几乎都是一样的,只是饱和度发生了变化。通过处理 HSV 中的图像,您可以简单地搜索肤色。
您可以通过简单地计算颜色范围内的像素数来完成此操作,或者您可以执行区域 http://www.cse.unr.edu/~bebis/CS791E/Notes/RegionGrowing.pdf围绕像素生长来计算颜色区域的大小。
编辑:为了处理颗粒状图像,您可能需要执行中值滤波器 http://en.wikipedia.org/wiki/Median_filter首先在图像上,然后减少颜色数量以首先分割图像,您将必须在一大组预分类(成人或非成人)图像上尝试设置,并查看这些值的行为方式以获得令人满意的检测水平。
编辑:这里有一些代码应该做一个简单的计数(没有测试它,它是一些代码的快速混搭)here http://www.obnoxiouslyverbose.com/8/c-image-processing-performance-unsafe-vs-safe-code-part-i和 RGB 到 HSLhere http://en.wikipedia.org/wiki/HSL_color_space)
Bitmap b = new Bitmap(_image);
BitmapData bData = b.LockBits(new Rectangle(0, 0, _image.Width, _image.Height), ImageLockMode.ReadWrite, b.PixelFormat);
byte bitsPerPixel = GetBitsPerPixel(bData.PixelFormat);
byte* scan0 = (byte*)bData.Scan0.ToPointer();
int count;
for (int i = 0; i < bData.Height; ++i)
{
for (int j = 0; j < bData.Width; ++j)
{
byte* data = scan0 + i * bData.Stride + j * bitsPerPixel / 8;
byte r = data[2];
byte g = data[1];
byte b = data[0];
byte max = (byte)Math.Max(r, Math.Max(g, b));
byte min = (byte)Math.Min(r, Math.Min(g, b));
int h;
if(max == min)
h = 0;
else if(r > g && r > b)
h = (60 * ((g - b) / (max - min))) % 360;
else if (g > r && g > b)
h = 60 * ((b - r)/max - min) + 120;
else if (b > r && b > g)
h = 60 * ((r - g) / max - min) + 240;
if(h > _lowerThresh && h < _upperThresh)
count++;
}
}
b.UnlockBits(bData);