下部分介绍图像识别涉及到的算法,主要用到的就是HOG+SVM,对二值图提取HOG特征向量,再用SVM多分类器训练相关模型,即可完成识别。

一、手腕去除及凸点计数

本阶段是对手势二值图再做进一步的处理,若存在裸露的手腕部分则将其去除掉并且计算手势最直观的特征手指数目将其作为一种分类特征 。

如果有手腕裸露时与手掌连为一体,之前的算法并不会去除手腕区域,但手腕区域对于之后的手势识别并无关系,所以可以将其去除精简要识别的手势二值图。

距离变换是针对二值图像的一种变换,计算图像中非零像素点到最近的零像素点的距离,然后用距离值作为该点的灰度像素值,将二值图像转换为灰度图像,通常用于细化轮廓和查找质心。通过遍历灰度图各像素点,可知像素值最高那个点是手掌的中心点即为质心,质心则可作为内切圆圆心,而其像素值则可作为内切圆半径,便可将内切圆以下部分当作手腕部分去除。

//手腕去除
public Mat wrist(Mat src){Mat mat3=new Mat();//距离变换Imgproc.distanceTransform(src,mat3,Imgproc.CV_DIST_L1,3);//寻找圆心和半径Mat mat4=new Mat();src.copyTo(mat4);int channels=mat3.channels();cr=0;cx=0;cy=0;float[]data=new float[channels*mat3.cols()];for (int i=0;i<mat3.rows();i++){mat3.get(i,0,data);for (int j=0;j<data.length;j++){if (data[j]>cr){cr=data[j];cx=j;cy=i;}}}//绘制内切圆Imgproc.circle(mat4,new Point(cx,cy),(int) cr,new Scalar(0,0,0),1);//手掌手腕分割Mat mat5=new Mat();src.copyTo(mat5);int chann=src.channels();int wi=src.cols();int hi=src.rows();byte[]data3=new byte[chann*wi];for (int i=hi/2;i<hi;i++){if (i>cy+cr){mat5.get(i,0,data3);for (int j=0;j<data3.length;j++){data3[j]=(byte)0;}mat5.put(i,0,data3);}}mat3.release();mat4.release();return  mat5;
}

手指个数可直接作为数字手势显著的归类几何特征,即从0到5的手指数每个都包含一些数字手势,如0个手指代表0,1个手指代表1和9,2个手指代表2、6和8,3个手指代表3,7,4个手指代表4,5个手指代表5。而可通过相关算法计算二值图的手势凸点,进而根据其几何关系进行二次筛选排除求得相关手势的手指数。

先确定下手指计数可分担后面支持向量机多分类识别的工作量,针对每个手指数所包含的手势训练相对应的分类器(即训练3个分类器,4和5直接用凸点即可识别)。而不只是用一个分类机来进行10分类。

 //计算手指个数(凸点)
public void findHull(Mat src){Mat hierarchy=new Mat();List<MatOfPoint> contours=new ArrayList<>();Point center=new Point();float[] radius={0};//找寻轮廓Imgproc.findContours(src,contours,hierarchy,Imgproc.RETR_LIST,Imgproc.CHAIN_APPROX_NONE,new Point(0,0));MatOfPoint contour=contours.get(0);MatOfPoint2f point2f=new MatOfPoint2f(contour.toArray());Imgproc.minEnclosingCircle(point2f,center,radius);//初始凸点集ArrayList<Point>  convexHullPointArrayList = new ArrayList<Point>();MatOfInt convexHullMatOfInt = new MatOfInt();Imgproc.convexHull( contour, convexHullMatOfInt, false);for(int j=0; j < convexHullMatOfInt.toList().size(); j++){convexHullPointArrayList.add(contour.toList().get(convexHullMatOfInt.toList().get(j)));}//筛除相邻凸点集ArrayList<Point>  convexHullPoint=new ArrayList<>();convexHullPoint.add(convexHullPointArrayList.get(0));for(int j=0;j<convexHullPointArrayList.size()-1;j++){double  x1=convexHullPointArrayList.get(j).x;double  y1=convexHullPointArrayList.get(j).y;double  x2=convexHullPointArrayList.get(j+1).x;double  y2=convexHullPointArrayList.get(j+1).y;if(Math.abs(x2-x1)>20||Math.abs(y2-y1)>20){convexHullPoint.add(convexHullPointArrayList.get(j+1));}}//手指凸点集ArrayList<Point>  convexHull=new ArrayList<>();//cx,cy为质心坐标for(int j=0;j<convexHullPoint.size();j++){double distancex=convexHullPoint.get(j).x-cx;double distancey=convexHullPoint.get(j).y-cy;double distance=cr/3*4;if(distancex*distancex+distancey*distancey>distance*distance&&convexHullPoint.get(j).y-y<0){convexHull.add(convexHullPoint.get(j));}}int convexHullcount=convexHull.size();if(convexHullcount>1){double  x1=convexHull.get(0).x;double  y1=convexHull.get(0).y;double  x2=convexHull.get(convexHullcount-1).x;double  y2=convexHull.get(convexHullcount-1).y;if(Math.abs(x2-x1)<20||Math.abs(y2-y1)<20){convexHull.remove(convexHullcount-1);}}hullnum=convexHull.size();Log.i("result","手指个数:" +hullnum );
}

