我正在构建一个ASP.NET网站,用户可以上传自己的照片.每天可能会有数千张照片上传.我的老板曾经问过一件事,就是我们有什么方法可以检测出任何照片是否显示出太多"皮肤"并在编辑做出最终决定之前自动将其标记为"仅限成人".
最好的办法是处理HSV颜色空间中的图像(请参阅此处了解rgb - hsv转换).所有种族之间的皮肤颜色几乎相同,只是变化的饱和度.通过处理HSV中的图像,您可以简单地搜索皮肤的颜色.
您可以通过简单计算颜色范围内的像素数来执行此操作,或者可以执行围绕像素生长的区域以计算颜色区域的大小.
编辑:为了处理颗粒状图像,您可能希望首先对图像执行中值滤镜,然后减少颜色数量以便首先对图像进行分割,您必须在大量预设中使用设置分类(成人或非成像)图像并查看值如何表现以获得令人满意的检测水平.
编辑:下面是一些代码,应该做一个简单的计数(没有测试它,它是从这里快速mashup的一些代码和rgb到hsl 这里)
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);
当然,对于发布某人脸部(或手,脚或其他)特写的第一个用户来说,这将失败.最终,所有这些形式的自动审查都将失败,直到计算机进行对象识别的方式出现真正的范式转换.
我并不是说你不应该尝试它; 但我想指出这些问题.不要指望完美(甚至是好)的解决方案.它不存在.
我怀疑是否存在可以确定用户是否上传顽皮图片的现成软件.您最好的选择是让用户使用图片旁边的按钮将图像标记为"仅限成人".(澄清:我的意思是除了上传图片的用户之外的用户 - 类似于在StackOverflow上如何标记帖子的攻击性.)
另外,请考虑对在专用产品中尝试做同样事情的审查:http://www.dansdata.com/pornsweeper.htm.
链接从今天的StackOverflow播客中被盗,当然:).
我们甚至不能在博客文章中编写能够准确检测脏词的过滤器,而且你的老板要求使用色情检测器?CLBUTTIC!
我会说你的答案在于众包任务.这几乎总是有效并且趋于非常好地扩展.
它不必涉及使一些用户进入"管理员"并提出不同的权限 - 它可以简单到在每个图像附近启用"不适当"链接并保持计数.
参见ECC杂志上发表的Fleck/Forsyth 的开创性论文" 寻找裸体人物 ".(高级).
http://www.cs.hmc.edu/~fleck/naked.html
来自理论/算法立场的有趣问题.解决该问题的一种方法是标记包含大的肤色区域的图像(如Trull所解释的).
然而,所显示的皮肤量不是图像的决定因素,而是所示皮肤的位置.也许您可以使用面部检测(搜索算法)来细化结果 - 确定皮肤区域相对于面部的大小,以及它们是否属于面部(可能在它下面多远).