肤色分割并二值化

根据在PS软件中查看手掌的颜色区间,选取的感兴趣区域为:

  • 0 ≤ H ≤ 29;
  • 25 ≤ S ≤ 100;
  • 0 ≤ V ≤ 255;

在这里我们使用inRange()函数进行分割,将区间内的像素值转换为1(白色),区间外的像素值转换为0(黑色)。
效果如图2.10所示

闭运算排除小型黑洞

腐蚀
就像土壤侵蚀一样,这个操作会把前景物体的边界腐蚀掉(但是前景仍然是白色)。这是怎么做到的呢?卷积核沿着图像滑动,如果与卷积核对应的原图像的所有像素值都是 1,那么中心元素就保持原来的像素值,否则就变为零。根据卷积核的大小靠近前景的所有像素都会被腐蚀掉(变为 0),所以前景物体会变小,整幅图像的白色区域会减少。这对于去除白噪声很有用,也可以用来断开两个连在一块的物体等。

膨胀
与腐蚀相反,与卷积核对应的原图像的像素值中只要有一个是 1,中心元素的像素值就是 1。所以这个操作会增加图像中的白色区域(前景)。一般在去噪声时先用腐蚀再用膨胀。因为腐蚀在去掉白噪声的同时,也会使前景对象变小。所以我们再对他进行膨胀。这时噪声已经被去除了,不会再回来了,但是前景还在并会增加。膨胀也可以用来连接两个分开的物体。

闭运算
闭运算是对图像先膨胀再腐蚀,可以排除小型黑洞。对实验图像进行闭运算,消除手掌中可能出现的小型黑洞,防止下一步获取轮廓时在手掌内识别到轮廓。闭运算操作前后效果如图2.11所示。

闭运算操作前后效果
闭运算操作前后效果

获取轮廓并显示

使用OpenCV中的findContours()函数寻找轮廓,并使用drawContours()函数画出轮廓。函数cv2.findContours()有三个参数。第一个是输入图像,第二个是轮廓检索模式,第三个是轮廓近似方法。第二个参数选用RETR_TREE, 这种模式下会返回所有轮廓,并且创建一个完整的组织结构列表。第三个参数选用设为cv2.CHAIN_APPROX_SIMPLE ,压缩垂直、水平、对角方向,只保留端点。

函数cv2.drawContours()被用来绘制轮廓。第一个参数是一张图片,可以是原图或者其他。第二个参数是轮廓,也可以说是cv2.findContours()找出来的点集,一个列表。第三个参数是对轮廓(第二个参数)的索引,当需要绘制独立轮廓时很有用,若要全部绘制可设为-1。接下来的参数是轮廓的颜色和厚度。
结果如图2.12所示。

下一篇文章将会介绍如何根据轮廓的几何特征找到我们的手指。