二、轮廓二值图识别

本阶段即做最后的二值图分类识别工作,将上阶段处理后的手势二值图进行最大外接矩形裁剪,然后提取合适的特征算子向量,根据之前计算好的手指数目,再将其送入对应的SVM分类器识别。

根据手指数(凸点数)加载相应的XML模型(4和5不用加载直接返回结果就行)

float label=0;
SVM mClassifier=SVM.create();
try {InputStream is1 = getResources().openRawResource(R.raw.svm1);InputStream is2 = getResources().openRawResource(R.raw.svm2);InputStream is3 = getResources().openRawResource(R.raw.svm3);InputStream is;File svm_modelDir = getDir("svm_model", Context.MODE_PRIVATE);File mSvmModel = new File(svm_modelDir, "svm.xml");FileOutputStream os = new FileOutputStream(mSvmModel);byte[] buffer = new byte[4096];int bytesRead;if(recognition.hullnum==1||recognition.hullnum==0)is=is1;else if(recognition.hullnum==2)is=is2;else if(recognition.hullnum==3)is=is3;else if(recognition.hullnum==4)return label=4;elsereturn label=5;while ((bytesRead = is.read(buffer)) != -1) {os.write(buffer, 0, bytesRead);}is.close();os.close();mClassifier=SVM.load(mSvmModel.getAbsolutePath());svm_modelDir.delete();} catch (IOException e) {e.printStackTrace();Log.e(TAG, "Failed to load xml Exception thrown: " + e);
}

设置HOG相关参数 winSize  blockSize   blockStide  cellSize   bins

 HOGDescriptor hog = new HOGDescriptor(new Size(96, 128), new Size(96, 64), new Size(96, 32), new Size(48, 32), 4);MatOfFloat descriptor=new MatOfFloat();

手势二值图进行最大外接矩形裁剪

Mat hierarchy1=new Mat();
List<MatOfPoint> contours1=new ArrayList<MatOfPoint>();
Imgproc.findContours(src,contours1,hierarchy1, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_NONE,new Point(0,0));
Mat imgRectROI;
try{MatOfPoint contour=contours1.get(0);org.opencv.core.Rect R= Imgproc.boundingRect(contour);imgRectROI= new Mat(src, R);
}catch (Exception e){imgRectROI = src.clone();
}
Imgproc.resize(imgRectROI,imgRectROI,new Size(96,128));

最后直接给出计算HOG特征参数,送入SVM进行识别,得出预测结果

//计算src图像的hog特征,放入descriptor数组中
hog.compute(imgRectROI,descriptor);
Mat testDescriptor = new Mat(1,descriptor.rows(),CvType. CV_32FC1);
//将hog特征列向量转换为行向量
for (int i = 0; i<descriptor.rows(); i++)
{testDescriptor.put(0, i, descriptor.get(i,0));
}
label=mClassifier.predict(testDescriptor);
Log.i("result","识别结果:" +label );

好吧....这就算是完整的一个单帧图像识别过程。希望能给正在寻找思路的小伙伴有一些帮助!

