1、先展示一下当前的效果

从keep上扒了一段仰卧起坐的视频教程进行计数测试:

(CSDN放不了视频,有兴趣的下方评论区留言)

2、回顾:

在上一期的内容中([开源]基于姿态估计的运动计数APP开发(一)),通过使用shufflenet轻量级网络+上采样输出关键点的heatmap已经可以在coco数据集中进行训练,并能够进行关键点识别。但是也存在一个问题,就是针对仰卧起坐这种动作,识别准确率非常低。通过分析原因,主要有两方面。一是开源的数据集中人的姿态是一些比较生活化的姿态,很少有仰卧起坐之类的姿态。另外一方面是网络本身比较小,提取特征能力有限,且为了在移动端实现实时检测,输出分辨率被限制在224*224,这些都会限制精度。本期主要是基于这些问题展开一些优化,初步实现一个可以进行实时计数的demo。

3、重新思考数据:

前面已经分析了coco以及mpii这些数据集对于我们训练仰卧起坐计数器这样一个APP来说并不是非常合适。并且对于这个任务来说,其实并不需要识别那么多的关键点。只要识别两个关键点就可以了,一个是头部关键点,一个是膝盖关键点。这样的话既不会影响我们最终计数APP的功能,又使得网络的任务减轻,可以专注与识别这两个关键点,从而提升精度。如下图所示。

由于没有现成的仰卧起坐数据集,只能自己动手,丰衣足食。好在对于仰卧起坐这样常规的运动,网上还是有很多相关资源的。这里我采用下载视频和图片两种方式。先从网上搜索“仰卧起坐”的视频,下载了10个左右的视频片段,然后通过抽帧的方式,从每个视频中抽取一部分帧作为训练用的数据。如下图所示为从视频中抽取的关键帧。

仅仅使用视频中抽取的帧会有一个比较严重的问题,就是背景过于单一,很容易造成过拟合。于是我从网上进行图片搜索,得到一分部背景较为丰富的图片,如下图所示:

收集完数据,就是进行标注了,这里我为了方便,自己开发了一款关键点标注工具,毕竟自己开发的,用着顺手。鼠标左键进行标注,右键取消上一次标注。不得不说,用python+qt开发一些基于UI的工具非常方便!与C++相比,解放了太多的生产力!

4、解决过拟合:

通过前面搜集的大约1K张图片,训练完之后会发现泛化性能并不好,很容易出现误识别。其实不难发现,由于数据量太少,网络已经出现了过拟合,训练到最后的loss非常小。解决过拟合最好的办法是增加数据量,但是时间有限,真的不想再去收集,标注数据,简直是浪费青春啊。于是就得考虑用一些数据增强的方法。我之前已经使用了一些光照增强的方法,例如随机改变亮度,随机调整HSV,这里主要增加一些几何上的变换。由于需要修改标签值,因此会麻烦一些。这里我主要考虑crop,padding,以及flip。

用来上述数据增强方法之后,效果显著改善了一些,过拟合没有那么严重,但是会出现一些错误的召回,会把一些书包或者衣服之类的当作关键点。那么主要原始还是训练数据的背景不够丰富,这里采用mixup的方法,从coco数据集中挑选一部分没有人的图片作为背景,随机的与训练图片进行重叠,从而有利于解决这种问题。

最终经过这些数据增强之后效果还不错。下面是相关代码,crop和padding合在一起实现。

