使用JavaCV进行手和手指检测

这篇文章是Andrew Davison博士发布的有关自然用户界面(NUI)系列的一部分,内容涉及使用JavaCV从网络摄像头视频提要中检测手。

注意:可以从http://fivedots.coe.psu.ac.th/~ad/jg/nui055/下载本章的所有源代码。

第5章的彩色斑点检测代码(可从http://fivedots.coe.psu.ac.th/~ad/jg/nui05/获得 )可以用作其他形状分析器的基础,我将在此处进行说明。通过扩展它来检测手和手指。 在图1中,我的左手戴着黑手套。 我的Handy应用程序尝试查找并标记拇指,食指,中指,无名指和小指。 在指尖和手的重心(COG)之间绘制黄线。

图1.检测左手和手指。

我使用了第5章的HSVSelector应用程序来确定黑手套的合适HSV范围。 在执行图2所示的步骤之前,Handy会加载这些范围,以获取手部的轮廓,其COG和相对于水平面的方向。

图2。找到手轮廓。

图2中的各个阶段几乎与第5章第4.1节中的ColorRectDetector.findRect()方法执行的阶段相同。但是,Handy继续进行处理,使用凸包和凸凹缺陷来定位并标记手中的指尖轮廓。 这些附加步骤如图3所示。

图3.查找和标记指尖。

船体和缺陷是通过标准的OpenCV操作从轮廓获得的,我将在下面进行解释。 但是,命名手指的最后一步使用了一种颇为怪异的策略,该策略假定轮廓的缺陷是针对伸出的左手。 拇指和食指基于它们相对于COG的角度位置来定位,而其他手指则根据它们相对于那些手指的位置来标识。 这个过程非常脆弱,并且很容易混淆,如图4所示。

图4.错误的中指。

但是,该技术相当可靠,通常至少可以识别拇指和食指,而与手的方向无关,这对于基本的手势处理来说应该足够了。 但是,该应用程序无法识别手势,希望它将成为下一章的主题。

Handy的类图如图5所示,仅列出了公共方法。

图5.方便的类图。

Handy的顶级与第5章中的BlobsDrumming应用程序的顶级并行(例如,参见第5章的图11​​),其中Handy类管理JFrame和HandPanel,显示带注释的网络摄像头图像。 图2和3总结的图像分析由HandDetector类执行,该类通过调用update()传递给当前的网络摄像头快照。 当HandPanel调用HandDetector.draw()时,它将绘制当前标记的指尖,COG和连接线。

1.分析网络摄像头图像

update()方法实质上是实现图2和图3的一系列调用。

// globals
private static final int IMG_SCALE = 2; 
         // scaling applied to webcam image

// HSV ranges defining the glove color
private int hueLower, hueUpper, satLower, satUpper,
            briLower, briUpper;

// OpenCV elements
private IplImage hsvImg;  // HSV version of webcam image
private IplImage imgThreshed;  // threshold for HSV settings

// hand details
private Point cogPt;       // center of gravity (COG) of contour
private int contourAxisAngle;     
   // contour's main axis angle relative to the horiz (in degrees)
private ArrayList fingerTips;


public void update(BufferedImage im)
{
  BufferedImage scaleIm = scaleImage(im, IMG_SCALE);   
      // reduce the size of the image to make processing faster

  // convert image format to HSV
  cvCvtColor(IplImage.createFrom(scaleIm), hsvImg, CV_BGR2HSV);

  // threshold image using loaded HSV settings for user's glove
  cvInRangeS(hsvImg, cvScalar(hueLower, satLower, briLower, 0),
                     cvScalar(hueUpper, satUpper, briUpper, 0),
                        imgThreshed);

  cvMorphologyEx(imgThreshed, imgThreshed, null, null,
                                             CV_MOP_OPEN, 1);
     // erosion followed by dilation on the image to remove
     // specks of white while retaining the image size

  CvSeq bigContour = findBiggestContour(imgThreshed);
  if (bigContour == null)
    return;

  extractContourInfo(bigContour, IMG_SCALE);
     // find the COG and angle to horizontal of the contour

  findFingerTips(bigContour, IMG_SCALE);
      // detect the fingertips positions in the contour

  nameFingers(cogPt, contourAxisAngle, fingerTips);
}  // end of upda
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值