数字手势识别App--(3)图像识别相关推荐

  1. 一步步做一个数字手势识别APP

    一步步做一个数字手势识别APP   这篇博客主要基于我做的一个数字手势识别APP,具体分享下如何一步步训练一个卷积神经网络模型(CNN)模型,然后把模型集成到Android Studio中,开发一个数 ...

  2. 基于卷积神经网络的数字手势识别APP(安卓) 毕业设计 附完整代码

    项目简介 这是一个基于卷积神经网络的数字手势识别 APP(安卓),主要功能为:通过手机摄像头识别做出的数字手势,能够识别数字 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 对应的手 ...

  3. Android基于卷积神经网络的数字手势识别识别数字手势0-10 Android studio编译

    这篇博客主要基于我做的一个数字手势识别APP,具体分享下如何一步步训练一个卷积神经网络模型(CNN)模型,然后把模型集成到Android Studio中,开发一个数字手势识别APP.Android基于 ...

  4. 数字手势识别App--(1)项目简介

    这段时间刚好处于出差前的一个空档期,于是就想记录一下我的毕设项目----基于手势识别的服务App,简单说就是通过数字手势识别去完成一些小功能如速算和拨号.速算:即在屏幕上显示算式,在前置做出答案对应的 ...

  5. 数字人民币App正式上线 京东子钱包推送量峰值增长超过20倍

    1月11日消息,日前,在CCTV2<正点财经>节目中,聚焦数字人民币App(试点版)正式上线,并对京东科技在数字人民币试点中的"供应链+场景+技术"服务优势进行了报道. ...

  6. 数字校园APP——可行性报告分析

    题目要求 请确定本团队项目的所有利益相关者,把调研结果发布到团队博客中 请团队所有成员针对目标用户确定需求调查提纲,并进行需求调研,可以采取各种你认为可行的方法,并把调研过程和结果发布到团队博客中 请 ...

  7. 数字校园APP开发与应用

    团队模式确定 通过小组讨论,我们小组最后选择主治医生模式.由王扶霖担任主刀医生,贡献分为60%,由胡德广来辅助主刀医生完成代码的工作,贡献分为10%,由我和王永利来主要完成文档和设计方面的工作,每个人 ...

  8. 【Matlab数字识别】数字仪表图像识别【含源码 693期】

    一.代码运行视频(哔哩哔哩) [Matlab数字识别]数字仪表图像识别[含源码 693期] 二.matlab版本及参考文献 1 matlab版本 2014a 2 参考文献 [1] 蔡利梅.MATLAB ...

  9. 双十二苏州老百姓学会了数字人民币APP钱包注册及使用

    苏州数字人民币红包活动已经正式开始,12月11日晚8点,被2000万数字人民币红包砸中的10万苏州市民,相继收到受邀下载"数字人民币APP"的短信,开启了数字人民币的使用之旅. 据 ...

  10. 数字藏品APP系统开发|数字藏品系统

    数字收藏是应用区块链技术对数字作品.艺术品和商品的所有权进行识别.数字收藏品可以在区块链网络中标记其所有者,并追踪其后续流通情况,包括但不限于数字图片.音乐.视频.电子门票.数字纪念品等方式.简单来说 ...

最新文章

  1. 这本书,让我秒懂了微服务架构
  2. 关于SQL 数据库表中的聚集索引和非聚集索引等
  3. 洛谷 5205 【模板】多项式开根
  4. java标识符命名_Java标识符命名规则
  5. getOutputStream() has already been called for this response解释以及解决方法
  6. User-Agent的变迁——浏览器大战之前世今生
  7. 计算机共享w7系统文件共享,win7系统怎么共享文件 电脑一键共享文件方法教程...
  8. java微信公众平台开发教程分享
  9. python删除文件夹无法访问_人生苦短 我学Python——anaconda和Jupyter notebook安装使用...
  10. java 发送邮件 ip被网易拉黑,发信IP或者发件人地址被网易加入了黑名单,原因如下及解决方法!...
  11. Android应用App开发工具
  12. java中如何将字符串数组转换成字符串(转)
  13. Themida是先进的Windows软件保护系统
  14. Unity开发回合制手游《魔神英雄传-神龙斗士》
  15. 阿里云软著申请|这项保护,让我得到了10万赔偿
  16. avue-tree默认展开一级菜单
  17. python 计算方位角(根据两点的坐标计算)
  18. android趣味项目,AndroidStudio项目开发实战——从基础入门到趣味开发
  19. 深入浅出 gRPC 02:gRPC 客户端创建和调用原理
  20. excel表头_三栏斜线表头怎么制作?excel数据验证表格看完整大连尾随男事件

热门文章

  1. latex 根据 excel, csv 的数据生成表格
  2. Flink的窗口计算案例
  3. numpy_eye函数
  4. 05- web网站链接测试与XENU工具使用
  5. hp1005mfp打印机驱动下载,打印机驱动安装方法
  6. 【精品】IntelliJ 文件模板 创建 通用Controller
  7. 危机下的暴走族 伟库用云实现“小康”
  8. BlackBerry手机上Java程序如何判断当前手机使用的运营商网络名称?网路制式?
  9. 手记:配置IIS服务器,支持sis、SISX、3GP、ADP、AMR、JAD、JAR、MMF、MFM、PMD、UMD等文件下载...
  10. 求面积 (坐标叉积公式+凹多边形面积-坐标公式)