class KPRandomPadCrop(object):def __init__(self, ratio=0.25, pad_value=[128, 128, 128]):assert (ratio > 0 and ratio <= 1)self.ratio = ratioself.pad_value = pad_valuedef __call__(self, image, labels=None):if random.randint(0,1):h, w = image.shape[:2]top_offset = int(h * random.uniform(0, self.ratio))bottom_offset = int(h * random.uniform(0, self.ratio))left_offset = int(w * random.uniform(0, self.ratio))right_offset = int(w * random.uniform(0, self.ratio))# padif random.randint(0,1):image = cv2.copyMakeBorder(image, top_offset, bottom_offset, left_offset, right_offset, cv2.BORDER_CONSTANT, value=self.pad_value)if labels is not None and len(labels) > 0:labels[:, 0] = (labels[:, 0] * w + left_offset) / (w + left_offset + right_offset)labels[:, 1] = (labels[:, 1] * h + top_offset) / (h + top_offset + bottom_offset)# cropelse:image = image[top_offset:h - bottom_offset, left_offset:w-right_offset]if labels is not None and len(labels) > 0:labels[:, 0] = (labels[:, 0] * w - left_offset) / (w - left_offset - right_offset)labels[:, 1] = (labels[:, 1] * h - top_offset) / (h - top_offset - bottom_offset)return image, labelsclass KPRandomHorizontalFlip(object):def __init__(self):passdef __call__(self, image, labels=None):if random.randint(0, 1):image = cv2.flip(image, 1)h, w = image.shape[:2]if labels is not None and len(labels) > 0:labels[:, 0] = 1.0 - labels[:, 0]return image, labelsclass KPRandomNegMixUp(object):def __init__(self, ratio=0.5, neg_dir='./coco_neg'):self.ratio = ratioself.neg_dir = neg_dirself.neg_images = []files = os.listdir(self.neg_dir)for file in files:if str(file).endswith('.jpg') or str(file).endswith('.png'):self.neg_images.append(str(file))def __call__(self, image, labels):if random.randint(0, 1):h, w = image.shape[:2]neg_name = random.choice(self.neg_images)neg_path = self.neg_dir + '/' + neg_nameneg_img = cv2.imread(neg_path)neg_img = cv2.resize(neg_img, (w, h)).astype(np.float32)neg_alpha = random.uniform(0, self.ratio)ori_alpha = 1 - neg_alphagamma = 0img_add = cv2.addWeighted(image, ori_alpha, neg_img, neg_alpha, gamma)return image, labelselse:return image, labels

5、在线难例挖掘

    通过上面的数据增强,训练出来的模型已经具备了一定的能力,但是通过大量的测试图片发现网络对于膝盖和头部的检测能力是不一样的。膝盖的检测较为稳定,而头部的检测经常会出现错误。分析原因,可能在于头部的变化比膝盖大的多,头部可能是正对相机,背对相机,也有可能被手臂挡住,因为网络很难学习到真正的头部特征。这里可以通过两种方法来改善,一种是简单的通过loss权重来赋予头部更大的权值,使得头部的梯度信息比膝盖的大,强迫网络更关注头部信息,还有一种就是用到了online hard keypoint mining。这是我在查看旷世的cpn人体姿态估计网络时候看到的,作者有视频进行介绍。其实实现起来很简单,就是对不同的关键点分别求loss,然后对loss排序,只返回一定比例的loss求梯度,作者给出的比例是0.5,即返回一半的关键点loss来求梯度。

6、总结

这个阶段主要是对网络精度的提升,通过精简关键点数目,重新收集,标注数据,增加padding,crop,flip数据增强,并引入mixup和在线难例挖掘等措施,来逐步提升网络泛化性能。并实现了一个python的demo(见文章开头),下一期主要是将该demo的功能实现为APP。

@end

