Python cv2中的皮肤检测和背景扣除

And*_*aff 4 python opencv gesture-recognition

在过去的几天里,我一直在使用OpenCV Python开展手势识别程序.理想情况下,我希望有一个像本视频中所示的系统.我已经阅读了视频描述中描述的算法,我对它的全部了解.但是,我在复制背景减法和肤色检测方面的成功时遇到了麻烦.我的所有尝试都结果非常嘈杂和/或非常依赖于照明,这两者都使我的代码暂时无用.

我尝试过以下方法:

  • BackgroundSubtractorMOG和BackgroundSubtractorMOG2应用于颜色框架
  • 将图像分割成Y Cr Cb,在重新组合成单​​个图像之前将MOG或MOG2应用于每个
  • 过滤范围以删除非肤色的颜色(应用于彩色图像)

到目前为止,我还没有成功.我已经能够挑选出一些轮廓,但这些都是嘈杂和不稳定的(根据框架来来去去).他们是我应该使用的另一种方法吗?

Aen*_*ed1 5

我写了一个手指拼写解释器应用程序,所以我遇到了许多你所面临的健壮性问题.经过几周的实验,我找到了一个包含几种不同方法的解决方案,但最重要的方法是基于颜色的分割.

基于颜色(肤色)的分割可能非常强大,但简单的实现必然缺乏您正在寻找的稳健性.首先,每个人的肤色都不同.因此,通过其他机制识别基线肤色非常重要.一种方法是使用面部检测器(例如级联分类器)来找到对象的面部,然后相应地"调整"滤波器范围.

我个人使用级联分类器来首先找到闭合的拳头形状,然后我将HSV直方图归一化并区分为1)仅包括拳头的紧定边界框和2)整个图像.然后我设置一个查找表(LUT),将每个通道的每个值映射到0到25​​5之间的值,表示像素代表皮肤的概率.

根据我的经验,改善我的手部跟踪逻辑性能的重要因素是当我想到不丢弃信息时.为了生成二进制图像,您将很容易使用一些最佳范围进行阈值处理,但是知道一个像素有40%的可能性是皮肤而另一个像素有60%的几率是有价值的.一旦达到阈值,你只需要1和0.

当然,如果您打算使用基于轮廓的姿势分类,可能需要在某个时刻进行阈值处理.但是,如果您真的想构建强大的手势识别软件,您可能需要使用卷积神经网络(CNN)进行分类调查.预测可以非常快速地进行,并且它对背景噪声,翻译等非常强大......希望这会有所帮助!

编辑:让我澄清一下关于"对HSV直方图进行归一化和差分化"的评论.首先,这样做的基本原理是能够使用OpenCV的LUT(查找表),而不是使用基于范围的阈值. LUT非常有效,并且比基于范围的阈值处理更灵活.例如,假设您想要的色调包含两个不同范围内的值(例如:0-30和150-180).基于LUT的方法很容易处理,因为每个单独的值都可以独立映射.

因此,一旦建立了LUT,您只需要LUT为每个帧运行HSV图像.这是一个非常有效的解决方案.

在我的例子中,为了构建LUT,我采取了以下步骤:

  • 转换为HSV色彩空间.
  • 获得拳头周围紧密边界框的投资回报率.
  • 为ROI和整个图像构建每个通道的直方图.
  • 缩小(标准化)完整图像通道直方图,使得比例与ROI直方图的比例匹配(即:将每个完整图像直方图乘以ROI_area/full_image_area).
  • 从ROI直方图中减去(差异)完整图像直方图.(具有大正值的条目将对应于ROI中常见的通道值,但不是完整图像.)
  • 然后我平滑差异直方图以减少噪音和"过度拟合".
  • 最后,我使用OpenCV的normalize函数将差异直方图规范化为0.0到1.0之间的值NORM_MINMAX.
  • 然后可以将差异直方图合并在一起以产生3通道LUT.

我个人不会在使用LUT后对值进行阈值处理.相反,我只是使用结果数据计算各种类型的"颜色质量中心",我用它来保持ROI以手为中心.然后,我可以将相同的基于LUT的值发送到CNN进行分类.

请注意,虽然这种方法适用于我的目的,但如果你执行阈值处理,它仍然不会是完美的; 将检测到一些前景作为背景,反之亦然.我结合了一些基于边缘检测的逻辑来帮助减少由米色墙壁造成的误报(我家常见的故障模式),但实际情况是,如果有一种真正强大的方法可以将手从背景中干净地分割出来改变背景和照明条件,我还没有找到它.所以我的建议是从视觉皮层中获取提示,并允许来自更高抽象级别的信息来帮助滤除噪声.(换句话说,调查有线电视新闻网 - 它们真的很了不起.)