基于机器视觉的数字1-10手势识别系统( 六 )


图像的整体阀值二值化方法,即对整幅图像只设置一个固定的阀值,将所有像素与其比较,若像素灰度小于阀值,则标记为物体,大于阀值就为背景 。这种方法的优点是计算速度比较快,对对比度高质量高的图像,尤其是对于背景较为简单的图像而言,其处理效果很好,但是对于背景复杂的图像,特别是前景像素和背景像素灰度值区别不明显,互相之间都有相互交叉的,固定阀值就不太适合了 。若外界亮度发生变化时,固定阀值也会变得与图像最佳处理效果不符 。
直方图均衡
由于人工设定阀值总会偏离最佳的处理效果,因此我们可以根据图像的灰度直方图来进行阀值的选择,这是一种自动确定阀值的方法 。灰度直方图是对图像的所有像素的灰度分布按灰度值的大小显示其出现频率的统计图 。通常,横轴表示灰度值,纵轴表示频率,频率即某一灰度值的像素在图像中出现的次数 。对于手势图像来说,手部的像素和背景的像素集中了很多像素,因此在直方图上会有两个山峰形的分布 。一个峰值对应于手,另一个对应于背景 。山峰之间的谷底就是通常选择作为阀值的值,谷底越深二值化的效果越好 。一个灰度直方图的示例图如下图所示:
开运算和闭运算
在研究开运算和闭运算之前,我们先介绍图像的膨胀和腐蚀 。参考文献[8]中详细介绍了腐蚀与膨胀的原理,简单来说,腐蚀得到的是原图像的子集,即腐蚀具有收缩图像的作用,膨胀则是腐蚀的对偶运算,膨胀式利用结构元素对输入图像进行扩充,膨胀可以填充图像中小于结构元素的洞 。了解了图像的膨胀和腐蚀以后,我们再来研究开运算和闭运算 。
一般研究发现,如果对一副图像先进行腐蚀,再进行膨胀,会有一个特别的效果,得到的图像往往不是原始图像本身,而比原始图像要简单 。这个操作就称作开运算 。腐蚀操作会去掉物体的边缘点,细小物体所有的点都会被认为是边缘点,因此会整个被删去 。再做膨胀时,留下来的大物体会变回原来的大小,而被删除的小物体则永远消失了 。开运算会去除小的明亮区域,剩余的明亮区域将被隔离,但是其大小不变 。
闭运算则是先对图像进行膨胀,再进行腐蚀 。用来填充物体内细小空洞、连接邻近物体、平滑其边界的同时并不明显改变其面积 。通常,由于噪声的影响,图像在阈值化后所得到边界往往是很不平滑的,物体区域具有一些噪声孔,背景区域上散布着一些小的噪声物体 。连续的开和闭运算可以有效地改善这种情况 。
有时需要经过多次腐蚀之后再加上相同次数的膨胀,才可以产生比较好的效果 。
针对本文中的二值化手势图像,存在一定的粗糙边缘以及内部的空洞,可以适当的选择适当的开运算、闭运算进行消除 。处理以后的效果会得到优化,对后续的特征检测更有帮助 。我们调用的是()和 ()函数实现上述变化的 。()是对图像进行腐蚀操作,函数形式:
轮廓提取
通过Canny之类的边缘检测算法可以根据像素之间的差异检测出轮廓边界的像素,但是它并没有将轮廓作为一个整体,在上图中可以明显看出 。下一步是要把这些边缘像素组合成轮廓,这就是轮廓提取的目标 。
由于边缘检测是并行处理得到的,所以其结果一般不连续,针对轮廓提取我们则会选择一种串行的检测技术得到一个连续的输出结果 。下面介绍一种常见的方法,采用 链码的八邻域搜索法 。在链码中,多边形被表示为一系列的位移,每一个位移有八个方向可以选择,用0-7表示:
图像中的每一个像素都会有8个相邻像素,即所谓八邻域点,如果当前像素点p(x,y)为边界像素点,则对其相邻八个像素点按次序扫描,下一个边界点一定在其中 。具体算法步骤即,首先,边缘检测已经分理处了背景与物体,定义背景像素为0,物体像素为1,同时设置d为八邻域像素点的位置编码,对图像进行自上而下,自左向右的扫描,将第一个值为1的像素点作为算法的开始点,取d=5进行下一个边界点的搜索;从d开始按逆时针方向依次检车当前点的八邻域像素点,第一次出现值为1的点,该点就是新的边界点,记录下其位置编码的 d1,存入序列结构中;由于八邻域算法是一个串行的算法,得到的是一个连续封闭的轮廓,即最后一定会回到起始点,故将上述步骤重复,若d1回到了初始点,则搜索结束,输出结果 。