[开源]基于姿态估计的运动计数APP开发(二)相关推荐

  1. [开源]基于姿态估计的运动计数APP开发(三)

    1.前言: 在上一期中[开源]基于姿态估计的运动计数APP开发(二)中,我们已经完成了仰卧起坐算法的开发和windows的demo开发.本期主要是将该算法一直到android平台上面,实现一个andr ...

  2. [开源]基于姿态估计的运动计数APP开发(一)

    前言: 看着自己日渐发福的身材,回想当年的英姿煞爽,感慨颇多.作为一个有羞耻心的程序猿,我决定开始减肥.考察了数十项减肥项目,我选择了仰卧起坐.因为它场地限制小,时间限制短,不剧烈,不伤身,最关键的是 ...

  3. 基于姿态估计的运动计数APP开发

    算法模型应用与实际生活,在原始模型上针对具体任务做了相应的改动,真的是学以致用:而且很好玩,真的让人感觉到了科研的乐趣!所以专门整理收藏 一 前言: 看着自己日渐发福的身材,回想当年的英姿煞爽,感慨颇 ...

  4. OpenSitUp开源项目:零基础开发基于姿态估计的运动健身APP

    更多深度学习工程实践项目,请关注公众号:DL工程实践 1.项目开源地址 https://github.com/DL-Practise/OpenSitUp 2.项目简介 计算机视觉中有一个应用分支叫做姿 ...

  5. html5 plus与vue,基于Html5 Plus + Vue + Mui 移动App 开发(二)

    基于Html5 Plus + Vue + Mui 移动App 开发(二) 界面效果: 本页面采用Html5 Plus + Vue + Mui 开发移动界面,本页面实现: 1.下拉刷新.上拉获取更多功能 ...

  6. 基于安卓手机的辅助驾驶APP开发

    目录结构:   1.项目介绍   2.网络设计   3.数据采集   4.APP开发   5.APP下载   6.效果展示 1.项目介绍: 该项目主要在于探索是否能在通用的安卓手机上实现一个辅助驾驶功 ...

  7. 浅析运动健身APP开发的四种模式

    健身行业是在"互联网+"的大潮中最早觉醒的行业之一,自2015年可谓运动健身APP开发爆发后,各类运动健身APP和智能硬件层出不穷,运动健身APP开发应用市场已被创业者视为开疆破土 ...

  8. ​运动健身APP开发软件,帮助您锻炼出一个理想身材​

    ​运动健身APP开发软件,帮助您锻炼出一个理想身材​. 1.解决网上健身烦恼,运动健身APP提供了丰富的教程资源,用户没有太多时间或只想在网上锻炼,也可以通过网上享受健身服务.视频教程,图形教程,健身 ...

  9. 基于百度地图sdk的地图app开发(七)——导航和模拟导航

    这是基于百度地图sdk的地图app开发系列博客第七篇 代码仓库位置:https://github.com/YanhuiLu89/lmap.git 上一篇 基于百度地图sdk的地图app开发(六)--路 ...

最新文章

  1. Java B2B2C多用户商城 springcloud架构-服务容错保护(Hystrix服务降级)
  2. DOM的appendchild在IE6、7下不兼容
  3. SM30 - SMOFOBJECT
  4. 使用宝塔部署node项目_使用宝塔面板进行项目的自动部署WebHook
  5. 0限流电阻 stm32_上/下拉电阻
  6. python中acosh_acosh()函数以及C ++中的示例
  7. 极简短网址-一套简约的短网址程序
  8. OSTimeDlyResume()--恢复一个延迟任务(取消任务延时)
  9. c# 数据结构 ---双链表
  10. 找回华为云删除的通讯录_找回小米手机误删照片只要10秒!人人都知道的方法,你怎能不知道...
  11. mtk一键usb驱动_微星b460主板装win7系统及bios设置教程(支持十代usb驱动)
  12. 何为量子计算机? | CSDN 博文精选
  13. [JNI] 开发基础 (2) 指针
  14. Java项目:前台展示+后台管理结合的在线购书系统(java+Springboot+ssm+mysql+maven)
  15. mysql-入门教程
  16. mo java_mojava和 high sierra系统区别?
  17. 一个简单的跑酷引擎-------bibibibi
  18. Viddy上视频营销最成功的6家公司
  19. springboot+vue+nodejs多用户网上图书商城系统-含卖家功能java
  20. PCIE——第5章——Montevina 的 MCH 和 ICH

热门文章

  1. python异常处理优点_python自测100题(下)
  2. iOS PUSH实现的简单步骤
  3. u3d文件上传至服务器,unity 上传图片到云服务器
  4. Vue eslint 团队代码规范
  5. Mozilla工程师观点:开源不赚钱,因为它不是为赚钱而设计的
  6. OpenCv调用摄像头拍照代码
  7. LoadRunner变量到参数的互换
  8. 浅析商业银行“业务连续性管理体系”的构建
  9. 关于通过DDMS向Android系统的模拟器的sdcard中导入mp3文件的问题
  10. windows最重要的三个dll